SUMO - Simulation of Urban MObility

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