SUMO - Simulation of Urban MObility

PCLoaderVisum.cpp

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