SUMO - Simulation of Urban MObility
|
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