NIImporter_VISUM.cpp

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

Generated on Wed May 5 00:06:34 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6