NIImporter_SUMO.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for networks stored in SUMO format
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 #include <string>
00030 #include <utils/xml/SUMOSAXHandler.h>
00031 #include <utils/common/UtilExceptions.h>
00032 #include <utils/common/TplConvert.h>
00033 #include <utils/common/MsgHandler.h>
00034 #include <netbuild/NBEdge.h>
00035 #include <netbuild/NBEdgeCont.h>
00036 #include <netbuild/NBNode.h>
00037 #include <netbuild/NBNodeCont.h>
00038 #include <netbuild/NBNetBuilder.h>
00039 #include <utils/xml/SUMOXMLDefinitions.h>
00040 #include "NIImporter_SUMO.h"
00041 #include <utils/geom/GeoConvHelper.h>
00042 #include <utils/geom/GeomConvHelper.h>
00043 #include <utils/options/OptionsCont.h>
00044 #include <utils/common/FileHelpers.h>
00045 #include <utils/xml/XMLSubSys.h>
00046 
00047 #ifdef CHECK_MEMORY_LEAKS
00048 #include <foreign/nvwa/debug_new.h>
00049 #endif // CHECK_MEMORY_LEAKS
00050 
00051 
00052 // ===========================================================================
00053 // method definitions
00054 // ===========================================================================
00055 // ---------------------------------------------------------------------------
00056 // static methods (interface in this case)
00057 // ---------------------------------------------------------------------------
00058 void
00059 NIImporter_SUMO::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) {
00060     // check whether the option is set (properly)
00061     if (!oc.isUsableFileList("sumo-net")) {
00062         return;
00063     }
00064     // build the handler
00065     NIImporter_SUMO handler(nb.getNodeCont());
00066     // parse file(s)
00067     std::vector<std::string> files = oc.getStringVector("sumo-net");
00068     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00069         if (!FileHelpers::exists(*file)) {
00070             MsgHandler::getErrorInstance()->inform("Could not open sumo-net-file '" + *file + "'.");
00071             return;
00072         }
00073         handler.setFileName(*file);
00074         MsgHandler::getMessageInstance()->beginProcessMsg("Parsing sumo-net from '" + *file + "'...");
00075         XMLSubSys::runParser(handler, *file);
00076         MsgHandler::getMessageInstance()->endProcessMsg("done.");
00077     }
00078     // build edges
00079     std::map<std::string, EdgeAttrs*> &loadedEdges = handler.myEdges;
00080     NBNodeCont &nodesCont = nb.getNodeCont();
00081     NBEdgeCont &edgesCont = nb.getEdgeCont();
00082     for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) {
00083         EdgeAttrs *ed = (*i).second;
00084         // get and check the nodes
00085         NBNode *from = nodesCont.retrieve(ed->fromNode);
00086         NBNode *to = nodesCont.retrieve(ed->toNode);
00087         if (from==0) {
00088             MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
00089             continue;
00090         }
00091         if (to==0) {
00092             MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
00093             continue;
00094         }
00095         // build and insert the edge
00096         NBEdge *e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority);
00097         if (!edgesCont.insert(e)) {
00098             MsgHandler::getErrorInstance()->inform("Could not insert edge '" + ed->id + "'.");
00099             delete e;
00100             continue;
00101         }
00102         ed->builtEdge = edgesCont.retrieve(ed->id);
00103     }
00104     // assign lane attributes (edges are built)
00105     for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) {
00106         EdgeAttrs *ed = (*i).second;
00107         if (ed->builtEdge==0) {
00108             // earlier errors
00109             continue;
00110         }
00111         for (unsigned int j=0; j<(unsigned int) ed->lanes.size(); ++j) {
00112             const std::vector<EdgeLane> &connections = ed->lanes[j]->connections;
00113             for (std::vector<EdgeLane>::const_iterator k=connections.begin(); k!=connections.end(); ++k) {
00114                 if ((*k).lane!="SUMO_NO_DESTINATION") {
00115                     std::string lane = (*k).lane;
00116                     std::string edge = lane.substr(0, lane.find('_'));
00117                     int index = TplConvert<char>::_2int(lane.substr(lane.find('_')+1).c_str());
00118                     if (loadedEdges.find(edge)==loadedEdges.end()) {
00119                         MsgHandler::getErrorInstance()->inform("Unknown edge given in succlane (for lane '" + lane + "').");
00120                         continue;
00121                     }
00122                     NBEdge *ce = loadedEdges.find(edge)->second->builtEdge;
00123                     if (ce==0) {
00124                         // earlier error or edge removal
00125                         continue;
00126                     }
00127                     ed->builtEdge->addLane2LaneConnection(j, ce, index, NBEdge::L2L_VALIDATED);
00128                 }
00129             }
00130         }
00131     }
00132     // clean up
00133     for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) {
00134         EdgeAttrs *ed = (*i).second;
00135         for (std::vector<LaneAttrs*>::const_iterator j=ed->lanes.begin(); j!=ed->lanes.end(); ++j) {
00136             delete *j;
00137         }
00138         delete ed;
00139     }
00140 }
00141 
00142 
00143 
00144 // ---------------------------------------------------------------------------
00145 // loader methods
00146 // ---------------------------------------------------------------------------
00147 NIImporter_SUMO::NIImporter_SUMO(NBNodeCont &nc)
00148         : SUMOSAXHandler("sumo-network"),
00149         myNodeCont(nc), myCurrentEdge(0) {}
00150 
00151 
00152 NIImporter_SUMO::~NIImporter_SUMO() throw() {
00153 }
00154 
00155 
00156 void
00157 NIImporter_SUMO::myStartElement(SumoXMLTag element,
00158                                 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00159     switch (element) {
00160     case SUMO_TAG_EDGE:
00161         addEdge(attrs);
00162         break;
00163     case SUMO_TAG_LANE:
00164         if (myCurrentEdge!=0) {
00165             addLane(attrs);
00166         }
00167         break;
00168     case SUMO_TAG_JUNCTION:
00169         addJunction(attrs);
00170         break;
00171     case SUMO_TAG_SUCC:
00172         addSuccEdge(attrs);
00173         break;
00174     case SUMO_TAG_SUCCLANE:
00175         addSuccLane(attrs);
00176         break;
00177     }
00178 }
00179 
00180 
00181 void
00182 NIImporter_SUMO::myCharacters(SumoXMLTag element,
00183                               const std::string &chars) throw(ProcessError) {
00184     switch (element) {
00185     case SUMO_TAG_LANE:
00186         // @deprecated At some time, SUMO_ATTR_SHAPE will be mandatory
00187         if (myCurrentLane!=0&&chars.length()!=0) {
00188             bool ok = true;
00189             myCurrentLane->shape = GeomConvHelper::parseShapeReporting(chars, "lane", 0, ok, false);
00190         }
00191         break;
00192     }
00193 }
00194 
00195 
00196 
00197 void
00198 NIImporter_SUMO::myEndElement(SumoXMLTag element) throw(ProcessError) {
00199     switch (element) {
00200     case SUMO_TAG_EDGE:
00201         if (myEdges.find(myCurrentEdge->id)!=myEdges.end()) {
00202             MsgHandler::getErrorInstance()->inform("Edge '" + myCurrentEdge->id + "' occured at least twice in the input.");
00203         } else {
00204             myEdges[myCurrentEdge->id] = myCurrentEdge;
00205         }
00206         myCurrentEdge = 0;
00207         break;
00208     case SUMO_TAG_LANE:
00209         if (myCurrentEdge!=0) {
00210             myCurrentEdge->maxSpeed = MAX2(myCurrentEdge->maxSpeed, myCurrentLane->maxSpeed);
00211             myCurrentEdge->lanes.push_back(myCurrentLane);
00212         }
00213         myCurrentLane = 0;
00214         break;
00215     }
00216 }
00217 
00218 
00219 void
00220 NIImporter_SUMO::addEdge(const SUMOSAXAttributes &attrs) {
00221     // get the id, report an error if not given or empty...
00222     std::string id;
00223     if (!attrs.setIDFromAttributes("edge", id)) {
00224         return;
00225     }
00226     bool ok = true;
00227     myCurrentEdge = new EdgeAttrs;
00228     myCurrentEdge->id = id;
00229     // get the type
00230     myCurrentEdge->type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, "edge", id.c_str(), ok, "");
00231     // get the origin and the destination node
00232     myCurrentEdge->fromNode = attrs.getOptStringReporting(SUMO_ATTR_FROM, "edge", id.c_str(), ok, "");
00233     myCurrentEdge->toNode = attrs.getOptStringReporting(SUMO_ATTR_TO, "edge", id.c_str(), ok, "");
00234     myCurrentEdge->priority = attrs.getOptIntReporting(SUMO_ATTR_PRIORITY, "edge", id.c_str(), ok, -1);
00235     myCurrentEdge->maxSpeed = 0;
00236     myCurrentEdge->builtEdge = 0;
00237 }
00238 
00239 
00240 void
00241 NIImporter_SUMO::addLane(const SUMOSAXAttributes &attrs) {
00242     myCurrentLane = new LaneAttrs;
00243     bool ok = true;
00244     myCurrentLane->maxSpeed = attrs.getOptSUMORealReporting(SUMO_ATTR_MAXSPEED, "lane", 0, ok, -1);
00245     myCurrentLane->depart = attrs.getOptBoolReporting(SUMO_ATTR_DEPART, 0, 0, ok, false);
00246     if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00247         // @deprecated At some time, SUMO_ATTR_SHAPE will be mandatory
00248         myCurrentLane->shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, "lane", 0, ok), "lane", 0, ok, false);
00249     }
00250 }
00251 
00252 
00253 void
00254 NIImporter_SUMO::addJunction(const SUMOSAXAttributes &attrs) {
00255     // get the id, report an error if not given or empty...
00256     std::string id;
00257     if (!attrs.setIDFromAttributes("junction", id)) {
00258         return;
00259     }
00260     if (id[0]==':') {
00261         return;
00262     }
00263     bool ok = true;
00264     SUMOReal x = attrs.getOptSUMORealReporting(SUMO_ATTR_X, "junction", id.c_str(), ok, -1);
00265     SUMOReal y = attrs.getOptSUMORealReporting(SUMO_ATTR_Y, "junction", id.c_str(), ok, -1);
00266     // !!! this is too simplified! A proper error check should be done
00267     if (x==-1||y==-1) {
00268         MsgHandler::getErrorInstance()->inform("Junction '" + id + "' has an invalid position.");
00269         return;
00270     }
00271     Position2D pos(x, y);
00272     if (!GeoConvHelper::x2cartesian(pos)) {
00273         MsgHandler::getErrorInstance()->inform("Unable to project coordinates for junction " + id + ".");
00274         return;
00275     }
00276     NBNode *node = new NBNode(id, pos);
00277     if (!myNodeCont.insert(node)) {
00278         MsgHandler::getErrorInstance()->inform("Problems on adding junction '" + id + "'.");
00279         delete node;
00280         return;
00281     }
00282 }
00283 
00284 
00285 void
00286 NIImporter_SUMO::addSuccEdge(const SUMOSAXAttributes &attrs) {
00287     bool ok = true;
00288     std::string lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, 0, 0, ok, "");
00289     std::string edge = lane.substr(0, lane.find('_'));
00290     int index = TplConvert<char>::_2int(lane.substr(lane.find('_')+1).c_str());
00291     myCurrentEdge = 0;
00292     myCurrentLane = 0;
00293     if (myEdges.find(edge)==myEdges.end()) {
00294         MsgHandler::getErrorInstance()->inform("Unknown edge '" + edge + "' given in succedge.");
00295         return;
00296     }
00297     myCurrentEdge = myEdges.find(edge)->second;
00298     // !!! externalize retrieval of lane index by name
00299     if (myCurrentEdge->lanes.size()<(size_t) index) {
00300         MsgHandler::getErrorInstance()->inform("Unknown lane '" + lane + "' given in succedge.");
00301         return;
00302     }
00303     myCurrentLane = myCurrentEdge->lanes[(size_t) index];
00304 }
00305 
00306 
00307 void
00308 NIImporter_SUMO::addSuccLane(const SUMOSAXAttributes &attrs) {
00309     if (myCurrentLane==0) {
00310         // had error
00311         return;
00312     }
00313     bool ok = true;
00314     std::string lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, 0, 0, ok, "");
00315     EdgeLane el;
00316     el.lane = lane;
00317     myCurrentLane->connections.push_back(el);
00318 }
00319 
00320 
00321 
00322 /****************************************************************************/
00323 

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