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 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <string>
00031 #include <utils/options/OptionsCont.h>
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/StringTokenizer.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/xml/SUMOSAXHandler.h>
00036 #include <utils/xml/SUMOXMLDefinitions.h>
00037 #include "ROEdge.h"
00038 #include "ROLane.h"
00039 #include "RONode.h"
00040 #include "RONet.h"
00041 #include "RONetHandler.h"
00042 #include "ROAbstractEdgeBuilder.h"
00043 
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047 
00048 
00049 // ===========================================================================
00050 // method definitions
00051 // ===========================================================================
00052 RONetHandler::RONetHandler(RONet &net,
00053                            ROAbstractEdgeBuilder &eb)
00054         : SUMOSAXHandler("sumo-network"),
00055         myNet(net), myCurrentName(),
00056         myCurrentEdge(0), myEdgeBuilder(eb), myHaveWarnedAboutDeprecatedVClass(false) {}
00057 
00058 
00059 RONetHandler::~RONetHandler() throw() {}
00060 
00061 
00062 void
00063 RONetHandler::myStartElement(SumoXMLTag element,
00064                              const SUMOSAXAttributes &attrs) throw(ProcessError) {
00065     switch (element) {
00066     case SUMO_TAG_EDGE:
00067         // in the first step, we do need the name to allocate the edge
00068         // in the second, we need it to know to which edge we have to add
00069         //  the following edges to
00070         parseEdge(attrs);
00071         break;
00072     case SUMO_TAG_LANE:
00073         if (myProcess) {
00074             parseLane(attrs);
00075         }
00076         break;
00077     case SUMO_TAG_JUNCTION:
00078         parseJunction(attrs);
00079         break;
00080     case SUMO_TAG_SUCC:
00081         parseConnectingEdge(attrs);
00082         break;
00083     case SUMO_TAG_SUCCLANE:
00084         parseConnectedEdge(attrs);
00085         break;
00086     case SUMO_TAG_DISTRICT:
00087         parseDistrict(attrs);
00088         break;
00089     case SUMO_TAG_DSOURCE:
00090         parseDistrictEdge(attrs, true);
00091         break;
00092     case SUMO_TAG_DSINK:
00093         parseDistrictEdge(attrs, false);
00094         break;
00095     default:
00096         break;
00097     }
00098 }
00099 
00100 
00101 void
00102 RONetHandler::parseEdge(const SUMOSAXAttributes &attrs) {
00103     // get the id, report an error if not given or empty...
00104     if (!attrs.setIDFromAttributes("edge", myCurrentName)) {
00105         throw ProcessError();
00106     }
00107     // get the edge
00108     myCurrentEdge = 0;
00109     if (myCurrentName[0]==':') {
00110         // this is an internal edge - we will not use it
00111         //  !!! recheck this; internal edges may be of importance during the dua
00112         return;
00113     }
00114     bool ok = true;
00115     std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, "edge", myCurrentName.c_str(), ok);
00116     std::string to = attrs.getStringReporting(SUMO_ATTR_TO, "edge", myCurrentName.c_str(), ok);
00117     std::string type = attrs.getStringReporting(SUMO_ATTR_FUNCTION, "edge", myCurrentName.c_str(), ok);
00118     if (!ok) {
00119         return;
00120     }
00121     RONode *fromNode = myNet.getNode(from);
00122     if (fromNode==0) {
00123         fromNode = new RONode(from);
00124         myNet.addNode(fromNode);
00125     }
00126     RONode *toNode = myNet.getNode(to);
00127     if (toNode==0) {
00128         toNode = new RONode(to);
00129         myNet.addNode(toNode);
00130     }
00131     // build the edge
00132     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode);
00133     myNet.addEdge(myCurrentEdge); // !!! where is the edge deleted when failing?
00134     // !!! secure??
00135     // get the type of the edge
00136     myProcess = true;
00137     if (type=="normal"||type=="connector") {
00138         myCurrentEdge->setType(ROEdge::ET_NORMAL);
00139     } else if (type=="source") {
00140         myCurrentEdge->setType(ROEdge::ET_SOURCE);
00141     } else if (type=="sink") {
00142         myCurrentEdge->setType(ROEdge::ET_SINK);
00143     } else if (type=="internal") {
00144         myProcess = false;
00145     } else {
00146         MsgHandler::getErrorInstance()->inform("Edge '" + myCurrentName + "' has an unknown type.");
00147         return;
00148     }
00149 }
00150 
00151 
00152 void
00153 RONetHandler::parseLane(const SUMOSAXAttributes &attrs) {
00154     if (myCurrentEdge==0) {
00155         // was an internal edge to skip or an error occured
00156         return;
00157     }
00158     std::vector<SUMOVehicleClass> allowed, disallowed;
00159     // get the id, report an error if not given or empty...
00160     std::string id;
00161     if (!attrs.setIDFromAttributes("lane", id)) {
00162         return;
00163     }
00164     // get the speed
00165     bool ok = true;
00166     SUMOReal maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED, "lane", id.c_str(), ok);
00167     SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "lane", id.c_str(), ok);
00168     std::string vclasses = attrs.getOptStringReporting(SUMO_ATTR_VCLASSES, "lane", id.c_str(), ok, "");
00169     std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, "lane", id.c_str(), ok, "");
00170     std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, "lane", id.c_str(), ok, "");
00171     if (!ok) {
00172         return;
00173     }
00174     // get the length
00175     // get the vehicle classes
00176     parseVehicleClasses(vclasses, allow, disallow,
00177                         allowed, disallowed, myHaveWarnedAboutDeprecatedVClass);
00178     if (allowed.size()!=0 || disallowed.size() != 0) {
00179         myNet.setRestrictionFound();
00180     }
00181     // add when both values are valid
00182     if (maxSpeed>0&&length>0&&id.length()>0) {
00183         myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, allowed, disallowed));
00184     }
00185 }
00186 
00187 
00188 void
00189 RONetHandler::parseJunction(const SUMOSAXAttributes &attrs) {
00190     // get the id, report an error if not given or empty...
00191     std::string id;
00192     if (!attrs.setIDFromAttributes("junction", id)) {
00193         return;
00194     }
00195     // get the position of the node
00196     bool ok = true;
00197     SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, "junction", id.c_str(), ok);
00198     SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, "junction", id.c_str(), ok);
00199     if (ok) {
00200         RONode *n = myNet.getNode(id);
00201         if (n==0) {
00202             n = new RONode(id);
00203             myNet.addNode(n);
00204         }
00205         n->setPosition(Position2D(x, y));
00206     } else {
00207         throw ProcessError();
00208     }
00209 }
00210 
00211 
00212 void
00213 RONetHandler::parseConnectingEdge(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00214     bool ok = true;
00215     std::string id = attrs.getStringReporting(SUMO_ATTR_EDGE, 0,0, ok);
00216     if (id[0]==':') {
00217         myCurrentEdge = 0;
00218         return;
00219     }
00220     myCurrentEdge = myNet.getEdge(id);
00221     if (myCurrentEdge==0) {
00222         throw ProcessError("An unknown edge occured (id='" + id + "').");
00223     }
00224 }
00225 
00226 
00227 void
00228 RONetHandler::parseConnectedEdge(const SUMOSAXAttributes &attrs) {
00229     if (myCurrentEdge==0) {
00230         // earlier error or internal link
00231         return;
00232     }
00233     bool ok = true;
00234     std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, "lane", myCurrentName.c_str(), ok);
00235     if (id=="SUMO_NO_DESTINATION") {
00236         return;
00237     }
00238     ROEdge *succ = myNet.getEdge(id.substr(0, id.rfind('_')));
00239     if (succ!=0) {
00240         // connect edge
00241         myCurrentEdge->addFollower(succ);
00242     } else {
00243         MsgHandler::getErrorInstance()->inform("At edge '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00244     }
00245 }
00246 
00247 
00248 void
00249 RONetHandler::parseDistrict(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00250     if (!attrs.setIDFromAttributes("district", myCurrentName)) {
00251         return;
00252     }
00253     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, 0, 0);
00254     myCurrentEdge->setType(ROEdge::ET_DISTRICT);
00255     myNet.addEdge(myCurrentEdge);
00256     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0);
00257     myCurrentEdge->setType(ROEdge::ET_DISTRICT);
00258     myNet.addEdge(myCurrentEdge);
00259     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
00260         std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
00261         for (std::vector<std::string>::const_iterator i=desc.begin(); i!=desc.end(); ++i) {
00262             ROEdge *edge = myNet.getEdge(*i);
00263             // check whether the edge exists
00264             if (edge==0) {
00265                 throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
00266             }
00267             myCurrentEdge->addFollower(edge);
00268             edge->addFollower(myNet.getEdge(myCurrentName));
00269         }
00270     }
00271 }
00272 
00273 
00274 void
00275 RONetHandler::parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource) {
00276     if (myCurrentEdge==0) {
00277         // earlier error or internal link
00278         return;
00279     }
00280     bool ok = true;
00281     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "district", myCurrentName.c_str(), ok);
00282     ROEdge *succ = myNet.getEdge(id);
00283     if (succ!=0) {
00284         // connect edge
00285         if (isSource) {
00286             myCurrentEdge->addFollower(succ);
00287         } else {
00288             succ->addFollower(myNet.getEdge(myCurrentName));
00289         }
00290     } else {
00291         MsgHandler::getErrorInstance()->inform("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00292     }
00293 }
00294 
00295 
00296 
00297 /****************************************************************************/
00298 

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