NIXMLEdgesHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for network edges stored in XML
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 <iostream>
00032 #include <map>
00033 #include <xercesc/sax/HandlerBase.hpp>
00034 #include <xercesc/sax/AttributeList.hpp>
00035 #include <xercesc/sax/SAXParseException.hpp>
00036 #include <xercesc/sax/SAXException.hpp>
00037 #include "NIXMLEdgesHandler.h"
00038 #include <cmath>
00039 #include <utils/xml/SUMOSAXHandler.h>
00040 #include <netbuild/NBNodeCont.h>
00041 #include <netbuild/NBTypeCont.h>
00042 #include <utils/xml/SUMOXMLDefinitions.h>
00043 #include <utils/common/MsgHandler.h>
00044 #include <utils/common/TplConvert.h>
00045 #include <utils/common/StringTokenizer.h>
00046 #include <utils/geom/GeomConvHelper.h>
00047 #include <utils/common/ToString.h>
00048 #include <utils/options/OptionsCont.h>
00049 #include <utils/geom/GeoConvHelper.h>
00050 
00051 #ifdef CHECK_MEMORY_LEAKS
00052 #include <foreign/nvwa/debug_new.h>
00053 #endif // CHECK_MEMORY_LEAKS
00054 
00055 
00056 // ===========================================================================
00057 // used namespaces
00058 // ===========================================================================
00059 using namespace std;
00060 
00061 const SUMOReal SUMOXML_INVALID_POSITION = -999999.;
00062 
00063 // ===========================================================================
00064 // method definitions
00065 // ===========================================================================
00066 NIXMLEdgesHandler::NIXMLEdgesHandler(NBNodeCont &nc,
00067                                      NBEdgeCont &ec,
00068                                      NBTypeCont &tc,
00069                                      NBDistrictCont &dc,
00070                                      OptionsCont &options) throw()
00071         : SUMOSAXHandler("xml-edges - file"),
00072         myOptions(options),
00073         myNodeCont(nc), myEdgeCont(ec), myTypeCont(tc), myDistrictCont(dc),
00074         myCurrentEdge(0),
00075         myHaveReportedAboutFunctionDeprecation(false) {}
00076 
00077 
00078 NIXMLEdgesHandler::~NIXMLEdgesHandler() throw() {}
00079 
00080 
00081 void
00082 NIXMLEdgesHandler::myStartElement(SumoXMLTag element,
00083                                   const SUMOSAXAttributes &attrs) throw(ProcessError) {
00084     if (element==SUMO_TAG_EDGE) {
00085         myIsUpdate = false;
00086         bool ok = true;
00087         // initialise the edge
00088         myCurrentEdge = 0;
00089         mySplits.clear();
00090         // get the id, report an error if not given or empty...
00091         if (!attrs.setIDFromAttributes("edge", myCurrentID)) {
00092             return;
00093         }
00094         myCurrentEdge = myEdgeCont.retrieve(myCurrentID);
00095         // check deprecated (unused) attributes
00096         if (!myHaveReportedAboutFunctionDeprecation&&attrs.hasAttribute(SUMO_ATTR_FUNCTION)) {
00097             MsgHandler::getWarningInstance()->inform("While parsing edge '" + myCurrentID + "': 'function' is deprecated.\n All occurences are ignored.");
00098             myHaveReportedAboutFunctionDeprecation = true;
00099         }
00100         // use default values, first
00101         myCurrentSpeed = myTypeCont.getDefaultSpeed();
00102         myCurrentPriority = myTypeCont.getDefaultPriority();
00103         myCurrentLaneNo = myTypeCont.getDefaultNoLanes();
00104         // use values from the edge to overwrite if existing, then
00105         if (myCurrentEdge!=0) {
00106             myIsUpdate = true;
00107             if (!myHaveReportedAboutOverwriting) {
00108                 MsgHandler::getMessageInstance()->inform("Duplicate edge id occured ('" + myCurrentID + "'); assuming overwriting is wished.");
00109                 myHaveReportedAboutOverwriting = true;
00110             }
00111             myCurrentSpeed = myCurrentEdge->getSpeed();
00112             myCurrentPriority = myCurrentEdge->getPriority();
00113             myCurrentLaneNo = myCurrentEdge->getNoLanes();
00114             myCurrentType = myCurrentEdge->getTypeID();
00115         }
00116         // check whether a type's values shall be used
00117         myCurrentType = "";
00118         if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
00119             myCurrentType = attrs.getStringReporting(SUMO_ATTR_TYPE, "edge", myCurrentID.c_str(), ok);
00120             if (!ok) {
00121                 return;
00122             }
00123             if (!myTypeCont.knows(myCurrentType)) {
00124                 MsgHandler::getErrorInstance()->inform("Type '" + myCurrentType + "' used by edge '" + myCurrentID + "' was not defined.");
00125                 return;
00126             }
00127             myCurrentSpeed = myTypeCont.getSpeed(myCurrentType);
00128             myCurrentPriority = myTypeCont.getPriority(myCurrentType);
00129             myCurrentLaneNo = myTypeCont.getNoLanes(myCurrentType);
00130         }
00131         // speed, priority and the number of lanes have now default values;
00132         // try to read the real values from the file
00133         if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
00134             myCurrentSpeed = attrs.getSUMORealReporting(SUMO_ATTR_SPEED, "edge", myCurrentID.c_str(), ok);
00135         }
00136         if (myOptions.getBool("speed-in-kmh")) {
00137             myCurrentSpeed = myCurrentSpeed / (SUMOReal) 3.6;
00138         }
00139         // try to get the number of lanes
00140         if (attrs.hasAttribute(SUMO_ATTR_NOLANES)) {
00141             myCurrentLaneNo = attrs.getIntReporting(SUMO_ATTR_NOLANES, "edge", myCurrentID.c_str(), ok);
00142         }
00143         // try to get the priority
00144         if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
00145             myCurrentPriority = attrs.getIntReporting(SUMO_ATTR_PRIORITY, "edge", myCurrentID.c_str(), ok);
00146         }
00147 
00148         // try to get the shape
00149         myShape = tryGetShape(attrs);
00150         // and how to spread the lanes
00151         if (attrs.getOptStringReporting(SUMO_ATTR_SPREADFUNC, "edge", myCurrentID.c_str(), ok, "")=="center") {
00152             myLanesSpread = NBEdge::LANESPREAD_CENTER;
00153         } else {
00154             myLanesSpread = NBEdge::LANESPREAD_RIGHT;
00155         }
00156         // try to set the nodes
00157         if (!setNodes(attrs)) {
00158             // return if this failed
00159             return;
00160         }
00161         // get the length or compute it
00162         if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
00163             myLength = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "edge", myCurrentID.c_str(), ok);
00164         } else {
00165             myLength = 0;
00166         }
00168         if (!ok) {
00169             return;
00170         }
00171         // check whether a previously defined edge shall be overwritten
00172         if (myCurrentEdge!=0) {
00173             myCurrentEdge->reinit(myFromNode, myToNode, myCurrentType, myCurrentSpeed,
00174                                   myCurrentLaneNo, myCurrentPriority, myShape,
00175                                   myLanesSpread);
00176         } else {
00177             // the edge must be allocated in dependence to whether a shape is given
00178             if (myShape.size()==0) {
00179                 myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed,
00180                                            myCurrentLaneNo, myCurrentPriority, myLanesSpread);
00181             } else {
00182                 myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed,
00183                                            myCurrentLaneNo, myCurrentPriority, myShape,
00184                                            myLanesSpread, OptionsCont::getOptions().getBool("xml.keep-shape"));
00185             }
00186             myCurrentEdge->setLoadedLength(myLength);
00187         }
00188     }
00189     if (element==SUMO_TAG_LANE) {
00190         if (myCurrentEdge==0) {
00191             if (!OptionsCont::getOptions().isInStringVector("remove-edges", myCurrentID)) {
00192                 MsgHandler::getErrorInstance()->inform("Additional lane information could not been set - the edge with id '" + myCurrentID + "' is not known.");
00193             }
00194             return;
00195         }
00196         bool ok = true;
00197         int lane = attrs.getIntReporting(SUMO_ATTR_ID, "lane", 0, ok);
00198         std::vector<std::string> disallowed, allowed, preferred;
00199         SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, "lane", 0, ok, ""), disallowed);
00200         SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_ALLOW, "lane", 0, ok, ""), allowed);
00201         SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_PREFER, "lane", 0, ok, ""), preferred);
00202         if (!ok) {
00203             return;
00204         }
00205         if (lane<0) {
00206             MsgHandler::getErrorInstance()->inform("Missing lane-id in lane definition (edge '" + myCurrentID + "').");
00207             return;
00208         }
00209         // check whether this lane exists
00210         if (lane>=(int) myCurrentEdge->getNoLanes()) {
00211             MsgHandler::getErrorInstance()->inform("Lane-id is larger than number of lanes (edge '" + myCurrentID + "').");
00212             return;
00213         }
00214         // set information about allowed / disallowed vehicle classes
00215         for (std::vector<std::string>::iterator i=disallowed.begin(); i!=disallowed.end(); ++i) {
00216             myCurrentEdge->disallowVehicleClass(lane, getVehicleClassID(*i));
00217         }
00218         for (std::vector<std::string>::iterator i=allowed.begin(); i!=allowed.end(); ++i) {
00219             myCurrentEdge->allowVehicleClass(lane, getVehicleClassID(*i));
00220         }
00221         for (std::vector<std::string>::iterator i=preferred.begin(); i!=preferred.end(); ++i) {
00222             myCurrentEdge->preferVehicleClass(lane, getVehicleClassID(*i));
00223         }
00224 
00225         // set information about later beginning lanes
00226         if (attrs.hasAttribute(SUMO_ATTR_FORCE_LENGTH)) {
00227             bool ok = true;
00228             int forcedLength = attrs.getIntReporting(SUMO_ATTR_FORCE_LENGTH, "lane", myCurrentID.c_str(), ok); // !!! edge id
00229             if (ok) {
00230                 int nameid = forcedLength;
00231                 forcedLength = (int)(myCurrentEdge->getGeometry().length() - forcedLength);
00232                 std::vector<Split>::iterator i;
00233                 i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder((SUMOReal) forcedLength));
00234                 if (i==mySplits.end()) {
00235                     Split e;
00236                     e.pos = (SUMOReal) forcedLength;
00237                     e.nameid = nameid;
00238                     for (unsigned int j=0; j<myCurrentEdge->getNoLanes(); j++) {
00239                         e.lanes.push_back(j);
00240                     }
00241                     mySplits.push_back(e);
00242                 }
00243                 i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder((SUMOReal) forcedLength));
00244                 std::vector<int>::iterator k = find((*i).lanes.begin(), (*i).lanes.end(), lane);
00245                 if (k!=(*i).lanes.end()) {
00246                     (*i).lanes.erase(k);
00247                 }
00248             }
00249         }
00250     }
00251     if (element==SUMO_TAG_SPLIT) {
00252         bool ok = true;
00253         Split e;
00254         e.pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "split", 0, ok);
00255         std::vector<Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
00256         if (i!=mySplits.end()) {
00257             MsgHandler::getErrorInstance()->inform("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + ".");
00258             return;
00259         }
00260         if (e.pos<0) {
00261             e.pos = myCurrentEdge->getGeometry().length() - e.pos;
00262         }
00263         e.nameid = e.pos;
00264         if (ok) {
00265             if (myCurrentEdge==0) {
00266                 if (!OptionsCont::getOptions().isInStringVector("remove-edges", myCurrentID)) {
00267                     MsgHandler::getErrorInstance()->inform("Additional lane information could not been set - the edge with id '" + myCurrentID + "' is not known.");
00268                 }
00269                 return;
00270             }
00271             if (e.pos<0) {
00272                 e.pos = myCurrentEdge->getGeometry().length() + e.pos;
00273             }
00274             std::vector<std::string> lanes;
00275             SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_LANES, "split", 0, ok, ""), lanes);
00276             for (std::vector<std::string>::iterator i=lanes.begin(); i!=lanes.end(); ++i) {
00277                 try {
00278                     int lane = TplConvert<char>::_2int((*i).c_str());
00279                     e.lanes.push_back(lane);
00280                 } catch (NumberFormatException &) {
00281                     MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "').");
00282                 } catch (EmptyData &) {
00283                     MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "').");
00284                 }
00285             }
00286             if (e.lanes.size()==0) {
00287                 MsgHandler::getErrorInstance()->inform("Missing lane information in split of edge '" + myCurrentID + "'.");
00288             } else {
00289                 mySplits.push_back(e);
00290             }
00291         }
00292     }
00293 }
00294 
00295 
00296 bool
00297 NIXMLEdgesHandler::setNodes(const SUMOSAXAttributes &attrs) throw() {
00298     // the names and the coordinates of the beginning and the end node
00299     // may be found, try
00300     bool ok = true;
00301     std::string begNodeID = myIsUpdate ? myCurrentEdge->getFromNode()->getID() : "";
00302     std::string endNodeID = myIsUpdate ? myCurrentEdge->getToNode()->getID() : "";
00303     begNodeID = attrs.hasAttribute(SUMO_ATTR_FROMNODE) ? attrs.getStringReporting(SUMO_ATTR_FROMNODE, "edge", 0, ok) : begNodeID;
00304     endNodeID = attrs.hasAttribute(SUMO_ATTR_TONODE) ? attrs.getStringReporting(SUMO_ATTR_TONODE, "edge", 0, ok) : endNodeID;
00305     if (!ok) {
00306         return false;
00307     }
00308     // or their positions !!! deprecated
00309     SUMOReal begNodeXPos = tryGetPosition(attrs, SUMO_ATTR_XFROM, "XFrom");
00310     SUMOReal begNodeYPos = tryGetPosition(attrs, SUMO_ATTR_YFROM, "YFrom");
00311     SUMOReal endNodeXPos = tryGetPosition(attrs, SUMO_ATTR_XTO, "XTo");
00312     SUMOReal endNodeYPos = tryGetPosition(attrs, SUMO_ATTR_YTO, "YTo");
00313     if (begNodeXPos!=SUMOXML_INVALID_POSITION&&begNodeYPos!=SUMOXML_INVALID_POSITION) {
00314         Position2D pos(begNodeXPos, begNodeYPos);
00315         GeoConvHelper::x2cartesian(pos);
00316         begNodeXPos = pos.x();
00317         begNodeYPos = pos.y();
00318     }
00319     if (endNodeXPos!=SUMOXML_INVALID_POSITION&&endNodeYPos!=SUMOXML_INVALID_POSITION) {
00320         Position2D pos(endNodeXPos, endNodeYPos);
00321         GeoConvHelper::x2cartesian(pos);
00322         endNodeXPos = pos.x();
00323         endNodeYPos = pos.y();
00324     }
00325     // check the obtained values for nodes
00326     myFromNode = insertNodeChecking(Position2D(begNodeXPos, begNodeYPos), begNodeID, "from");
00327     myToNode = insertNodeChecking(Position2D(endNodeXPos, endNodeYPos), endNodeID, "to");
00328     return myFromNode!=0&&myToNode!=0;
00329 }
00330 
00331 
00332 SUMOReal
00333 NIXMLEdgesHandler::tryGetPosition(const SUMOSAXAttributes &attrs, SumoXMLAttr attrID,
00334                                   const std::string &attrName) {
00335     bool ok = true;
00336     return attrs.getOptSUMORealReporting(attrID, "edge", myCurrentID.c_str(), ok, SUMOXML_INVALID_POSITION);
00337 }
00338 
00339 
00340 NBNode *
00341 NIXMLEdgesHandler::insertNodeChecking(const Position2D &pos,
00342                                       const std::string &name, const std::string &dir) {
00343     NBNode *ret = 0;
00344     if (name=="" && (pos.x()==SUMOXML_INVALID_POSITION || pos.y()==SUMOXML_INVALID_POSITION)) {
00345         MsgHandler::getErrorInstance()->inform("Neither the name nor the position of the " + dir + "-node is given for edge '" + myCurrentID + "'.");
00346         return ret;
00347     }
00348     if (name!="") {
00349         if (pos.x()!=SUMOXML_INVALID_POSITION && pos.y()!=SUMOXML_INVALID_POSITION) {
00350             // the node is named and it has a position given
00351             if (!myNodeCont.insert(name, pos)) {
00352                 MsgHandler::getErrorInstance()->inform("Position of " + dir + "-node '" + name + "' mismatches previous positions.");
00353                 return 0;
00354             }
00355         }
00356         // the node is given by its name
00357         ret = myNodeCont.retrieve(name);
00358         if (ret==0) {
00359             MsgHandler::getErrorInstance()->inform("Edge's '" + myCurrentID + "' " + dir + "-node '" + name + "' is not known.");
00360         }
00361     } else {
00362         ret = myNodeCont.retrieve(pos);
00363         if (ret==0) {
00364             ret = new NBNode(myNodeCont.getFreeID(), pos);
00365             if (!myNodeCont.insert(ret)) {
00366                 MsgHandler::getErrorInstance()->inform("Could not insert " + dir + "-node at position " + toString(pos) + ".");
00367                 delete ret;
00368                 return 0;
00369             }
00370         }
00371     }
00372     return ret;
00373 }
00374 
00375 
00376 Position2DVector
00377 NIXMLEdgesHandler::tryGetShape(const SUMOSAXAttributes &attrs) throw() {
00378     if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00379         return Position2DVector();
00380     }
00381     // try to build shape
00382     bool ok = true;
00383     std::string shpdef = attrs.getOptStringReporting(SUMO_ATTR_SHAPE, "edge", 0, ok, "");
00384     if (shpdef=="") {
00385         return Position2DVector();
00386     }
00387     Position2DVector shape1 = GeomConvHelper::parseShapeReporting(shpdef, "edge", 0, ok, true);
00388     Position2DVector shape;
00389     for (int i=0; i<(int) shape1.size(); ++i) {
00390         Position2D pos(shape1[i]);
00391         if (!GeoConvHelper::x2cartesian(pos)) {
00392             MsgHandler::getErrorInstance()->inform("Unable to project coordinates for edge '" + myCurrentID + "'.");
00393         }
00394         shape.push_back(pos);
00395     }
00396     return shape;
00397 }
00398 
00399 
00400 void
00401 NIXMLEdgesHandler::parseSplitLanes(const std::string &val) throw(ProcessError) {
00402     if (mySplits.size()!=0) {
00403         Split &e = mySplits.back();
00404         std::vector<std::string> lanes;
00405         SUMOSAXAttributes::parseStringVector(val, lanes);
00406         for (std::vector<std::string>::iterator i=lanes.begin(); i!=lanes.end(); ++i) {
00407             try {
00408                 int lane = TplConvert<char>::_2int((*i).c_str());
00409                 e.lanes.push_back(lane);
00410             } catch (NumberFormatException &) {
00411                 MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "').");
00412             } catch (EmptyData &) {
00413                 MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "').");
00414             }
00415         }
00416     }
00417 }
00418 
00419 
00420 void
00421 NIXMLEdgesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00422     if (element==SUMO_TAG_EDGE && myCurrentEdge!=0) {
00423         if (!myIsUpdate) {
00424             try {
00425                 if (!myEdgeCont.insert(myCurrentEdge)) {
00426                     MsgHandler::getErrorInstance()->inform("Duplicate edge occured. ID='" + myCurrentID + "'");
00427                     delete myCurrentEdge;
00428                 }
00429             } catch (InvalidArgument &e) {
00430                 MsgHandler::getErrorInstance()->inform(e.what());
00431                 throw;
00432             } catch (...) {
00433                 MsgHandler::getErrorInstance()->inform("An important information is missing in edge '" + myCurrentID + "'.");
00434             }
00435         }
00436         if (mySplits.size()!=0) {
00437             std::vector<Split>::iterator i, i2;
00438             sort(mySplits.begin(), mySplits.end(), split_sorter());
00439             NBEdge *e = myCurrentEdge;
00440             unsigned int noLanesMax = e->getNoLanes();
00441             // compute the node positions and sort the lanes
00442             for (i=mySplits.begin(); i!=mySplits.end(); ++i) {
00443                 (*i).gpos = e->getGeometry().positionAtLengthPosition((*i).pos);
00444                 sort((*i).lanes.begin(), (*i).lanes.end());
00445                 noLanesMax = MAX2(noLanesMax, (unsigned int)(*i).lanes.size());
00446             }
00447             // split the edge
00448             std::vector<int> currLanes;
00449             for (unsigned int l=0; l<noLanesMax; ++l) {
00450                 currLanes.push_back(l);
00451             }
00452             std::string edgeid = e->getID();
00453             SUMOReal seen = 0;
00454             for (i=mySplits.begin(); i!=mySplits.end(); ++i) {
00455                 const Split &exp = *i;
00456                 assert(exp.lanes.size()!=0);
00457                 if (exp.pos>0 && e->getGeometry().length()+seen>exp.pos) {
00458                     std::string nid = edgeid + "." +  toString(exp.nameid);
00459                     NBNode *rn = new NBNode(nid, exp.gpos);
00460                     if (myNodeCont.insert(rn)) {
00461                         //  split the edge
00462                         std::string nid = myCurrentID + "." +  toString(exp.nameid);
00463                         std::string pid = e->getID();
00464                         myEdgeCont.splitAt(myDistrictCont, e, exp.pos-seen, rn,
00465                                            pid, nid, e->getNoLanes(), (unsigned int) exp.lanes.size());
00466                         seen = exp.pos;
00467                         std::vector<int> newLanes = exp.lanes;
00468                         NBEdge *pe = myEdgeCont.retrieve(pid);
00469                         NBEdge *ne = myEdgeCont.retrieve(nid);
00470                         // reconnect lanes
00471                         pe->invalidateConnections(true);
00472                         //  new on right
00473                         unsigned int rightMostP = currLanes[0];
00474                         unsigned int rightMostN = newLanes[0];
00475                         for (int l=0; l<(int) rightMostP-(int) rightMostN; ++l) {
00476                             pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
00477                         }
00478                         //  new on left
00479                         unsigned int leftMostP = currLanes.back();
00480                         unsigned int leftMostN = newLanes.back();
00481                         for (int l=0; l<(int) leftMostN-(int) leftMostP; ++l) {
00482                             pe->addLane2LaneConnection(pe->getNoLanes()-1, ne, leftMostN-l, NBEdge::L2L_VALIDATED, true);
00483                         }
00484                         //  all other connected
00485                         for (unsigned int l=0; l<noLanesMax; ++l) {
00486                             if (find(currLanes.begin(), currLanes.end(), l)==currLanes.end()) {
00487                                 continue;
00488                             }
00489                             if (find(newLanes.begin(), newLanes.end(), l)==newLanes.end()) {
00490                                 continue;
00491                             }
00492                             pe->addLane2LaneConnection(l-rightMostP, ne, l-rightMostN, NBEdge::L2L_VALIDATED, true);
00493                         }
00494                         // move to next
00495                         e = ne;
00496                         currLanes = newLanes;
00497                     } else {
00498                         MsgHandler::getWarningInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "').");
00499                     }
00500                 }  else if (exp.pos==0) {
00501                     e->decLaneNo(e->getNoLanes()-exp.lanes.size());
00502                     currLanes = exp.lanes;
00503                 } else {
00504                     MsgHandler::getWarningInstance()->inform("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "').");
00505                 }
00506             }
00507             // patch lane offsets
00508             e = myEdgeCont.retrieve(edgeid);
00509             i = mySplits.begin();
00510             if ((*i).pos!=0) {
00511                 e = e->getToNode()->getOutgoingEdges()[0];
00512             }
00513             for (; i!=mySplits.end(); ++i) {
00514                 unsigned int maxLeft = (*i).lanes.back();
00515                 if (maxLeft<noLanesMax) {
00516                     Position2DVector g = e->getGeometry();
00517                     g.move2side(SUMO_const_laneWidthAndOffset*(noLanesMax-1-maxLeft));
00518                     e->setGeometry(g);
00519                 }
00520                 if (e->getToNode()->getOutgoingEdges().size()!=0) {
00521                     e = e->getToNode()->getOutgoingEdges()[0];
00522                 }
00523             }
00524         }
00525     }
00526 }
00527 
00528 
00529 
00530 /****************************************************************************/
00531 

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