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