SUMO - Simulation of Urban MObility

RONetHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The handler for SUMO-Networks
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/options/OptionsCont.h>
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/StringTokenizer.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/xml/SUMOSAXHandler.h>
00037 #include <utils/xml/SUMOXMLDefinitions.h>
00038 #include "ROEdge.h"
00039 #include "ROLane.h"
00040 #include "RONode.h"
00041 #include "RONet.h"
00042 #include "RONetHandler.h"
00043 #include "ROAbstractEdgeBuilder.h"
00044 
00045 #ifdef CHECK_MEMORY_LEAKS
00046 #include <foreign/nvwa/debug_new.h>
00047 #endif // CHECK_MEMORY_LEAKS
00048 
00049 
00050 // ===========================================================================
00051 // method definitions
00052 // ===========================================================================
00053 RONetHandler::RONetHandler(RONet& net,
00054                            ROAbstractEdgeBuilder& eb)
00055     : SUMOSAXHandler("sumo-network"),
00056       myNet(net), myCurrentName(),
00057       myCurrentEdge(0), myEdgeBuilder(eb),
00058       myHaveWarnedAboutDeprecatedDistrict(false), myHaveWarnedAboutDeprecatedDSource(false), myHaveWarnedAboutDeprecatedDSink(false) {}
00059 
00060 
00061 RONetHandler::~RONetHandler() throw() {}
00062 
00063 
00064 void
00065 RONetHandler::myStartElement(int element,
00066                              const SUMOSAXAttributes& attrs) throw(ProcessError) {
00067     switch (element) {
00068     case SUMO_TAG_EDGE:
00069         // in the first step, we do need the name to allocate the edge
00070         // in the second, we need it to know to which edge we have to add
00071         //  the following edges to
00072         parseEdge(attrs);
00073         break;
00074     case SUMO_TAG_LANE:
00075         if (myProcess) {
00076             parseLane(attrs);
00077         }
00078         break;
00079     case SUMO_TAG_JUNCTION:
00080         parseJunction(attrs);
00081         break;
00082     case SUMO_TAG_SUCC:
00083         parseConnectingEdge(attrs);
00084         break;
00085     case SUMO_TAG_SUCCLANE:
00086         parseConnectedEdge(attrs);
00087         break;
00088     case SUMO_TAG_CONNECTION:
00089         parseConnection(attrs);
00090         break;
00091     case SUMO_TAG_DISTRICT__DEPRECATED:
00092         if (!myHaveWarnedAboutDeprecatedDistrict) {
00093             myHaveWarnedAboutDeprecatedDistrict = true;
00094             WRITE_WARNING("'" + toString(SUMO_TAG_DISTRICT__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZ) + "'.");
00095         }
00096     case SUMO_TAG_TAZ:
00097         parseDistrict(attrs);
00098         break;
00099     case SUMO_TAG_DSOURCE__DEPRECATED:
00100         if (!myHaveWarnedAboutDeprecatedDSource) {
00101             myHaveWarnedAboutDeprecatedDSource = true;
00102             WRITE_WARNING("'" + toString(SUMO_TAG_DSOURCE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSOURCE) + "'.");
00103         }
00104     case SUMO_TAG_TAZSOURCE:
00105         parseDistrictEdge(attrs, true);
00106         break;
00107     case SUMO_TAG_DSINK__DEPRECATED:
00108         if (!myHaveWarnedAboutDeprecatedDSink) {
00109             myHaveWarnedAboutDeprecatedDSink = true;
00110             WRITE_WARNING("'" + toString(SUMO_TAG_DSINK__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSINK) + "'.");
00111         }
00112     case SUMO_TAG_TAZSINK:
00113         parseDistrictEdge(attrs, false);
00114         break;
00115     default:
00116         break;
00117     }
00118 }
00119 
00120 
00121 void
00122 RONetHandler::parseEdge(const SUMOSAXAttributes& attrs) {
00123     // get the id, report an error if not given or empty...
00124     bool ok = true;
00125     myCurrentName = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00126     if (!ok) {
00127         throw ProcessError();
00128     }
00129     // get the edge
00130     myCurrentEdge = 0;
00131     if (myCurrentName[0]==':') {
00132         // this is an internal edge - we will not use it
00133         //  !!! recheck this; internal edges may be of importance during the dua
00134         return;
00135     }
00136     std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
00137     std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
00138     std::string type = attrs.hasAttribute(SUMO_ATTR_FUNCTION) ? attrs.getStringReporting(SUMO_ATTR_FUNCTION, myCurrentName.c_str(), ok) : "";
00139     if (!ok) {
00140         return;
00141     }
00142     RONode* fromNode = myNet.getNode(from);
00143     if (fromNode==0) {
00144         fromNode = new RONode(from);
00145         myNet.addNode(fromNode);
00146     }
00147     RONode* toNode = myNet.getNode(to);
00148     if (toNode==0) {
00149         toNode = new RONode(to);
00150         myNet.addNode(toNode);
00151     }
00152     // build the edge
00153     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode);
00154     if (myNet.addEdge(myCurrentEdge)) {
00155         // get the type of the edge
00156         myProcess = true;
00157         if (type==""||type=="normal"||type=="connector") {
00158             myCurrentEdge->setType(ROEdge::ET_NORMAL);
00159         } else if (type=="source") {
00160             myCurrentEdge->setType(ROEdge::ET_SOURCE);
00161         } else if (type=="sink") {
00162             myCurrentEdge->setType(ROEdge::ET_SINK);
00163         } else if (type=="internal") {
00164             myProcess = false;
00165         } else {
00166             WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
00167             return;
00168         }
00169     } else {
00170         myCurrentEdge = 0;
00171     }
00172 }
00173 
00174 
00175 void
00176 RONetHandler::parseLane(const SUMOSAXAttributes& attrs) {
00177     if (myCurrentEdge==0) {
00178         // was an internal edge to skip or an error occured
00179         return;
00180     }
00181     bool ok = true;
00182     SUMOVehicleClasses allowed, disallowed;
00183     // get the id, report an error if not given or empty...
00184     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00185     if (!ok) {
00186         return;
00187     }
00188     // get the speed
00189     SUMOReal maxSpeed = attrs.hasAttribute(SUMO_ATTR_SPEED)
00190                         ? attrs.getSUMORealReporting(SUMO_ATTR_SPEED, id.c_str(), ok)
00191                         : attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED__DEPRECATED, id.c_str(), ok);
00192     SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
00193     std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
00194     std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
00195     if (!ok) {
00196         return;
00197     }
00198     // get the length
00199     // get the vehicle classes
00200     parseVehicleClasses(allow, disallow, allowed, disallowed);
00201     if (allowed.size()!=0 || disallowed.size() != 0) {
00202         myNet.setRestrictionFound();
00203     }
00204     // add when both values are valid
00205     if (maxSpeed>0&&length>0&&id.length()>0) {
00206         myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, allowed, disallowed));
00207     }
00208 }
00209 
00210 
00211 void
00212 RONetHandler::parseJunction(const SUMOSAXAttributes& attrs) {
00213     bool ok = true;
00214     // get the id, report an error if not given or empty...
00215     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00216     if (!ok) {
00217         return;
00218     }
00219     // get the position of the node
00220     SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
00221     SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
00222     if (ok) {
00223         RONode* n = myNet.getNode(id);
00224         if (n==0) {
00225             n = new RONode(id);
00226             myNet.addNode(n);
00227         }
00228         n->setPosition(Position(x, y));
00229     } else {
00230         throw ProcessError();
00231     }
00232 }
00233 
00234 
00235 void
00236 RONetHandler::parseConnectingEdge(const SUMOSAXAttributes& attrs) throw(ProcessError) {
00237     bool ok = true;
00238     std::string id = attrs.getStringReporting(SUMO_ATTR_EDGE,0, ok);
00239     if (id[0]==':') {
00240         myCurrentEdge = 0;
00241         return;
00242     }
00243     myCurrentEdge = myNet.getEdge(id);
00244     if (myCurrentEdge==0) {
00245         throw ProcessError("An unknown edge occured (id='" + id + "').");
00246     }
00247 }
00248 
00249 
00250 void
00251 RONetHandler::parseConnectedEdge(const SUMOSAXAttributes& attrs) {
00252     if (myCurrentEdge==0) {
00253         // earlier error or internal link
00254         return;
00255     }
00256     bool ok = true;
00257     std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, myCurrentName.c_str(), ok);
00258     if (id=="SUMO_NO_DESTINATION") {
00259         return;
00260     }
00261     ROEdge* succ = myNet.getEdge(id.substr(0, id.rfind('_')));
00262     if (succ!=0) {
00263         // connect edge
00264         myCurrentEdge->addFollower(succ);
00265     } else {
00266         WRITE_ERROR("At edge '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00267     }
00268 }
00269 
00270 
00271 void
00272 RONetHandler::parseConnection(const SUMOSAXAttributes& attrs) {
00273     bool ok = true;
00274     std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
00275     std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
00276     if (fromID[0]==':') { // skip inner lane connections
00277         return;
00278     }
00279     ROEdge* from = myNet.getEdge(fromID);
00280     ROEdge* to = myNet.getEdge(toID);
00281     if (from == 0) {
00282         throw ProcessError("unknown from-edge '" + fromID + "' in connection");
00283     }
00284     if (to == 0) {
00285         throw ProcessError("unknown to-edge '" + toID + "' in connection");
00286     }
00287     from->addFollower(to);
00288 }
00289 
00290 
00291 void
00292 RONetHandler::parseDistrict(const SUMOSAXAttributes& attrs) throw(ProcessError) {
00293     myCurrentEdge = 0;
00294     bool ok = true;
00295     myCurrentName = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00296     if (!ok) {
00297         return;
00298     }
00299     ROEdge* sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", 0, 0);
00300     sink->setType(ROEdge::ET_DISTRICT);
00301     myNet.addEdge(sink);
00302     ROEdge* source = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0);
00303     source->setType(ROEdge::ET_DISTRICT);
00304     myNet.addEdge(source);
00305     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
00306         std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
00307         for (std::vector<std::string>::const_iterator i=desc.begin(); i!=desc.end(); ++i) {
00308             ROEdge* edge = myNet.getEdge(*i);
00309             // check whether the edge exists
00310             if (edge==0) {
00311                 throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
00312             }
00313             source->addFollower(edge);
00314             edge->addFollower(sink);
00315         }
00316     }
00317 }
00318 
00319 
00320 void
00321 RONetHandler::parseDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
00322     bool ok = true;
00323     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
00324     ROEdge* succ = myNet.getEdge(id);
00325     if (succ!=0) {
00326         // connect edge
00327         if (isSource) {
00328             myNet.getEdge(myCurrentName+"-source")->addFollower(succ);
00329         } else {
00330             succ->addFollower(myNet.getEdge(myCurrentName+"-sink"));
00331         }
00332     } else {
00333         WRITE_ERROR("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00334     }
00335 }
00336 
00337 
00338 
00339 /****************************************************************************/
00340 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines