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; /// hmmmm - assume it's sorted...
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             lineParser.parseLine(line);
00226             long idL = TplConvert<char>::_2long(lineParser.get("Nr").c_str());
00227             std::string id = toString(idL);
00228             std::string catid = lineParser.get("CATID");
00229             // process read values
00230             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKoord").c_str());
00231             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKoord").c_str());
00232             Position pos(x, y);
00233             if (!geoConvHelper.x2cartesian(pos)) {
00234                 WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
00235             }
00236             std::string type = typemap[catid];
00237             // patch the values
00238             bool discard = oc.getBool("discard");
00239             int layer = oc.getInt("layer");
00240             RGBColor color;
00241             if (tm.has(type)) {
00242                 const PCTypeMap::TypeDef& def = tm.get(type);
00243                 id = def.prefix + id;
00244                 type = def.id;
00245                 color = RGBColor::parseColor(def.color);
00246                 discard = def.discard;
00247                 layer = def.layer;
00248             } else {
00249                 id = oc.getString("prefix") + id;
00250                 type = oc.getString("type");
00251                 color = c;
00252             }
00253             if (!discard) {
00254                 PointOfInterest* poi = new PointOfInterest(id, type, pos, color);
00255                 if (!toFill.insert(id, poi, layer)) {
00256                     WRITE_ERROR("POI '" + id + "' could not been added.");
00257                     delete poi;
00258                 }
00259             }
00260         }
00261 
00262         // poly
00263         if (polyType != "") {
00264             StringTokenizer st(line, ";");
00265             std::string id = st.next();
00266             std::string type;
00267             if (!first && lastID != id) {
00268                 // we have parsed a polygon completely
00269                 RGBColor color;
00270                 int layer = oc.getInt("layer");
00271                 bool discard = oc.getBool("discard");
00272                 if (tm.has(polyType)) {
00273                     const PCTypeMap::TypeDef& def = tm.get(polyType);
00274                     id = def.prefix + id;
00275                     type = def.id;
00276                     color = RGBColor::parseColor(def.color);
00277                     discard = def.discard;
00278                     layer = def.layer;
00279                 } else {
00280                     id = oc.getString("prefix") + id;
00281                     type = oc.getString("type");
00282                     color = c;
00283                 }
00284                 if (!discard) {
00285                     Polygon* poly = new Polygon(id, type, color, vec, false);
00286                     if (!toFill.insert(id, poly, 1)) {
00287                         WRITE_ERROR("Polygon '" + id + "' could not been added.");
00288                         delete poly;
00289                     }
00290                 }
00291                 vec.clear();
00292             }
00293             lastID = id;
00294             first = false;
00295             // parse current poly
00296             std::string index = st.next();
00297             std::string xpos = st.next();
00298             std::string ypos = st.next();
00299             Position pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
00300             if (!geoConvHelper.x2cartesian(pos2D)) {
00301                 WRITE_WARNING("Unable to project coordinates for polygon '" + id + "'.");
00302             }
00303             vec.push_back(pos2D);
00304         }
00305 
00306         // district refering a shape
00307         if (parsingDistrictsDirectly) {
00308             //$BEZIRK:NR    CODE    NAME    TYPNR   XKOORD  YKOORD  FLAECHEID   BEZART  IVANTEIL_Q  IVANTEIL_Z  OEVANTEIL   METHODEANBANTEILE   ZWERT1  ZWERT2  ZWERT3  ISTINAUSWAHL    OBEZNR  NOM_COM COD_COM
00309             lineParser.parseLine(line);
00310             long idL = TplConvert<char>::_2long(lineParser.get("NR").c_str());
00311             std::string id = toString(idL);
00312             long area = TplConvert<char>::_2long(lineParser.get("FLAECHEID").c_str());
00313             SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00314             SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00315             // patch the values
00316             std::string type = "district";
00317             bool discard = oc.getBool("discard");
00318             int layer = oc.getInt("layer");
00319             RGBColor color;
00320             if (tm.has(type)) {
00321                 const PCTypeMap::TypeDef& def = tm.get(type);
00322                 id = def.prefix + id;
00323                 type = def.id;
00324                 color = RGBColor::parseColor(def.color);
00325                 discard = def.discard;
00326                 layer = def.layer;
00327             } else {
00328                 id = oc.getString("prefix") + id;
00329                 type = oc.getString("type");
00330                 color = c;
00331             }
00332             if (!discard) {
00333                 if (teilflaechen[flaechenelemente[area]].size() > 0) {
00334                     Polygon* poly = new Polygon(id, type, color, teilflaechen[flaechenelemente[area]], false);
00335                     if (!toFill.insert(id, poly, layer)) {
00336                         WRITE_ERROR("Polygon '" + id + "' could not been added.");
00337                         delete poly;
00338                     }
00339                 } else {
00340                     Position pos(x, y);
00341                     if (!geoConvHelper.x2cartesian(pos)) {
00342                         WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
00343                     }
00344                     PointOfInterest* poi = new PointOfInterest(id, type, pos, color);
00345                     if (!toFill.insert(id, poi, layer)) {
00346                         WRITE_ERROR("POI '" + id + "' could not been added.");
00347                         delete poi;
00348                     }
00349                 }
00350             }
00351         }
00352 
00353 
00354         if (line.find("$POIKATEGORIEDEF:") == 0 || line.find("$POIKATEGORIE:") == 0) {
00355             // ok, got categories, begin parsing from next line
00356             parsingCategories = true;
00357             lineParser.reinit(line.substr(line.find(":") + 1));
00358         }
00359         if (line.find("$POI:") == 0) {
00360             // ok, got pois, begin parsing from next line
00361             parsingPOIs = true;
00362             lineParser.reinit(line.substr(line.find(":") + 1));
00363         }
00364         if (line.find("$BEZIRK") == 0 && line.find("FLAECHEID") != std::string::npos) {
00365             // ok, have a district header, and it seems like districts would reference shapes...
00366             parsingDistrictsDirectly = true;
00367             lineParser.reinit(line.substr(line.find(":") + 1));
00368         }
00369 
00370 
00371         if (line.find("$BEZIRKPOLY") != std::string::npos) {
00372             polyType = "district";
00373         }
00374         if (line.find("$GEBIETPOLY") != std::string::npos) {
00375             polyType = "area";
00376         }
00377 
00378     }
00379 }
00380 
00381 
00382 
00383 /****************************************************************************/
00384 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines