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