NIXMLConnectionsHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for edge connections 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 <xercesc/sax/HandlerBase.hpp>
00033 #include <xercesc/sax/AttributeList.hpp>
00034 #include <xercesc/sax/SAXParseException.hpp>
00035 #include <xercesc/sax/SAXException.hpp>
00036 #include "NIXMLConnectionsHandler.h"
00037 #include <netbuild/NBEdge.h>
00038 #include <netbuild/NBEdgeCont.h>
00039 #include <netbuild/NBNode.h>
00040 #include <utils/common/StringTokenizer.h>
00041 #include <utils/xml/SUMOSAXHandler.h>
00042 #include <utils/xml/SUMOXMLDefinitions.h>
00043 #include <utils/common/ToString.h>
00044 #include <utils/common/TplConvert.h>
00045 #include <utils/common/TplConvertSec.h>
00046 #include <utils/common/UtilExceptions.h>
00047 #include <utils/common/MsgHandler.h>
00048 
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052 
00053 
00054 // ===========================================================================
00055 // method definitions
00056 // ===========================================================================
00057 NIXMLConnectionsHandler::NIXMLConnectionsHandler(NBEdgeCont &ec) throw()
00058         : SUMOSAXHandler("xml-connection-description"), myEdgeCont(ec),
00059         myHaveReportedAboutFunctionDeprecation(false) {}
00060 
00061 
00062 NIXMLConnectionsHandler::~NIXMLConnectionsHandler() throw() {}
00063 
00064 
00065 void
00066 NIXMLConnectionsHandler::myStartElement(SumoXMLTag element,
00067                                         const SUMOSAXAttributes &attrs) throw(ProcessError) {
00068     if (element==SUMO_TAG_RESET) {
00069         bool ok = true;
00070         std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, "reset", 0, ok);
00071         std::string to = attrs.getStringReporting(SUMO_ATTR_TO, "reset", 0, ok);
00072         if (!ok) {
00073             return;
00074         }
00075         NBEdge *fromEdge = myEdgeCont.retrieve(from);
00076         NBEdge *toEdge = myEdgeCont.retrieve(to);
00077         if (fromEdge==0) {
00078             MsgHandler::getErrorInstance()->inform("The connection-source edge '" + from + "' to reset is not known.");
00079             return;
00080         }
00081         if (toEdge==0) {
00082             MsgHandler::getErrorInstance()->inform("The connection-destination edge '" + to + "' to reset is not known.");
00083             return;
00084         }
00085         fromEdge->removeFromConnections(toEdge);
00086     }
00087 
00088     if (element==SUMO_TAG_CONNECTION) {
00089         bool ok = true;
00090         std::string from = attrs.getOptStringReporting(SUMO_ATTR_FROM, "connection", 0, ok, "");
00091         std::string to = attrs.getOptStringReporting(SUMO_ATTR_TO, "connection", 0, ok, "");
00092         std::string laneConn = attrs.getOptStringReporting(SUMO_ATTR_LANE, "connection", 0, ok, "");
00093         if (!ok) {
00094             return;
00095         }
00096         if (from.length()==0) {
00097             MsgHandler::getErrorInstance()->inform("A from-edge is not specified within one of the connections");
00098             return;
00099         }
00100         // extract edges
00101         NBEdge *fromEdge = myEdgeCont.retrieve(from);
00102         NBEdge *toEdge = to.length()!=0 ? myEdgeCont.retrieve(to) : 0;
00103         // check whether they are valid
00104         if (fromEdge==0) {
00105             MsgHandler::getErrorInstance()->inform("The connection-source edge '" + from + "' is not known.");
00106             return;
00107         }
00108         if (toEdge==0 && to.length()!=0) {
00109             MsgHandler::getErrorInstance()->inform("The connection-destination edge '" + to + "' is not known.");
00110             return;
00111         }
00112         // parse optional lane information
00113         if (!myHaveReportedAboutFunctionDeprecation&&attrs.hasAttribute(SUMO_ATTR_TYPE)) {
00114             MsgHandler::getWarningInstance()->inform("While parsing connections: 'type' is deprecated.\n All occurences are ignored.");
00115             myHaveReportedAboutFunctionDeprecation = true;
00116         }
00117         if (laneConn=="") {
00118             fromEdge->addEdge2EdgeConnection(toEdge);
00119         } else {
00120             parseLaneBound(attrs, fromEdge, toEdge);
00121         }
00122     }
00123     if (element==SUMO_TAG_PROHIBITION) {
00124         bool ok = true;
00125         std::string prohibitor = attrs.getOptStringReporting(SUMO_ATTR_PROHIBITOR, "prohibition", 0, ok, "");
00126         std::string prohibited = attrs.getOptStringReporting(SUMO_ATTR_PROHIBITED, "prohibition", 0, ok, "");
00127         if (!ok) {
00128             return;
00129         }
00130         NBConnection prohibitorC = parseConnection("prohibitor", prohibitor);
00131         NBConnection prohibitedC = parseConnection("prohibited", prohibited);
00132         if (prohibitorC.getFrom()==0||prohibitedC.getFrom()==0) {
00133             // something failed
00134             return;
00135         }
00136         NBNode *n = prohibitorC.getFrom()->getToNode();
00137         n->addSortedLinkFoes(prohibitorC, prohibitedC);
00138     }
00139 }
00140 
00141 
00142 NBConnection
00143 NIXMLConnectionsHandler::parseConnection(const std::string &defRole,
00144         const std::string &def) throw() {
00145     // split from/to
00146     size_t div = def.find("->");
00147     if (div==std::string::npos) {
00148         MsgHandler::getErrorInstance()->inform("Missing connection divider in " + defRole + " '" + def + "'");
00149         return NBConnection(0, 0);
00150     }
00151     std::string fromDef = def.substr(0, div);
00152     std::string toDef = def.substr(div+2);
00153 
00154     // retrieve the edges
00155     // check whether the definition includes a lane information (do not process it)
00156     if (fromDef.find('_')!=std::string::npos) {
00157         fromDef = fromDef.substr(0, fromDef.find('_'));
00158     }
00159     if (toDef.find('_')!=std::string::npos) {
00160         toDef = toDef.substr(0, toDef.find('_'));
00161     }
00162     // retrieve them now
00163     NBEdge *fromE = myEdgeCont.retrieve(fromDef);
00164     NBEdge *toE = myEdgeCont.retrieve(toDef);
00165     // check
00166     if (fromE==0) {
00167         MsgHandler::getErrorInstance()->inform("Could not find edge '" + fromDef + "' in " + defRole + " '" + def + "'");
00168         return NBConnection(0, 0);
00169     }
00170     if (toE==0) {
00171         MsgHandler::getErrorInstance()->inform("Could not find edge '" + toDef + "' in " + defRole + " '" + def + "'");
00172         return NBConnection(0, 0);
00173     }
00174     return NBConnection(fromE, toE);
00175 }
00176 
00177 
00178 void
00179 NIXMLConnectionsHandler::parseLaneBound(const SUMOSAXAttributes &attrs,
00180                                         NBEdge *from,
00181                                         NBEdge *to) throw() {
00182     if (to==0) {
00183         // do nothing if it's a dead end
00184         return;
00185     }
00186     bool ok = true;
00187     std::string laneConn = attrs.getOptStringReporting(SUMO_ATTR_LANE, "connection", 0, ok, "");
00188     // split the information
00189     StringTokenizer st(laneConn, ':');
00190     if (st.size()!=2) {
00191         MsgHandler::getErrorInstance()->inform("Invalid lane to lane connection from '" +
00192                                                from->getID() + "' to '" + to->getID() + "'.");
00193         return;
00194     }
00195     bool mayDefinitelyPass = attrs.getOptBoolReporting(SUMO_ATTR_PASS, "connection", 0, ok, false);
00196     if (!ok) {
00197         return;
00198     }
00199     // get the begin and the end lane
00200     int fromLane;
00201     int toLane;
00202     try {
00203         fromLane = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
00204         toLane = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
00205         if (fromLane<0 || fromLane>=from->getNoLanes() || toLane<0 || toLane>=to->getNoLanes()) {
00206             MsgHandler::getErrorInstance()->inform("False lane index in connection from '" + from->getID() + "' to '" + to->getID() + "'.");
00207             return;
00208         }
00209         if (from->hasConnectionTo(to, toLane)) {
00210             WRITE_WARNING("Target lane '" + to->getID() + "_" + toString(toLane) + "' is already connected from '" + from->getID() + "'.");
00211         }
00212         if (!from->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, true, mayDefinitelyPass)) {
00213             NBEdge *nFrom = from;
00214             bool toNext = true;
00215             do {
00216                 if (nFrom->getToNode()->getOutgoingEdges().size()!=1) {
00217                     toNext = false;
00218                     break;
00219                 }
00220                 NBEdge *t = nFrom->getToNode()->getOutgoingEdges()[0];
00221                 if (t->getID().substr(0, t->getID().find('/'))!=nFrom->getID().substr(0, nFrom->getID().find('/'))) {
00222                     toNext = false;
00223                     break;
00224                 }
00225                 if (toNext) {
00226                     nFrom = t;
00227                 }
00228             } while (toNext);
00229             if (nFrom==0||!nFrom->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, false, mayDefinitelyPass)) {
00230                 WRITE_WARNING("Could not set loaded connection from '" + from->getID() + "_" + toString<int>(fromLane) + "' to '" + to->getID() + "_" + toString<int>(toLane) + "'.");
00231             } else {
00232                 from = nFrom;
00233             }
00234         }
00235     } catch (NumberFormatException &) {
00236         MsgHandler::getErrorInstance()->inform("At least one of the defined lanes was not numeric");
00237     }
00238     //
00239     bool keepUncontrolled = attrs.getOptBoolReporting(SUMO_ATTR_UNCONTROLLED, 0, 0, ok, false);
00240     if (keepUncontrolled) {
00241         from->disableConnection4TLS(fromLane, to, toLane);
00242     }
00243 }
00244 
00245 
00246 
00247 /****************************************************************************/
00248 

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