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