|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // A VISUM network importer 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 <utils/common/MsgHandler.h> 00032 #include <utils/common/TplConvert.h> 00033 #include <utils/common/ToString.h> 00034 #include <utils/options/OptionsCont.h> 00035 #include <utils/geom/GeoConvHelper.h> 00036 #include <netbuild/NBDistrict.h> 00037 #include <utils/common/TplConvertSec.h> 00038 00039 #include <netbuild/NBNetBuilder.h> 00040 #include "NILoader.h" 00041 #include "NIImporter_VISUM.h" 00042 00043 #ifdef CHECK_MEMORY_LEAKS 00044 #include <foreign/nvwa/debug_new.h> 00045 #endif // CHECK_MEMORY_LEAKS 00046 00047 00048 // =========================================================================== 00049 // method definitions 00050 // =========================================================================== 00051 // --------------------------------------------------------------------------- 00052 // static methods (interface in this case) 00053 // --------------------------------------------------------------------------- 00054 void 00055 NIImporter_VISUM::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { 00056 // check whether the option is set (properly) 00057 if (!oc.isSet("visum-file")) { 00058 return; 00059 } 00060 // build the handler 00061 NIImporter_VISUM loader(nb, oc.getString("visum-file"), 00062 NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm")), 00063 oc.getBool("visum.use-type-priority")); 00064 loader.load(); 00065 } 00066 00067 00068 00069 // --------------------------------------------------------------------------- 00070 // loader methods 00071 // --------------------------------------------------------------------------- 00072 NIImporter_VISUM::NIImporter_VISUM(NBNetBuilder& nb, 00073 const std::string& file, 00074 NBCapacity2Lanes capacity2Lanes, 00075 bool useVisumPrio) throw() 00076 : myNetBuilder(nb), myFileName(file), 00077 myCapacity2Lanes(capacity2Lanes), myUseVisumPrio(useVisumPrio) { 00078 // the order of process is important! 00079 // set1 00080 addParser("VSYS", &NIImporter_VISUM::parse_VSysTypes); 00081 addParser("STRECKENTYP", &NIImporter_VISUM::parse_Types); 00082 addParser("KNOTEN", &NIImporter_VISUM::parse_Nodes); 00083 addParser("BEZIRK", &NIImporter_VISUM::parse_Districts); 00084 addParser("PUNKT", &NIImporter_VISUM::parse_Point); 00085 00086 00087 // set2 00088 // two types of "strecke" 00089 addParser("STRECKE", &NIImporter_VISUM::parse_Edges); 00090 addParser("STRECKEN", &NIImporter_VISUM::parse_Edges); 00091 addParser("KANTE", &NIImporter_VISUM::parse_Kante); 00092 00093 00094 // set3 00095 addParser("ANBINDUNG", &NIImporter_VISUM::parse_Connectors); 00096 // two types of "abbieger" 00097 addParser("ABBIEGEBEZIEHUNG", &NIImporter_VISUM::parse_Turns); 00098 addParser("ABBIEGER", &NIImporter_VISUM::parse_Turns); 00099 00100 addParser("STRECKENPOLY", &NIImporter_VISUM::parse_EdgePolys); 00101 addParser("FAHRSTREIFEN", &NIImporter_VISUM::parse_Lanes); 00102 addParser("FLAECHENELEMENT", &NIImporter_VISUM::parse_PartOfArea); 00103 00104 00105 // set4 00106 // two types of lsa 00107 addParser("LSA", &NIImporter_VISUM::parse_TrafficLights); 00108 addParser("SIGNALANLAGE", &NIImporter_VISUM::parse_TrafficLights); 00109 // two types of knotenzulsa 00110 addParser("KNOTENZULSA", &NIImporter_VISUM::parse_NodesToTrafficLights); 00111 addParser("LSAZUKNOTEN", &NIImporter_VISUM::parse_NodesToTrafficLights); 00112 addParser("SIGNALANLAGEZUKNOTEN", &NIImporter_VISUM::parse_NodesToTrafficLights); 00113 // two types of signalgruppe 00114 addParser("LSASIGNALGRUPPE", &NIImporter_VISUM::parse_SignalGroups); 00115 addParser("SIGNALGRUPPE", &NIImporter_VISUM::parse_SignalGroups); 00116 // two types of ABBZULSASIGNALGRUPPE 00117 addParser("ABBZULSASIGNALGRUPPE", &NIImporter_VISUM::parse_TurnsToSignalGroups); 00118 addParser("SIGNALGRUPPEZUABBIEGER", &NIImporter_VISUM::parse_TurnsToSignalGroups); 00119 addParser("SIGNALGRUPPEZUFSABBIEGER", &NIImporter_VISUM::parse_TurnsToSignalGroups); 00120 00121 addParser("TEILFLAECHENELEMENT", &NIImporter_VISUM::parse_AreaSubPartElement); 00122 00123 // two types of LSAPHASE 00124 addParser("LSAPHASE", &NIImporter_VISUM::parse_Phases); 00125 addParser("PHASE", &NIImporter_VISUM::parse_Phases); 00126 00127 addParser("LSASIGNALGRUPPEZULSAPHASE", &NIImporter_VISUM::parse_SignalGroupsToPhases); 00128 addParser("FAHRSTREIFENABBIEGER", &NIImporter_VISUM::parse_LanesConnections); 00129 } 00130 00131 00132 NIImporter_VISUM::~NIImporter_VISUM() throw() { 00133 for (NIVisumTL_Map::iterator j=myNIVisumTLs.begin(); j!=myNIVisumTLs.end(); j++) { 00134 delete j->second; 00135 } 00136 } 00137 00138 00139 void 00140 NIImporter_VISUM::addParser(const std::string& name, ParsingFunction function) throw() { 00141 TypeParser p; 00142 p.name = name; 00143 p.function = function; 00144 p.position = -1; 00145 mySingleDataParsers.push_back(p); 00146 } 00147 00148 00149 void 00150 NIImporter_VISUM::load() throw(ProcessError) { 00151 // open the file 00152 if (!myLineReader.setFile(myFileName)) { 00153 throw ProcessError("Can not open visum-file '" + myFileName + "'."); 00154 } 00155 // scan the file for data positions 00156 while (myLineReader.hasMore()) { 00157 std::string line = myLineReader.readLine(); 00158 if (line.length()>0 && line[0]=='$') { 00159 ParserVector::iterator i; 00160 for (i=mySingleDataParsers.begin(); i!=mySingleDataParsers.end(); i++) { 00161 std::string dataName = "$" + (*i).name + ":"; 00162 if (line.substr(0, dataName.length())==dataName) { 00163 (*i).position = myLineReader.getPosition(); 00164 (*i).pattern = line.substr(dataName.length()); 00165 WRITE_MESSAGE("Found: " + dataName + " at " + toString<int>(myLineReader.getPosition())); 00166 } 00167 } 00168 } 00169 } 00170 // go through the parsers and process all entries 00171 for (ParserVector::iterator i=mySingleDataParsers.begin(); i!=mySingleDataParsers.end(); i++) { 00172 if ((*i).position<0) { 00173 // do not process using parsers for which no information was found 00174 continue; 00175 } 00176 // ok, the according information is stored in the file 00177 PROGRESS_BEGIN_MESSAGE("Parsing " + (*i).name); 00178 // reset the line reader and let it point to the begin of the according data field 00179 myLineReader.reinit(); 00180 myLineReader.setPos((*i).position); 00181 // prepare the line parser 00182 myLineParser.reinit((*i).pattern); 00183 // read 00184 bool singleDataEndFound = false; 00185 while (myLineReader.hasMore() && !singleDataEndFound) { 00186 std::string line = myLineReader.readLine(); 00187 if (line.length()==0||line[0]=='*'||line[0]=='$') { 00188 singleDataEndFound = true; 00189 } else { 00190 myLineParser.parseLine(line); 00191 try { 00192 myCurrentID = "<unknown>"; 00193 (this->*(*i).function)(); 00194 } catch (OutOfBoundsException&) { 00195 WRITE_ERROR("Too short value line in " + (*i).name + " occured."); 00196 } catch (NumberFormatException&) { 00197 WRITE_ERROR("A value in " + (*i).name + " should be numeric but is not (id='" + myCurrentID + "')."); 00198 } catch (UnknownElement& e) { 00199 WRITE_ERROR("One of the needed values ('" + std::string(e.what()) + "') is missing in " + (*i).name + "."); 00200 } 00201 } 00202 } 00203 // close single reader processing 00204 PROGRESS_DONE_MESSAGE(); 00205 } 00206 // build traffic lights 00207 for (NIVisumTL_Map::iterator j=myNIVisumTLs.begin(); j!=myNIVisumTLs.end(); j++) { 00208 j->second->build(myNetBuilder.getTLLogicCont()); 00209 } 00210 // build district shapes 00211 for (std::map<NBDistrict*, PositionVector>::const_iterator k=myDistrictShapes.begin(); k!=myDistrictShapes.end(); ++k) { 00212 (*k).first->addShape((*k).second); 00213 } 00214 } 00215 00216 00217 00218 00219 00220 void 00221 NIImporter_VISUM::parse_VSysTypes() { 00222 std::string name = myLineParser.know("VSysCode") ? myLineParser.get("VSysCode").c_str() : myLineParser.get("CODE").c_str(); 00223 std::string type = myLineParser.know("VSysMode") ? myLineParser.get("VSysMode").c_str() : myLineParser.get("Typ").c_str(); 00224 myVSysTypes[name] = type; 00225 } 00226 00227 00228 void 00229 NIImporter_VISUM::parse_Types() { 00230 // get the id 00231 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00232 // get the maximum speed 00233 SUMOReal speed = getNamedFloat("v0-IV", "V0IV"); 00234 // get the priority 00235 int priority = 1000-TplConvert<char>::_2int(myLineParser.get("Rang").c_str()); 00236 // try to retrieve the number of lanes 00237 SUMOReal cap = getNamedFloat("Kap-IV", "KAPIV"); 00238 int nolanes = myCapacity2Lanes.get(cap); 00239 // insert the type 00240 myNetBuilder.getTypeCont().insert(myCurrentID, nolanes, speed/(SUMOReal) 3.6, priority, -1); 00241 } 00242 00243 00244 void 00245 NIImporter_VISUM::parse_Nodes() { 00246 // get the id 00247 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00248 // get the position 00249 SUMOReal x = getNamedFloat("XKoord"); 00250 SUMOReal y = getNamedFloat("YKoord"); 00251 Position pos(x, y); 00252 if (!NILoader::transformCoordinates(pos)) { 00253 WRITE_ERROR("Unable to project coordinates for node " + myCurrentID + "."); 00254 return; 00255 } 00256 // add to the list 00257 if (!myNetBuilder.getNodeCont().insert(myCurrentID, pos)) { 00258 WRITE_ERROR("Duplicate node occured ('" + myCurrentID + "')."); 00259 } 00260 } 00261 00262 00263 void 00264 NIImporter_VISUM::parse_Districts() { 00265 // get the id 00266 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00267 // get the information whether the source and the destination 00268 // connections are weighted 00269 //bool sourcesWeighted = getWeightedBool("Proz_Q"); 00270 //bool destWeighted = getWeightedBool("Proz_Z"); 00271 // get the node information 00272 SUMOReal x = getNamedFloat("XKoord"); 00273 SUMOReal y = getNamedFloat("YKoord"); 00274 Position pos(x, y); 00275 if (!NILoader::transformCoordinates(pos, false)) { 00276 WRITE_ERROR("Unable to project coordinates for district " + myCurrentID + "."); 00277 return; 00278 } 00279 // build the district 00280 NBDistrict* district = new NBDistrict(myCurrentID, pos); 00281 if (!myNetBuilder.getDistrictCont().insert(district)) { 00282 WRITE_ERROR("Duplicate district occured ('" + myCurrentID + "')."); 00283 delete district; 00284 return; 00285 } 00286 if (myLineParser.know("FLAECHEID")) { 00287 long flaecheID = TplConvert<char>::_2long(myLineParser.get("FLAECHEID").c_str()); 00288 myShapeDistrictMap[flaecheID] = district; 00289 } 00290 } 00291 00292 00293 void 00294 NIImporter_VISUM::parse_Point() { 00295 long id = TplConvert<char>::_2long(myLineParser.get("ID").c_str()); 00296 SUMOReal x = TplConvert<char>::_2SUMOReal(myLineParser.get("XKOORD").c_str()); 00297 SUMOReal y = TplConvert<char>::_2SUMOReal(myLineParser.get("YKOORD").c_str()); 00298 Position pos(x, y); 00299 if (!NILoader::transformCoordinates(pos, false)) { 00300 WRITE_ERROR("Unable to project coordinates for point " + toString(id) + "."); 00301 return; 00302 } 00303 myPoints[id] = pos; 00304 } 00305 00306 00307 void 00308 NIImporter_VISUM::parse_Edges() { 00309 if (myLineParser.know("VSYSSET") && myLineParser.get("VSYSSET")=="") { 00310 // no vehicle allowed; don't add 00311 return; 00312 } 00313 // get the id 00314 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00315 // get the from- & to-node and validate them 00316 NBNode* from = getNamedNode("VonKnot", "VonKnotNr"); 00317 NBNode* to = getNamedNode("NachKnot", "NachKnotNr"); 00318 if (!checkNodes(from, to)) { 00319 return; 00320 } 00321 // get the type 00322 std::string type = myLineParser.know("Typ") ? myLineParser.get("Typ") : myLineParser.get("TypNr"); 00323 // get the speed 00324 SUMOReal speed = myNetBuilder.getTypeCont().getSpeed(type); 00325 if (!OptionsCont::getOptions().getBool("visum.use-type-speed")) { 00326 try { 00327 speed = myLineParser.know("v0-IV") 00328 ? TplConvertSec<char>::_2SUMORealSec(myLineParser.get("v0-IV").c_str(), -1) 00329 : TplConvertSec<char>::_2SUMORealSec(myLineParser.get("V0IV").c_str(), -1); 00330 speed = speed / (SUMOReal) 3.6; 00331 } catch (OutOfBoundsException) {} 00332 } 00333 if (speed<=0) { 00334 speed = myNetBuilder.getTypeCont().getSpeed(type); 00335 } 00336 00337 // get the information whether the edge is a one-way 00338 bool oneway = myLineParser.know("Einbahn") 00339 ? TplConvert<char>::_2bool(myLineParser.get("Einbahn").c_str()) 00340 : true; 00341 // get the number of lanes 00342 int nolanes = myNetBuilder.getTypeCont().getNumLanes(type); 00343 if (!OptionsCont::getOptions().getBool("visum.recompute-lane-number")) { 00344 try { 00345 if (!OptionsCont::getOptions().getBool("visum.use-type-laneno")) { 00346 nolanes = myLineParser.know("Fahrstreifen") 00347 ? TplConvertSec<char>::_2intSec(myLineParser.get("Fahrstreifen").c_str(), 0) 00348 : TplConvertSec<char>::_2intSec(myLineParser.get("ANZFAHRSTREIFEN").c_str(), 0); 00349 } 00350 } catch (UnknownElement) { 00351 } 00352 } else { 00353 SUMOReal cap = myLineParser.know("KAPIV") 00354 ? TplConvertSec<char>::_2SUMORealSec(myLineParser.get("KAPIV").c_str(), -1) 00355 : TplConvertSec<char>::_2SUMORealSec(myLineParser.get("KAP-IV").c_str(), -1); 00356 nolanes = myCapacity2Lanes.get(cap); 00357 } 00358 // check whether the id is already used 00359 // (should be the opposite direction) 00360 bool oneway_checked = oneway; 00361 NBEdge* previous = myNetBuilder.getEdgeCont().retrieve(myCurrentID); 00362 if (previous!=0) { 00363 myCurrentID = '-' + myCurrentID; 00364 previous->setLaneSpreadFunction(LANESPREAD_RIGHT); 00365 oneway_checked = false; 00366 } 00367 if (find(myTouchedEdges.begin(), myTouchedEdges.end(), myCurrentID)!=myTouchedEdges.end()) { 00368 oneway_checked = false; 00369 } 00370 std::string tmpid = '-' + myCurrentID; 00371 if (find(myTouchedEdges.begin(), myTouchedEdges.end(), tmpid)!=myTouchedEdges.end()) { 00372 previous = myNetBuilder.getEdgeCont().retrieve(tmpid); 00373 if (previous!=0) { 00374 previous->setLaneSpreadFunction(LANESPREAD_RIGHT); 00375 } 00376 oneway_checked = false; 00377 } 00378 // add the edge 00379 int prio = myUseVisumPrio ? myNetBuilder.getTypeCont().getPriority(type) : -1; 00380 if (nolanes!=0&&speed!=0) { 00381 LaneSpreadFunction lsf = oneway_checked ? LANESPREAD_CENTER : LANESPREAD_RIGHT; 00382 // @todo parse name from visum files 00383 NBEdge* e = new NBEdge(myCurrentID, from, to, type, speed, nolanes, prio, 00384 NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, "", lsf); 00385 if (!myNetBuilder.getEdgeCont().insert(e)) { 00386 delete e; 00387 WRITE_ERROR("Duplicate edge occured ('" + myCurrentID + "')."); 00388 } 00389 } 00390 myTouchedEdges.push_back(myCurrentID); 00391 // nothing more to do, when the edge is a one-way street 00392 if (oneway) { 00393 return; 00394 } 00395 // add the opposite edge 00396 myCurrentID = '-' + myCurrentID; 00397 if (nolanes!=0&&speed!=0) { 00398 LaneSpreadFunction lsf = oneway_checked ? LANESPREAD_CENTER : LANESPREAD_RIGHT; 00399 // @todo parse name from visum files 00400 NBEdge* e = new NBEdge(myCurrentID, from, to, type, speed, nolanes, prio, 00401 NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, "", lsf); 00402 if (!myNetBuilder.getEdgeCont().insert(e)) { 00403 delete e; 00404 WRITE_ERROR("Duplicate edge occured ('" + myCurrentID + "')."); 00405 } 00406 } 00407 myTouchedEdges.push_back(myCurrentID); 00408 } 00409 00410 00411 void 00412 NIImporter_VISUM::parse_Kante() { 00413 long id = TplConvert<char>::_2long(myLineParser.get("ID").c_str()); 00414 long from = TplConvert<char>::_2long(myLineParser.get("VONPUNKTID").c_str()); 00415 long to = TplConvert<char>::_2long(myLineParser.get("NACHPUNKTID").c_str()); 00416 myEdges[id] = std::make_pair(from, to); 00417 } 00418 00419 00420 void 00421 NIImporter_VISUM::parse_PartOfArea() { 00422 long flaecheID = TplConvert<char>::_2long(myLineParser.get("FLAECHEID").c_str()); 00423 long flaechePartID = TplConvert<char>::_2long(myLineParser.get("TFLAECHEID").c_str()); 00424 if (mySubPartsAreas.find(flaechePartID)==mySubPartsAreas.end()) { 00425 mySubPartsAreas[flaechePartID] = std::vector<long>(); 00426 } 00427 mySubPartsAreas[flaechePartID].push_back(flaecheID); 00428 } 00429 00430 00431 void 00432 NIImporter_VISUM::parse_Connectors() { 00433 if (OptionsCont::getOptions().getBool("visum.no-connectors")) { 00434 // do nothing, if connectors shall not be imported 00435 return; 00436 } 00437 // get the source district 00438 std::string bez = NBHelpers::normalIDRepresentation(myLineParser.get("BezNr")); 00439 // get the destination node 00440 NBNode* dest = getNamedNode("KnotNr"); 00441 if (dest==0) { 00442 return; 00443 } 00444 // get the weight of the connection 00445 SUMOReal proz = getWeightedFloat("Proz"); 00446 if (proz>0) { 00447 proz /= 100.; 00448 } else { 00449 proz = 1; 00450 } 00451 // get the duration to wait 00452 SUMOReal retard = -1; 00453 if (myLineParser.know("t0-IV")) { 00454 retard = getNamedFloat("t0-IV", -1); 00455 } 00456 // get the type; 00457 // use a standard type with a large speed when a type is not given 00458 std::string type = myLineParser.know("Typ") 00459 ? NBHelpers::normalIDRepresentation(myLineParser.get("Typ")) 00460 : ""; 00461 // add the connectors as an edge 00462 std::string id = bez + "-" + dest->getID(); 00463 // get the information whether this is a sink or a source 00464 std::string dir = myLineParser.get("Richtung"); 00465 if (dir.length()==0) { 00466 dir = "QZ"; 00467 } 00468 // build the source when needed 00469 if (dir.find('Q')!=std::string::npos) { 00470 const EdgeVector& edges = dest->getOutgoingEdges(); 00471 bool hasContinuation = false; 00472 for (EdgeVector::const_iterator i=edges.begin(); i!=edges.end(); ++i) { 00473 if (!(*i)->isMacroscopicConnector()) { 00474 hasContinuation = true; 00475 } 00476 } 00477 if (!hasContinuation) { 00478 // obviously, there is no continuation on the net 00479 WRITE_WARNING("Incoming connector '" + id + "' will not be build - would be not connected to network."); 00480 } else { 00481 NBNode* src = buildDistrictNode(bez, dest, true); 00482 if (src==0) { 00483 WRITE_ERROR("The district '" + bez + "' could not be built."); 00484 return; 00485 } 00486 NBEdge* edge = new NBEdge(id, src, dest, "VisumConnector", 00487 OptionsCont::getOptions().getFloat("visum.connector-speeds"), 00488 OptionsCont::getOptions().getInt("visum.connectors-lane-number"), 00489 -1, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, 00490 "", LANESPREAD_RIGHT); 00491 edge->setAsMacroscopicConnector(); 00492 if (!myNetBuilder.getEdgeCont().insert(edge)) { 00493 WRITE_ERROR("A duplicate edge id occured (ID='" + id + "')."); 00494 return; 00495 } 00496 edge = myNetBuilder.getEdgeCont().retrieve(id); 00497 if (edge!=0) { 00498 myNetBuilder.getDistrictCont().addSource(bez, edge, proz); 00499 } 00500 } 00501 } 00502 // build the sink when needed 00503 if (dir.find('Z')!=std::string::npos) { 00504 const EdgeVector& edges = dest->getIncomingEdges(); 00505 bool hasPredeccessor = false; 00506 for (EdgeVector::const_iterator i=edges.begin(); i!=edges.end(); ++i) { 00507 if (!(*i)->isMacroscopicConnector()) { 00508 hasPredeccessor = true; 00509 } 00510 } 00511 if (!hasPredeccessor) { 00512 // obviously, the network is not connected to this node 00513 WRITE_WARNING("Outgoing connector '" + id + "' will not be build - would be not connected to network."); 00514 } else { 00515 NBNode* src = buildDistrictNode(bez, dest, false); 00516 if (src==0) { 00517 WRITE_ERROR("The district '" + bez + "' could not be built."); 00518 return; 00519 } 00520 id = "-" + id; 00521 NBEdge* edge = new NBEdge(id, dest, src, "VisumConnector", 00522 OptionsCont::getOptions().getFloat("visum.connector-speeds"), 00523 OptionsCont::getOptions().getInt("visum.connectors-lane-number"), 00524 -1, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, 00525 "", LANESPREAD_RIGHT); 00526 edge->setAsMacroscopicConnector(); 00527 if (!myNetBuilder.getEdgeCont().insert(edge)) { 00528 WRITE_ERROR("A duplicate edge id occured (ID='" + id + "')."); 00529 return; 00530 } 00531 edge = myNetBuilder.getEdgeCont().retrieve(id); 00532 if (edge!=0) { 00533 myNetBuilder.getDistrictCont().addSink(bez, edge, proz); 00534 } 00535 } 00536 } 00537 } 00538 00539 00540 void 00541 NIImporter_VISUM::parse_Turns() { 00542 if (myLineParser.know("VSYSSET") && myLineParser.get("VSYSSET")=="") { 00543 // no vehicle allowed; don't add 00544 return; 00545 } 00546 // retrieve the nodes 00547 NBNode* from = getNamedNode("VonKnot", "VonKnotNr"); 00548 NBNode* via = getNamedNode("UeberKnot", "UeberKnotNr"); 00549 NBNode* to = getNamedNode("NachKnot", "NachKnotNr"); 00550 if (from==0||via==0||to==0) { 00551 return; 00552 } 00553 // all nodes are known 00554 std::string type = myLineParser.know("VSysCode") 00555 ? myLineParser.get("VSysCode") 00556 : myLineParser.get("VSYSSET"); 00557 if (myVSysTypes.find(type)!=myVSysTypes.end() && myVSysTypes.find(type)->second=="IV") { 00558 // try to set the turning definition 00559 NBEdge* src = from->getConnectionTo(via); 00560 NBEdge* dest = via->getConnectionTo(to); 00561 // check both 00562 if (src==0) { 00563 // maybe it was removed due to something 00564 if (OptionsCont::getOptions().isSet("keep-edges.min-speed") 00565 || 00566 OptionsCont::getOptions().isSet("keep-edges.explicit")) { 00567 WRITE_WARNING("Could not set connection from node '" + from->getID() + "' to node '" + via->getID() + "'."); 00568 } else { 00569 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) { 00570 WRITE_WARNING("There is no edge from node '" + from->getID() + "' to node '" + via->getID() + "'."); 00571 } 00572 } 00573 return; 00574 } 00575 if (dest==0) { 00576 if (OptionsCont::getOptions().isSet("keep-edges.min-speed") 00577 || 00578 OptionsCont::getOptions().isSet("keep-edges.explicit")) { 00579 WRITE_WARNING("Could not set connection from node '" + via->getID() + "' to node '" + to->getID() + "'."); 00580 } else { 00581 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) { 00582 WRITE_WARNING("There is no edge from node '" + via->getID() + "' to node '" + to->getID() + "'."); 00583 } 00584 } 00585 return; 00586 } 00587 // both edges found 00588 // set them into the edge 00589 src->setTurningDestination(dest); 00590 } 00591 } 00592 00593 00594 void 00595 NIImporter_VISUM::parse_EdgePolys() { 00596 // get the from- & to-node and validate them 00597 NBNode* from = getNamedNode("VonKnot", "VonKnotNr"); 00598 NBNode* to = getNamedNode("NachKnot", "NachKnotNr"); 00599 if (!checkNodes(from, to)) { 00600 return; 00601 } 00602 bool failed = false; 00603 int index; 00604 SUMOReal x, y; 00605 try { 00606 index = TplConvert<char>::_2int(myLineParser.get("INDEX").c_str()); 00607 x = getNamedFloat("XKoord"); 00608 y = getNamedFloat("YKoord"); 00609 } catch (NumberFormatException&) { 00610 WRITE_ERROR("Error in geometry description from node '" + from->getID() + "' to node '" + to->getID() + "'."); 00611 return; 00612 } 00613 Position pos(x, y); 00614 if (!NILoader::transformCoordinates(pos)) { 00615 WRITE_ERROR("Unable to project coordinates for node '" + from->getID() + "'."); 00616 return; 00617 } 00618 NBEdge* e = from->getConnectionTo(to); 00619 if (e!=0) { 00620 e->addGeometryPoint(index, pos); 00621 } else { 00622 failed = true; 00623 } 00624 e = to->getConnectionTo(from); 00625 if (e!=0) { 00626 e->addGeometryPoint(-index, pos); 00627 failed = false; 00628 } 00629 // check whether the operation has failed 00630 if (failed) { 00631 // we should report this to the warning instance only if we have removed 00632 // some nodes or edges... 00633 if (OptionsCont::getOptions().isSet("keep-edges.min-speed") || OptionsCont::getOptions().isSet("keep-edges.explicit")) { 00634 WRITE_WARNING("Could not set geometry between node '" + from->getID() + "' and node '" + to->getID() + "'."); 00635 } else { 00636 // ... in the other case we report this to the error instance 00637 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) { 00638 WRITE_WARNING("There is no edge from node '" + from->getID() + "' to node '" + to->getID() + "'."); 00639 } 00640 } 00641 } 00642 } 00643 00644 00645 void 00646 NIImporter_VISUM::parse_Lanes() { 00647 // get the node 00648 NBNode* node = getNamedNode("KNOTNR"); 00649 // get the edge 00650 NBEdge* baseEdge = getNamedEdge("STRNR"); 00651 NBEdge* edge = getNamedEdgeContinuating("STRNR", node); 00652 // check 00653 if (node==0||edge==0) { 00654 return; 00655 } 00656 // get the lane 00657 std::string laneS = myLineParser.know("FSNR") 00658 ? NBHelpers::normalIDRepresentation(myLineParser.get("FSNR")) 00659 : NBHelpers::normalIDRepresentation(myLineParser.get("NR")); 00660 int lane = -1; 00661 try { 00662 lane = TplConvert<char>::_2int(laneS.c_str()); 00663 } catch (NumberFormatException&) { 00664 WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not numeric (" + laneS + ")."); 00665 return; 00666 } 00667 lane -= 1; 00668 if (lane<0) { 00669 WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not positive (" + laneS + ")."); 00670 return; 00671 } 00672 // get the direction 00673 std::string dirS = NBHelpers::normalIDRepresentation(myLineParser.get("RICHTTYP")); 00674 int prevLaneNo = baseEdge->getNumLanes(); 00675 if ((dirS=="1"&&!(node->hasIncoming(edge))) || (dirS=="0"&&!(node->hasOutgoing(edge)))) { 00676 // get the last part of the turnaround direction 00677 edge = getReversedContinuating(edge, node); 00678 } 00679 // get the length 00680 std::string lengthS = NBHelpers::normalIDRepresentation(myLineParser.get("LAENGE")); 00681 SUMOReal length = -1; 00682 try { 00683 length = TplConvert<char>::_2SUMOReal(lengthS.c_str()); 00684 } catch (NumberFormatException&) { 00685 WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not numeric (" + lengthS + ")."); 00686 return; 00687 } 00688 if (length<0) { 00689 WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not positive (" + lengthS + ")."); 00690 return; 00691 } 00692 // 00693 if (dirS=="1") { 00694 lane -= prevLaneNo; 00695 } 00696 // 00697 if (length==0) { 00698 if ((int) edge->getNumLanes()>lane) { 00699 // ok, we know this already... 00700 return; 00701 } 00702 // increment by one 00703 edge->incLaneNo(1); 00704 } else { 00705 // check whether this edge already has been created 00706 if (edge->getID().substr(edge->getID().length()-node->getID().length()-1)=="_" + node->getID()) { 00707 if (edge->getID().substr(edge->getID().find('_'))=="_" + toString(length) + "_" + node->getID()) { 00708 if ((int) edge->getNumLanes()>lane) { 00709 // ok, we know this already... 00710 return; 00711 } 00712 // increment by one 00713 edge->incLaneNo(1); 00714 return; 00715 } 00716 } 00717 // nope, we have to split the edge... 00718 // maybe it is not the proper edge to split - VISUM seems not to sort the splits... 00719 bool mustRecheck = true; 00720 NBNode* nextNode = node; 00721 SUMOReal seenLength = 0; 00722 while (mustRecheck) { 00723 if (edge->getID().substr(edge->getID().length()-node->getID().length()-1)=="_" + node->getID()) { 00724 // ok, we have a previously created edge here 00725 std::string sub = edge->getID(); 00726 sub = sub.substr(sub.rfind('_', sub.rfind('_')-1)); 00727 sub = sub.substr(1, sub.find('_', 1)-1); 00728 SUMOReal dist = TplConvert<char>::_2SUMOReal(sub.c_str()); 00729 if (dist<length) { 00730 seenLength += edge->getLength(); 00731 if (dirS=="1") { 00732 // incoming -> move back 00733 edge = edge->getFromNode()->getIncomingEdges()[0]; 00734 nextNode = edge->getToNode(); 00735 nextNode = edge->getFromNode(); 00736 } else { 00737 // outgoing -> move forward 00738 edge = edge->getToNode()->getOutgoingEdges()[0]; 00739 nextNode = edge->getFromNode(); 00740 nextNode = edge->getToNode(); 00741 } 00742 } else { 00743 mustRecheck = false; 00744 } 00745 } else { 00746 // we have the center edge - do not continue... 00747 mustRecheck = false; 00748 } 00749 } 00750 // compute position 00751 Position p; 00752 SUMOReal useLength = length - seenLength; 00753 useLength = edge->getLength()-useLength; 00754 std::string edgeID = edge->getID(); 00755 p = edge->getGeometry().positionAtLengthPosition(useLength); 00756 if (edgeID.substr(edgeID.length()-node->getID().length()-1)=="_" + node->getID()) { 00757 edgeID = edgeID.substr(0, edgeID.find('_')); 00758 } 00759 NBNode* rn = new NBNode(edgeID + "_" + toString((size_t) length) + "_" + node->getID(), p); 00760 if (!myNetBuilder.getNodeCont().insert(rn)) { 00761 throw ProcessError("Ups - could not insert node!"); 00762 } 00763 std::string nid = edgeID + "_" + toString((size_t) length) + "_" + node->getID(); 00764 myNetBuilder.getEdgeCont().splitAt(myNetBuilder.getDistrictCont(), edge, useLength, rn, 00765 edge->getID(), nid, edge->getNumLanes()+0, edge->getNumLanes()+1); 00766 NBEdge* nedge = myNetBuilder.getEdgeCont().retrieve(nid); 00767 nedge = nedge->getToNode()->getOutgoingEdges()[0]; 00768 while (nedge->getID().substr(nedge->getID().length()-node->getID().length()-1)=="_" + node->getID()) { 00769 assert(nedge->getToNode()->getOutgoingEdges().size()>0); 00770 nedge->incLaneNo(1); 00771 nedge = nedge->getToNode()->getOutgoingEdges()[0]; 00772 } 00773 } 00774 } 00775 00776 00777 void 00778 NIImporter_VISUM::parse_TrafficLights() { 00779 // get the id 00780 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00781 // cycle time 00782 SUMOReal CycleTime = getNamedFloat("Umlaufzeit", "UMLZEIT"); 00783 // IntermediateTime 00784 SUMOReal IntermediateTime = getNamedFloat("StdZwischenzeit", "STDZWZEIT"); 00785 // PhaseBased 00786 bool PhaseBased = myLineParser.know("PhasenBasiert") 00787 ? TplConvert<char>::_2bool(myLineParser.get("PhasenBasiert").c_str()) 00788 : false; 00789 // add to the list 00790 myNIVisumTLs[myCurrentID] = new NIVisumTL(myCurrentID, (SUMOTime) CycleTime, (SUMOTime) IntermediateTime, PhaseBased); 00791 } 00792 00793 00794 void 00795 NIImporter_VISUM::parse_NodesToTrafficLights() { 00796 std::string Node = myLineParser.get("KnotNr").c_str(); 00797 std::string TrafficLight = myLineParser.get("LsaNr").c_str(); 00798 // add to the list 00799 myNIVisumTLs[TrafficLight]->GetNodes()->push_back(myNetBuilder.getNodeCont().retrieve(Node)); 00800 } 00801 00802 00803 void 00804 NIImporter_VISUM::parse_SignalGroups() { 00805 // get the id 00806 myCurrentID = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00807 std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr")); 00808 // StartTime 00809 SUMOReal StartTime = getNamedFloat("GzStart", "GRUENANF"); 00810 // EndTime 00811 SUMOReal EndTime = getNamedFloat("GzEnd", "GRUENENDE"); 00812 // add to the list 00813 if (myNIVisumTLs.find(LSAid)==myNIVisumTLs.end()) { 00814 WRITE_ERROR("Could not find TLS '" + LSAid + "' for setting the signal group."); 00815 return; 00816 } 00817 (*myNIVisumTLs.find(LSAid)).second->AddSignalGroup(myCurrentID, (SUMOTime) StartTime, (SUMOTime) EndTime); 00818 } 00819 00820 00821 void 00822 NIImporter_VISUM::parse_TurnsToSignalGroups() { 00823 // get the id 00824 std::string SGid = getNamedString("SGNR", "SIGNALGRUPPENNR"); 00825 std::string LSAid = getNamedString("LsaNr"); 00826 // nodes 00827 NBNode* from = myLineParser.know("VonKnot") ? getNamedNode("VonKnot") : 0; 00828 NBNode* via = myLineParser.know("KNOTNR") 00829 ? getNamedNode("KNOTNR") 00830 : getNamedNode("UeberKnot", "UeberKnotNr"); 00831 NBNode* to = myLineParser.know("NachKnot") ? getNamedNode("NachKnot") : 0; 00832 // edges 00833 NBEdge* edg1 = 0; 00834 NBEdge* edg2 = 0; 00835 if (from==0&&to==0) { 00836 edg1 = getNamedEdgeContinuating("VONSTRNR", via); 00837 edg2 = getNamedEdgeContinuating("NACHSTRNR", via); 00838 } else { 00839 edg1 = getEdge(from, via); 00840 edg2 = getEdge(via, to); 00841 } 00842 // add to the list 00843 NIVisumTL::SignalGroup* SG; 00844 SG = (*myNIVisumTLs.find(LSAid)).second->GetSignalGroup(SGid); 00845 if (edg1!=0 && edg2!=0) { 00846 if (!via->hasIncoming(edg1)) { 00847 std::string sid; 00848 if (edg1->getID()[0]=='-') { 00849 sid = edg1->getID().substr(1); 00850 } else { 00851 sid = "-" + edg1->getID(); 00852 } 00853 if (sid.find('_')!=std::string::npos) { 00854 sid = sid.substr(0, sid.find('_')); 00855 } 00856 edg1 = getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), via); 00857 } 00858 if (!via->hasOutgoing(edg2)) { 00859 std::string sid; 00860 if (edg2->getID()[0]=='-') { 00861 sid = edg2->getID().substr(1); 00862 } else { 00863 sid = "-" + edg2->getID(); 00864 } 00865 if (sid.find('_')!=std::string::npos) { 00866 sid = sid.substr(0, sid.find('_')); 00867 } 00868 edg2 = getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), via); 00869 } 00870 SG->GetConnections()->push_back(NBConnection(edg1, edg2)); 00871 } 00872 } 00873 00874 00875 void 00876 NIImporter_VISUM::parse_AreaSubPartElement() { 00877 long id = TplConvert<char>::_2long(myLineParser.get("TFLAECHEID").c_str()); 00878 long edgeid = TplConvert<char>::_2long(myLineParser.get("KANTEID").c_str()); 00879 if (myEdges.find(edgeid)==myEdges.end()) { 00880 WRITE_ERROR("Unknown edge in TEILFLAECHENELEMENT"); 00881 return; 00882 } 00883 std::string dir = myLineParser.get("RICHTUNG"); 00884 std::string indexS = NBHelpers::normalIDRepresentation(myLineParser.get("INDEX")); 00885 int index = -1; 00886 try { 00887 index = TplConvert<char>::_2int(indexS.c_str()) - 1; 00888 } catch (NumberFormatException&) { 00889 WRITE_ERROR("An index for a TEILFLAECHENELEMENT is not numeric (id='" + toString(id) + "')."); 00890 return; 00891 } 00892 PositionVector shape; 00893 shape.push_back(myPoints[myEdges[edgeid].first]); 00894 shape.push_back(myPoints[myEdges[edgeid].second]); 00895 if (dir.length()>0&&dir[0]=='1') { 00896 shape = shape.reverse(); 00897 } 00898 if (mySubPartsAreas.find(id)==mySubPartsAreas.end()) { 00899 WRITE_ERROR("Unkown are for area part '" + myCurrentID + "'."); 00900 return; 00901 } 00902 00903 const std::vector<long> &areas = mySubPartsAreas.find(id)->second; 00904 for (std::vector<long>::const_iterator i=areas.begin(); i!=areas.end(); ++i) { 00905 NBDistrict* d = myShapeDistrictMap[*i]; 00906 if (d==0) { 00907 continue; 00908 } 00909 if (myDistrictShapes.find(d)==myDistrictShapes.end()) { 00910 myDistrictShapes[d] = PositionVector(); 00911 } 00912 if (dir.length()>0&&dir[0]=='1') { 00913 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); 00914 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); 00915 } else { 00916 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); 00917 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); 00918 } 00919 } 00920 } 00921 00922 00923 void 00924 NIImporter_VISUM::parse_Phases() { 00925 // get the id 00926 std::string Phaseid = NBHelpers::normalIDRepresentation(myLineParser.get("Nr")); 00927 std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr")); 00928 // StartTime 00929 SUMOReal StartTime = getNamedFloat("GzStart", "GRUENANF"); 00930 // EndTime 00931 SUMOReal EndTime = getNamedFloat("GzEnd", "GRUENENDE"); 00932 // add to the list 00933 (*myNIVisumTLs.find(LSAid)).second->AddPhase(Phaseid, (SUMOTime) StartTime, (SUMOTime) EndTime); 00934 } 00935 00936 00937 void NIImporter_VISUM::parse_SignalGroupsToPhases() { 00938 // get the id 00939 std::string Phaseid = NBHelpers::normalIDRepresentation(myLineParser.get("PsNr")); 00940 std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr")); 00941 std::string SGid = NBHelpers::normalIDRepresentation(myLineParser.get("SGNR")); 00942 // insert 00943 NIVisumTL::Phase* PH; 00944 NIVisumTL::SignalGroup* SG; 00945 NIVisumTL* LSA; 00946 LSA = (*myNIVisumTLs.find(LSAid)).second; 00947 SG = LSA->GetSignalGroup(SGid); 00948 PH = (*LSA->GetPhases()->find(Phaseid)).second; 00949 (*SG->GetPhases())[Phaseid] = PH; 00950 } 00951 00952 00953 void NIImporter_VISUM::parse_LanesConnections() { 00954 // get the node 00955 NBNode* node = getNamedNode("KNOTNR", "KNOT"); 00956 if (node==0) { 00957 return; 00958 } 00959 // get the from-edge 00960 NBEdge* fromEdge = getNamedEdgeContinuating("VONSTRNR", "VONSTR", node); 00961 NBEdge* toEdge = getNamedEdgeContinuating("NACHSTRNR", "NACHSTR", node); 00962 if (fromEdge==0||toEdge==0) { 00963 return; 00964 } 00965 00966 int fromLaneOffset = 0; 00967 if (!node->hasIncoming(fromEdge)) { 00968 fromLaneOffset = fromEdge->getNumLanes(); 00969 fromEdge = getReversedContinuating(fromEdge, node); 00970 } else { 00971 fromEdge = getReversedContinuating(fromEdge, node); 00972 NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(fromEdge->getID().substr(0, fromEdge->getID().find('_'))); 00973 fromLaneOffset = tmp->getNumLanes(); 00974 } 00975 00976 int toLaneOffset = 0; 00977 if (!node->hasOutgoing(toEdge)) { 00978 toLaneOffset = toEdge->getNumLanes(); 00979 toEdge = getReversedContinuating(toEdge, node); 00980 } else { 00981 NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(toEdge->getID().substr(0, toEdge->getID().find('_'))); 00982 toLaneOffset = tmp->getNumLanes(); 00983 } 00984 // get the from-lane 00985 std::string fromLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("VONFSNR")); 00986 int fromLane = -1; 00987 try { 00988 fromLane = TplConvert<char>::_2int(fromLaneS.c_str()); 00989 } catch (NumberFormatException&) { 00990 WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is not numeric (" + fromLaneS + ")."); 00991 return; 00992 } 00993 fromLane -= 1; 00994 if (fromLane<0) { 00995 WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is not positive (" + fromLaneS + ")."); 00996 return; 00997 } 00998 // get the from-lane 00999 std::string toLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("NACHFSNR")); 01000 int toLane = -1; 01001 try { 01002 toLane = TplConvert<char>::_2int(toLaneS.c_str()); 01003 } catch (NumberFormatException&) { 01004 WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is not numeric (" + toLaneS + ")."); 01005 return; 01006 } 01007 toLane -= 1; 01008 if (toLane<0) { 01009 WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is not positive (" + toLaneS + ")."); 01010 return; 01011 } 01012 // !!! the next is probably a hack 01013 if (fromLane-fromLaneOffset<0) { 01014 fromLaneOffset = 0; 01015 } else { 01016 fromLane = fromEdge->getNumLanes() - (fromLane-fromLaneOffset) - 1; 01017 } 01018 if (toLane-toLaneOffset<0) { 01019 toLaneOffset = 0; 01020 } else { 01021 toLane = toEdge->getNumLanes() - (toLane-toLaneOffset) - 1; 01022 } 01023 // 01024 if ((int) fromEdge->getNumLanes()<=fromLane) { 01025 WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is larger than the edge's lane number (" + fromLaneS + ")."); 01026 return; 01027 } 01028 if ((int) toEdge->getNumLanes()<=toLane) { 01029 WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is larger than the edge's lane number (" + toLaneS + ")."); 01030 return; 01031 } 01032 // 01033 fromEdge->addLane2LaneConnection(fromLane, toEdge, toLane, NBEdge::L2L_VALIDATED); 01034 } 01035 01036 01037 01038 01039 01040 01041 01042 01043 01044 01045 01046 01047 01048 SUMOReal 01049 NIImporter_VISUM::getWeightedFloat(const std::string& name) throw() { 01050 try { 01051 return TplConvert<char>::_2SUMOReal(myLineParser.get(name).c_str()); 01052 } catch (...) {} 01053 try { 01054 return TplConvert<char>::_2SUMOReal(myLineParser.get((name+"(IV)")).c_str()); 01055 } catch (...) {} 01056 return -1; 01057 } 01058 01059 01060 bool 01061 NIImporter_VISUM::getWeightedBool(const std::string& name) throw() { 01062 try { 01063 return TplConvert<char>::_2bool(myLineParser.get(name).c_str()); 01064 } catch (...) {} 01065 try { 01066 return TplConvert<char>::_2bool(myLineParser.get((name+"(IV)")).c_str()); 01067 } catch (...) {} 01068 return false; 01069 } 01070 01071 01072 NBNode* 01073 NIImporter_VISUM::getNamedNode(const std::string& fieldName) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01074 std::string nodeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01075 NBNode* node = myNetBuilder.getNodeCont().retrieve(nodeS); 01076 if (node==0) { 01077 WRITE_ERROR("The node '" + nodeS + "' is not known."); 01078 } 01079 return node; 01080 } 01081 01082 01083 NBNode* 01084 NIImporter_VISUM::getNamedNode(const std::string& fieldName1, const std::string& fieldName2) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01085 if (myLineParser.know(fieldName1)) { 01086 return getNamedNode(fieldName1); 01087 } else { 01088 return getNamedNode(fieldName2); 01089 } 01090 } 01091 01092 01093 NBEdge* 01094 NIImporter_VISUM::getNamedEdge(const std::string& fieldName) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01095 std::string edgeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01096 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeS); 01097 if (edge==0) { 01098 WRITE_ERROR("The edge '" + edgeS + "' is not known."); 01099 } 01100 return edge; 01101 } 01102 01103 01104 NBEdge* 01105 NIImporter_VISUM::getNamedEdge(const std::string& fieldName1, const std::string& fieldName2) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01106 if (myLineParser.know(fieldName1)) { 01107 return getNamedEdge(fieldName1); 01108 } else { 01109 return getNamedEdge(fieldName2); 01110 } 01111 } 01112 01113 01114 01115 NBEdge* 01116 NIImporter_VISUM::getReversedContinuating(NBEdge* edge, NBNode* node) throw() { 01117 std::string sid; 01118 if (edge->getID()[0]=='-') { 01119 sid = edge->getID().substr(1); 01120 } else { 01121 sid = "-" + edge->getID(); 01122 } 01123 if (sid.find('_')!=std::string::npos) { 01124 sid = sid.substr(0, sid.find('_')); 01125 } 01126 return getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), node); 01127 } 01128 01129 01130 NBEdge* 01131 NIImporter_VISUM::getNamedEdgeContinuating(NBEdge* begin, NBNode* node) throw() { 01132 if (begin==0) { 01133 return 0; 01134 } 01135 NBEdge* ret = begin; 01136 std::string edgeID = ret->getID(); 01137 // hangle forward 01138 while (ret!=0) { 01139 // ok, this is the edge we are looking for 01140 if (ret->getToNode()==node) { 01141 return ret; 01142 } 01143 const EdgeVector& nedges = ret->getToNode()->getOutgoingEdges(); 01144 if (nedges.size()!=1) { 01145 // too many edges follow 01146 ret = 0; 01147 continue; 01148 } 01149 NBEdge* next = nedges[0]; 01150 if (ret->getID().substr(0, edgeID.length())!=next->getID().substr(0, edgeID.length())) { 01151 // ok, another edge is next... 01152 ret = 0; 01153 continue; 01154 } 01155 if (next->getID().substr(next->getID().length()-node->getID().length())!=node->getID()) { 01156 ret = 0; 01157 continue; 01158 } 01159 ret = next; 01160 } 01161 01162 ret = begin; 01163 // hangle backward 01164 while (ret!=0) { 01165 // ok, this is the edge we are looking for 01166 if (ret->getFromNode()==node) { 01167 return ret; 01168 } 01169 const EdgeVector& nedges = ret->getFromNode()->getIncomingEdges(); 01170 if (nedges.size()!=1) { 01171 // too many edges follow 01172 ret = 0; 01173 continue; 01174 } 01175 NBEdge* next = nedges[0]; 01176 if (ret->getID().substr(0, edgeID.length())!=next->getID().substr(0, edgeID.length())) { 01177 // ok, another edge is next... 01178 ret = 0; 01179 continue; 01180 } 01181 if (next->getID().substr(next->getID().length()-node->getID().length())!=node->getID()) { 01182 ret = 0; 01183 continue; 01184 } 01185 ret = next; 01186 } 01187 return 0; 01188 } 01189 01190 01191 NBEdge* 01192 NIImporter_VISUM::getNamedEdgeContinuating(const std::string& fieldName, NBNode* node) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01193 std::string edgeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01194 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeS); 01195 if (edge==0) { 01196 WRITE_ERROR("The edge '" + edgeS + "' is not known."); 01197 } 01198 return getNamedEdgeContinuating(edge, node); 01199 } 01200 01201 01202 NBEdge* 01203 NIImporter_VISUM::getNamedEdgeContinuating(const std::string& fieldName1, const std::string& fieldName2, 01204 NBNode* node) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01205 if (myLineParser.know(fieldName1)) { 01206 return getNamedEdgeContinuating(fieldName1, node); 01207 } else { 01208 return getNamedEdgeContinuating(fieldName2, node); 01209 } 01210 } 01211 01212 01213 NBEdge* 01214 NIImporter_VISUM::getEdge(NBNode* FromNode, NBNode* ToNode) throw() { 01215 EdgeVector::const_iterator i; 01216 for (i = FromNode->getOutgoingEdges().begin(); i != FromNode->getOutgoingEdges().end(); i++) { 01217 if (ToNode == (*i)->getToNode()) { 01218 return(*i); 01219 } 01220 } 01222 return 0; 01223 } 01224 01225 01226 SUMOReal 01227 NIImporter_VISUM::getNamedFloat(const std::string& fieldName) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01228 std::string valS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01229 return TplConvert<char>::_2SUMOReal(valS.c_str()); 01230 } 01231 01232 01233 SUMOReal 01234 NIImporter_VISUM::getNamedFloat(const std::string& fieldName, SUMOReal defaultValue) throw() { 01235 try { 01236 std::string valS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01237 return TplConvert<char>::_2SUMOReal(valS.c_str()); 01238 } catch (...) { 01239 return defaultValue; 01240 } 01241 } 01242 01243 01244 SUMOReal 01245 NIImporter_VISUM::getNamedFloat(const std::string& fieldName1, const std::string& fieldName2) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01246 if (myLineParser.know(fieldName1)) { 01247 return getNamedFloat(fieldName1); 01248 } else { 01249 return getNamedFloat(fieldName2); 01250 } 01251 } 01252 01253 01254 SUMOReal 01255 NIImporter_VISUM::getNamedFloat(const std::string& fieldName1, const std::string& fieldName2, 01256 SUMOReal defaultValue) throw() { 01257 if (myLineParser.know(fieldName1)) { 01258 return getNamedFloat(fieldName1, defaultValue); 01259 } else { 01260 return getNamedFloat(fieldName2, defaultValue); 01261 } 01262 } 01263 01264 01265 std::string 01266 NIImporter_VISUM::getNamedString(const std::string& fieldName) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01267 return NBHelpers::normalIDRepresentation(myLineParser.get(fieldName)); 01268 } 01269 01270 01271 std::string 01272 NIImporter_VISUM::getNamedString(const std::string& fieldName1, 01273 const std::string& fieldName2) throw(OutOfBoundsException, NumberFormatException, UnknownElement) { 01274 if (myLineParser.know(fieldName1)) { 01275 return getNamedString(fieldName1); 01276 } else { 01277 return getNamedString(fieldName2); 01278 } 01279 } 01280 01281 01282 01283 01284 01285 01286 NBNode* 01287 NIImporter_VISUM::buildDistrictNode(const std::string& id, NBNode* dest, 01288 bool isSource) throw() { 01289 // get the district 01290 NBDistrict* dist = myNetBuilder.getDistrictCont().retrieve(id); 01291 if (dist==0) { 01292 return 0; 01293 } 01294 // build the id 01295 std::string nid; 01296 nid = id + "-" + dest->getID(); 01297 if (!isSource) { 01298 nid = "-" + nid; 01299 } 01300 // insert the node 01301 if (!myNetBuilder.getNodeCont().insert(nid, dist->getPosition())) { 01302 WRITE_ERROR("Could not build connector node '" + nid + "'."); 01303 } 01304 // return the node 01305 return myNetBuilder.getNodeCont().retrieve(nid); 01306 } 01307 01308 01309 bool 01310 NIImporter_VISUM::checkNodes(NBNode* from, NBNode* to) throw() { 01311 if (from==0) { 01312 WRITE_ERROR(" The from-node was not found within the net"); 01313 } 01314 if (to==0) { 01315 WRITE_ERROR(" The to-node was not found within the net"); 01316 } 01317 if (from==to) { 01318 WRITE_ERROR(" Both nodes are the same"); 01319 } 01320 return from!=0&&to!=0&&from!=to; 01321 } 01322 01323 01324 /****************************************************************************/ 01325