00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00054
00055
00056
00057
00058 void
00059 NIImporter_SUMO::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) {
00060
00061 if (!oc.isUsableFileList("sumo-net")) {
00062 return;
00063 }
00064
00065 NIImporter_SUMO handler(nb.getNodeCont());
00066
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
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
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
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
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
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
00125 continue;
00126 }
00127 ed->builtEdge->addLane2LaneConnection(j, ce, index, NBEdge::L2L_VALIDATED);
00128 }
00129 }
00130 }
00131 }
00132
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
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
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
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
00230 myCurrentEdge->type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, "edge", id.c_str(), ok, "");
00231
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
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
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
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
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
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