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 
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines