PCLoaderVisum.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A reader of pois and polygons stored in VISUM-format
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <string>
00031 #include <map>
00032 #include <fstream>
00033 #include <utils/common/StringTokenizer.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/common/MsgHandler.h>
00036 #include <utils/common/StringUtils.h>
00037 #include <utils/common/TplConvert.h>
00038 #include <utils/common/ToString.h>
00039 #include <utils/common/FileHelpers.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/options/Option.h>
00042 #include <utils/importio/LineReader.h>
00043 #include <utils/common/StdDefs.h>
00044 #include <polyconvert/PCPolyContainer.h>
00045 #include "PCLoaderVisum.h"
00046 #include <utils/common/RGBColor.h>
00047 #include <utils/geom/GeomHelper.h>
00048 #include <utils/geom/Boundary.h>
00049 #include <utils/geom/Position2D.h>
00050 #include <utils/geom/GeoConvHelper.h>
00051 #include <utils/importio/NamedColumnsParser.h>
00052 
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056 
00057 
00058 // ===========================================================================
00059 // method definitions
00060 // ===========================================================================
00061 void
00062 PCLoaderVisum::loadIfSet(OptionsCont &oc, PCPolyContainer &toFill,
00063                          PCTypeMap &tm) throw(ProcessError) {
00064     if (!oc.isSet("visum-files")) {
00065         return;
00066     }
00067     // parse file(s)
00068     std::vector<std::string> files = oc.getStringVector("visum-files");
00069     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00070         if (!FileHelpers::exists(*file)) {
00071             throw ProcessError("Could not open visum-file '" + *file + "'.");
00072         }
00073         MsgHandler::getMessageInstance()->beginProcessMsg("Parsing from visum-file '" + *file + "'...");
00074         load(*file, oc, toFill, tm);
00075         MsgHandler::getMessageInstance()->endProcessMsg("done.");
00076     }
00077 }
00078 
00079 
00080 
00081 void
00082 PCLoaderVisum::load(const std::string &file, OptionsCont &oc, PCPolyContainer &toFill,
00083                     PCTypeMap &tm) throw(ProcessError) {
00084     std::string what;
00085     std::map<long, Position2D> punkte;
00086     std::map<long, Position2DVector> kanten;
00087     std::map<long, Position2DVector> teilflaechen;
00088     std::map<long, long> flaechenelemente;
00089     NamedColumnsParser lineParser;
00090     LineReader lr(file);
00091     while (lr.hasMore()) {
00092         std::string line = lr.readLine();
00093         // reset if current is over
00094         if (line.length()==0||line[0]=='*'||line[0]=='$') {
00095             what = "";
00096         }
00097         // read items
00098         if (what=="$PUNKT") {
00099             lineParser.parseLine(line);
00100             long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00101             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00102             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00103             Position2D pos(x, y);
00104             if (!GeoConvHelper::x2cartesian(pos)) {
00105                 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for point '" + toString(id) + "'.");
00106             }
00107             punkte[id] = pos;
00108             continue;
00109         } else if (what=="$KANTE") {
00110             lineParser.parseLine(line);
00111             long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00112             long fromID = TplConvert<char>::_2long(lineParser.get("VONPUNKTID").c_str());
00113             long toID = TplConvert<char>::_2long(lineParser.get("NACHPUNKTID").c_str());
00114             Position2DVector vec;
00115             vec.push_back(punkte[fromID]);
00116             vec.push_back(punkte[toID]);
00117             kanten[id] = vec;
00118             continue;
00119         } else if (what=="$ZWISCHENPUNKT") {
00120             lineParser.parseLine(line);
00121             long id = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00122             int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00123             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00124             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00125             Position2D pos(x, y);
00126             if (!GeoConvHelper::x2cartesian(pos)) {
00127                 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for edge '" + toString(id) + "'.");
00128             }
00129             kanten[id].insertAt(index, pos);
00130             continue;
00131         } else if (what=="$TEILFLAECHENELEMENT") {
00132             lineParser.parseLine(line);
00133             long id = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00134             int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00135             index = 0; 
00136             long kid = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00137             int dir = TplConvert<char>::_2int(lineParser.get("RICHTUNG").c_str());
00138             if (teilflaechen.find(id)==teilflaechen.end()) {
00139                 teilflaechen[id] = Position2DVector();
00140             }
00141             if (dir==0) {
00142                 for (int i=0; i<(int) kanten[kid].size(); ++i) {
00143                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00144                 }
00145             } else {
00146                 for (int i=(int) kanten[kid].size()-1; i>=0; --i) {
00147                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00148                 }
00149             }
00150             continue;
00151         } else if (what=="$FLAECHENELEMENT") {
00152             lineParser.parseLine(line);
00153             long id = TplConvert<char>::_2long(lineParser.get("FLAECHEID").c_str());
00154             long tid = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00155             int enklave = TplConvert<char>::_2int(lineParser.get("ENKLAVE").c_str()); // !!! unused
00156             enklave = 0;
00157             flaechenelemente[id] = tid;
00158             continue;
00159         }
00160         // set if read
00161         if (line[0]=='$') {
00162             what = "";
00163             if (line.find("$PUNKT")==0) {
00164                 what = "$PUNKT";
00165             } else if (line.find("$KANTE")==0) {
00166                 what = "$KANTE";
00167             } else if (line.find("$ZWISCHENPUNKT")==0) {
00168                 what = "$ZWISCHENPUNKT";
00169             } else if (line.find("$TEILFLAECHENELEMENT")==0) {
00170                 what = "$TEILFLAECHENELEMENT";
00171             } else if (line.find("$FLAECHENELEMENT")==0) {
00172                 what = "$FLAECHENELEMENT";
00173             }
00174             if (what!="") {
00175                 lineParser.reinit(line.substr(what.length()+1));
00176             }
00177         }
00178     }
00179 
00180     // do some more sane job...
00181     RGBColor c = RGBColor::parseColor(oc.getString("color"));
00182     std::map<std::string, std::string> typemap;
00183     // load the pois/polys
00184     lr.reinit();
00185     bool parsingCategories = false;
00186     bool parsingPOIs = false;
00187     bool parsingDistrictsDirectly = false;
00188     Position2DVector vec;
00189     std::string polyType, lastID;
00190     bool first = true;
00191     while (lr.hasMore()) {
00192         std::string line = lr.readLine();
00193         // do not parse empty lines
00194         if (line.length()==0) {
00195             continue;
00196         }
00197         // do not parse comment lines
00198         if (line[0]=='*') {
00199             continue;
00200         }
00201 
00202         if (line[0]=='$') {
00203             // reset parsing on new entry type
00204             parsingCategories = false;
00205             parsingPOIs = false;
00206             parsingDistrictsDirectly = false;
00207             polyType = "";
00208         }
00209 
00210         if (parsingCategories) {
00211             // parse the category
00212             StringTokenizer st(line, ";");
00213             std::string catid = st.next();
00214             std::string catname = st.next();
00215             typemap[catid] = catname;
00216         }
00217         if (parsingPOIs) {
00218             // parse the poi
00219             // $POI:Nr;CATID;CODE;NAME;Kommentar;XKoord;YKoord;
00220             StringTokenizer st(line, ";");
00221             std::string num = st.next();
00222             std::string catid = st.next();
00223             std::string code = st.next();
00224             std::string name = st.next();
00225             std::string comment = st.next();
00226             std::string xpos = st.next();
00227             std::string ypos = st.next();
00228             // process read values
00229             SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00230             SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00231             Position2D pos(x, y);
00232             if (!GeoConvHelper::x2cartesian(pos)) {
00233                 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for POI '" + num + "'.");
00234             }
00235             std::string type = typemap[catid];
00236             // check the poi
00237             name = num;
00238             // patch the values
00239             bool discard = false;
00240             int layer = oc.getInt("layer");
00241             RGBColor color;
00242             if (tm.has(type)) {
00243                 const PCTypeMap::TypeDef &def = tm.get(type);
00244                 name = def.prefix + name;
00245                 type = def.id;
00246                 color = RGBColor::parseColor(def.color);
00247                 discard = def.discard;
00248                 layer = def.layer;
00249             } else {
00250                 name = oc.getString("prefix") + name;
00251                 type = oc.getString("type");
00252                 color = c;
00253             }
00254             if (!discard) {
00255                 PointOfInterest *poi = new PointOfInterest(name, type, pos, color);
00256                 if (!toFill.insert(name, poi, layer)) {
00257                     MsgHandler::getErrorInstance()->inform("POI '" + name + "' could not been added.");
00258                     delete poi;
00259                 }
00260             }
00261         }
00262 
00263         // poly
00264         if (polyType!="") {
00265             StringTokenizer st(line, ";");
00266             std::string id = st.next();
00267             std::string type;
00268             if (!first&&lastID!=id) {
00269                 // we have parsed a polygon completely
00270                 RGBColor color;
00271                 int layer = oc.getInt("layer");
00272                 bool discard = false;
00273                 if (tm.has(polyType)) {
00274                     const PCTypeMap::TypeDef &def = tm.get(polyType);
00275                     id = def.prefix + id;
00276                     type = def.id;
00277                     color = RGBColor::parseColor(def.color);
00278                     discard = def.discard;
00279                     layer = def.layer;
00280                 } else {
00281                     id = oc.getString("prefix") + id;
00282                     type = oc.getString("type");
00283                     color = c;
00284                 }
00285                 if (!discard) {
00286                     Polygon2D *poly = new Polygon2D(id, type, color, vec, false);
00287                     if (!toFill.insert(id, poly, 1)) {
00288                         MsgHandler::getErrorInstance()->inform("Polygon '" + id + "' could not been added.");
00289                         delete poly;
00290                     }
00291                 }
00292                 vec.clear();
00293             }
00294             lastID = id;
00295             first = false;
00296             // parse current poly
00297             std::string index = st.next();
00298             std::string xpos = st.next();
00299             std::string ypos = st.next();
00300             Position2D pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
00301             if (!GeoConvHelper::x2cartesian(pos2D)) {
00302                 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for polygon '" + id + "'.");
00303             }
00304             vec.push_back(pos2D);
00305         }
00306 
00307         // district refering a shape
00308         if (parsingDistrictsDirectly) {
00309             //$BEZIRK:NR    CODE    NAME    TYPNR   XKOORD  YKOORD  FLAECHEID   BEZART  IVANTEIL_Q  IVANTEIL_Z  OEVANTEIL   METHODEANBANTEILE   ZWERT1  ZWERT2  ZWERT3  ISTINAUSWAHL    OBEZNR  NOM_COM COD_COM
00310             StringTokenizer st(line, ";");
00311             std::string num = st.next();
00312             std::string code = st.next();
00313             std::string name = st.next();
00314             st.next(); // typntr
00315             std::string xpos = st.next();
00316             std::string ypos = st.next();
00317             long id = TplConvert<char>::_2long(st.next().c_str());
00318             // patch the values
00319             std::string type = "district";
00320             name = num;
00321             bool discard = false;
00322             int layer = oc.getInt("layer");
00323             RGBColor color;
00324             if (tm.has(type)) {
00325                 const PCTypeMap::TypeDef &def = tm.get(type);
00326                 name = def.prefix + name;
00327                 type = def.id;
00328                 color = RGBColor::parseColor(def.color);
00329                 discard = def.discard;
00330                 layer = def.layer;
00331             } else {
00332                 name = oc.getString("prefix") + name;
00333                 type = oc.getString("type");
00334                 color = c;
00335             }
00336             if (!discard) {
00337                 if (teilflaechen[flaechenelemente[id]].size()>0) {
00338                     Polygon2D *poly = new Polygon2D(name, type, color, teilflaechen[flaechenelemente[id]], false);
00339                     if (!toFill.insert(name, poly, layer)) {
00340                         MsgHandler::getErrorInstance()->inform("Polygon '" + name + "' could not been added.");
00341                         delete poly;
00342                     }
00343                 } else {
00344                     SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00345                     SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00346                     Position2D pos(x, y);
00347                     if (!GeoConvHelper::x2cartesian(pos)) {
00348                         MsgHandler::getWarningInstance()->inform("Unable to project coordinates for POI '" + name + "'.");
00349                     }
00350                     PointOfInterest *poi = new PointOfInterest(name, type, pos, color);
00351                     if (!toFill.insert(name, poi, layer)) {
00352                         MsgHandler::getErrorInstance()->inform("POI '" + name + "' could not been added.");
00353                         delete poi;
00354                     }
00355                 }
00356             }
00357         }
00358 
00359 
00360         if (line.find("$POIKATEGORIEDEF:")==0||line.find("$POIKATEGORIE:")==0) {
00361             // ok, got categories, begin parsing from next line
00362             parsingCategories = true;
00363         }
00364         if (line.find("$POI:")==0) {
00365             // ok, got pois, begin parsing from next line
00366             parsingPOIs = true;
00367         }
00368         if (line.find("$BEZIRK")==0 && line.find("FLAECHEID")!=std::string::npos) {
00369             // ok, have a district header, and it seems like districts would reference shapes...
00370             parsingDistrictsDirectly = true;
00371         }
00372 
00373 
00374         if (line.find("$BEZIRKPOLY")!=std::string::npos) {
00375             polyType = "district";
00376         }
00377         if (line.find("$GEBIETPOLY")!=std::string::npos) {
00378             polyType = "area";
00379         }
00380 
00381     }
00382 }
00383 
00384 
00385 
00386 /****************************************************************************/
00387 

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6