SUMO - Simulation of Urban MObility

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 (C) 2001-2011 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/Position.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         PROGRESS_BEGIN_MESSAGE("Parsing from visum-file '" + *file + "'");
00074         load(*file, oc, toFill, tm);
00075         PROGRESS_DONE_MESSAGE();
00076     }
00077 }
00078 
00079 
00080 
00081 void
00082 PCLoaderVisum::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
00083                     PCTypeMap& tm) throw(ProcessError) {
00084     GeoConvHelper& geoConvHelper = GeoConvHelper::getDefaultInstance();
00085     std::string what;
00086     std::map<long, Position> punkte;
00087     std::map<long, PositionVector> kanten;
00088     std::map<long, PositionVector> teilflaechen;
00089     std::map<long, long> flaechenelemente;
00090     NamedColumnsParser lineParser;
00091     LineReader lr(file);
00092     while (lr.hasMore()) {
00093         std::string line = lr.readLine();
00094         // reset if current is over
00095         if (line.length()==0||line[0]=='*'||line[0]=='$') {
00096             what = "";
00097         }
00098         // read items
00099         if (what=="$PUNKT") {
00100             lineParser.parseLine(line);
00101             long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00102             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00103             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00104             Position pos(x, y);
00105             if (!geoConvHelper.x2cartesian(pos)) {
00106                 WRITE_WARNING("Unable to project coordinates for point '" + toString(id) + "'.");
00107             }
00108             punkte[id] = pos;
00109             continue;
00110         } else if (what=="$KANTE") {
00111             lineParser.parseLine(line);
00112             long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00113             long fromID = TplConvert<char>::_2long(lineParser.get("VONPUNKTID").c_str());
00114             long toID = TplConvert<char>::_2long(lineParser.get("NACHPUNKTID").c_str());
00115             PositionVector vec;
00116             vec.push_back(punkte[fromID]);
00117             vec.push_back(punkte[toID]);
00118             kanten[id] = vec;
00119             continue;
00120         } else if (what=="$ZWISCHENPUNKT") {
00121             lineParser.parseLine(line);
00122             long id = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00123             int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00124             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00125             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00126             Position pos(x, y);
00127             if (!geoConvHelper.x2cartesian(pos)) {
00128                 WRITE_WARNING("Unable to project coordinates for edge '" + toString(id) + "'.");
00129             }
00130             kanten[id].insertAt(index, pos);
00131             continue;
00132         } else if (what=="$TEILFLAECHENELEMENT") {
00133             lineParser.parseLine(line);
00134             long id = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00135             int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00136             index = 0; 
00137             long kid = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00138             int dir = TplConvert<char>::_2int(lineParser.get("RICHTUNG").c_str());
00139             if (teilflaechen.find(id)==teilflaechen.end()) {
00140                 teilflaechen[id] = PositionVector();
00141             }
00142             if (dir==0) {
00143                 for (int i=0; i<(int) kanten[kid].size(); ++i) {
00144                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00145                 }
00146             } else {
00147                 for (int i=(int) kanten[kid].size()-1; i>=0; --i) {
00148                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00149                 }
00150             }
00151             continue;
00152         } else if (what=="$FLAECHENELEMENT") {
00153             lineParser.parseLine(line);
00154             long id = TplConvert<char>::_2long(lineParser.get("FLAECHEID").c_str());
00155             long tid = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00156             int enklave = TplConvert<char>::_2int(lineParser.get("ENKLAVE").c_str()); // !!! unused
00157             enklave = 0;
00158             flaechenelemente[id] = tid;
00159             continue;
00160         }
00161         // set if read
00162         if (line[0]=='$') {
00163             what = "";
00164             if (line.find("$PUNKT")==0) {
00165                 what = "$PUNKT";
00166             } else if (line.find("$KANTE")==0) {
00167                 what = "$KANTE";
00168             } else if (line.find("$ZWISCHENPUNKT")==0) {
00169                 what = "$ZWISCHENPUNKT";
00170             } else if (line.find("$TEILFLAECHENELEMENT")==0) {
00171                 what = "$TEILFLAECHENELEMENT";
00172             } else if (line.find("$FLAECHENELEMENT")==0) {
00173                 what = "$FLAECHENELEMENT";
00174             }
00175             if (what!="") {
00176                 lineParser.reinit(line.substr(what.length()+1));
00177             }
00178         }
00179     }
00180 
00181     // do some more sane job...
00182     RGBColor c = RGBColor::parseColor(oc.getString("color"));
00183     std::map<std::string, std::string> typemap;
00184     // load the pois/polys
00185     lr.reinit();
00186     bool parsingCategories = false;
00187     bool parsingPOIs = false;
00188     bool parsingDistrictsDirectly = false;
00189     PositionVector vec;
00190     std::string polyType, lastID;
00191     bool first = true;
00192     while (lr.hasMore()) {
00193         std::string line = lr.readLine();
00194         // do not parse empty lines
00195         if (line.length()==0) {
00196             continue;
00197         }
00198         // do not parse comment lines
00199         if (line[0]=='*') {
00200             continue;
00201         }
00202 
00203         if (line[0]=='$') {
00204             // reset parsing on new entry type
00205             parsingCategories = false;
00206             parsingPOIs = false;
00207             parsingDistrictsDirectly = false;
00208             polyType = "";
00209         }
00210 
00211         if (parsingCategories) {
00212             // parse the category
00213             StringTokenizer st(line, ";");
00214             std::string catid = st.next();
00215             std::string catname = st.next();
00216             typemap[catid] = catname;
00217         }
00218         if (parsingPOIs) {
00219             // parse the poi
00220             // $POI:Nr;CATID;CODE;NAME;Kommentar;XKoord;YKoord;
00221             StringTokenizer st(line, ";");
00222             std::string num = st.next();
00223             std::string catid = st.next();
00224             std::string code = st.next();
00225             std::string name = st.next();
00226             std::string comment = st.next();
00227             std::string xpos = st.next();
00228             std::string ypos = st.next();
00229             // process read values
00230             SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00231             SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00232             Position pos(x, y);
00233             if (!geoConvHelper.x2cartesian(pos)) {
00234                 WRITE_WARNING("Unable to project coordinates for POI '" + num + "'.");
00235             }
00236             std::string type = typemap[catid];
00237             // check the poi
00238             name = num;
00239             // patch the values
00240             bool discard = oc.getBool("discard");
00241             int layer = oc.getInt("layer");
00242             RGBColor color;
00243             if (tm.has(type)) {
00244                 const PCTypeMap::TypeDef& def = tm.get(type);
00245                 name = def.prefix + name;
00246                 type = def.id;
00247                 color = RGBColor::parseColor(def.color);
00248                 discard = def.discard;
00249                 layer = def.layer;
00250             } else {
00251                 name = oc.getString("prefix") + name;
00252                 type = oc.getString("type");
00253                 color = c;
00254             }
00255             if (!discard) {
00256                 PointOfInterest* poi = new PointOfInterest(name, type, pos, color);
00257                 if (!toFill.insert(name, poi, layer)) {
00258                     WRITE_ERROR("POI '" + name + "' could not been added.");
00259                     delete poi;
00260                 }
00261             }
00262         }
00263 
00264         // poly
00265         if (polyType!="") {
00266             StringTokenizer st(line, ";");
00267             std::string id = st.next();
00268             std::string type;
00269             if (!first&&lastID!=id) {
00270                 // we have parsed a polygon completely
00271                 RGBColor color;
00272                 int layer = oc.getInt("layer");
00273                 bool discard = oc.getBool("discard");
00274                 if (tm.has(polyType)) {
00275                     const PCTypeMap::TypeDef& def = tm.get(polyType);
00276                     id = def.prefix + id;
00277                     type = def.id;
00278                     color = RGBColor::parseColor(def.color);
00279                     discard = def.discard;
00280                     layer = def.layer;
00281                 } else {
00282                     id = oc.getString("prefix") + id;
00283                     type = oc.getString("type");
00284                     color = c;
00285                 }
00286                 if (!discard) {
00287                     Polygon* poly = new Polygon(id, type, color, vec, false);
00288                     if (!toFill.insert(id, poly, 1)) {
00289                         WRITE_ERROR("Polygon '" + id + "' could not been added.");
00290                         delete poly;
00291                     }
00292                 }
00293                 vec.clear();
00294             }
00295             lastID = id;
00296             first = false;
00297             // parse current poly
00298             std::string index = st.next();
00299             std::string xpos = st.next();
00300             std::string ypos = st.next();
00301             Position pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
00302             if (!geoConvHelper.x2cartesian(pos2D)) {
00303                 WRITE_WARNING("Unable to project coordinates for polygon '" + id + "'.");
00304             }
00305             vec.push_back(pos2D);
00306         }
00307 
00308         // district refering a shape
00309         if (parsingDistrictsDirectly) {
00310             //$BEZIRK:NR    CODE    NAME    TYPNR   XKOORD  YKOORD  FLAECHEID   BEZART  IVANTEIL_Q  IVANTEIL_Z  OEVANTEIL   METHODEANBANTEILE   ZWERT1  ZWERT2  ZWERT3  ISTINAUSWAHL    OBEZNR  NOM_COM COD_COM
00311             StringTokenizer st(line, ";");
00312             std::string num = st.next();
00313             std::string code = st.next();
00314             std::string name = st.next();
00315             st.next(); // typntr
00316             std::string xpos = st.next();
00317             std::string ypos = st.next();
00318             long id = TplConvert<char>::_2long(st.next().c_str());
00319             // patch the values
00320             std::string type = "district";
00321             name = num;
00322             bool discard = oc.getBool("discard");
00323             int layer = oc.getInt("layer");
00324             RGBColor color;
00325             if (tm.has(type)) {
00326                 const PCTypeMap::TypeDef& def = tm.get(type);
00327                 name = def.prefix + name;
00328                 type = def.id;
00329                 color = RGBColor::parseColor(def.color);
00330                 discard = def.discard;
00331                 layer = def.layer;
00332             } else {
00333                 name = oc.getString("prefix") + name;
00334                 type = oc.getString("type");
00335                 color = c;
00336             }
00337             if (!discard) {
00338                 if (teilflaechen[flaechenelemente[id]].size()>0) {
00339                     Polygon* poly = new Polygon(name, type, color, teilflaechen[flaechenelemente[id]], false);
00340                     if (!toFill.insert(name, poly, layer)) {
00341                         WRITE_ERROR("Polygon '" + name + "' could not been added.");
00342                         delete poly;
00343                     }
00344                 } else {
00345                     SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00346                     SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00347                     Position pos(x, y);
00348                     if (!geoConvHelper.x2cartesian(pos)) {
00349                         WRITE_WARNING("Unable to project coordinates for POI '" + name + "'.");
00350                     }
00351                     PointOfInterest* poi = new PointOfInterest(name, type, pos, color);
00352                     if (!toFill.insert(name, poi, layer)) {
00353                         WRITE_ERROR("POI '" + name + "' could not been added.");
00354                         delete poi;
00355                     }
00356                 }
00357             }
00358         }
00359 
00360 
00361         if (line.find("$POIKATEGORIEDEF:")==0||line.find("$POIKATEGORIE:")==0) {
00362             // ok, got categories, begin parsing from next line
00363             parsingCategories = true;
00364         }
00365         if (line.find("$POI:")==0) {
00366             // ok, got pois, begin parsing from next line
00367             parsingPOIs = true;
00368         }
00369         if (line.find("$BEZIRK")==0 && line.find("FLAECHEID")!=std::string::npos) {
00370             // ok, have a district header, and it seems like districts would reference shapes...
00371             parsingDistrictsDirectly = true;
00372         }
00373 
00374 
00375         if (line.find("$BEZIRKPOLY")!=std::string::npos) {
00376             polyType = "district";
00377         }
00378         if (line.find("$GEBIETPOLY")!=std::string::npos) {
00379             polyType = "area";
00380         }
00381 
00382     }
00383 }
00384 
00385 
00386 
00387 /****************************************************************************/
00388 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines