SUMO - Simulation of Urban MObility
NIImporter_VISUM.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines