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 "NIImporter_OpenStreetMap.h"
00030 #include <algorithm>
00031 #include <functional>
00032 #include <sstream>
00033 #include <utils/xml/SUMOSAXHandler.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/common/TplConvert.h>
00036 #include <utils/common/ToString.h>
00037 #include <utils/common/MsgHandler.h>
00038 #include <netbuild/NBEdge.h>
00039 #include <netbuild/NBEdgeCont.h>
00040 #include <netbuild/NBNode.h>
00041 #include <netbuild/NBNodeCont.h>
00042 #include <netbuild/NBNetBuilder.h>
00043 #include <netbuild/NBOwnTLDef.h>
00044 #include <utils/xml/SUMOXMLDefinitions.h>
00045 #include <utils/geom/GeoConvHelper.h>
00046 #include <utils/geom/GeomConvHelper.h>
00047 #include <utils/options/OptionsCont.h>
00048 #include <utils/common/FileHelpers.h>
00049 #include <utils/xml/XMLSubSys.h>
00050 #include <utils/iodevices/BinaryInputDevice.h>
00051
00052 #ifdef CHECK_MEMORY_LEAKS
00053 #include <foreign/nvwa/debug_new.h>
00054 #endif // CHECK_MEMORY_LEAKS
00055
00056
00057
00058
00059
00060
00061
00068 class NIImporter_OpenStreetMap::CompareNodesInPairs: public std::unary_function<
00069 std::pair<int, NIOSMNode*>, bool> {
00070 public:
00077 CompareNodesInPairs(const std::pair<int, NIOSMNode*>& p0) :
00078 myP0(p0) {
00079 }
00088 bool operator()(const std::pair<int, NIOSMNode*>& p1) const {
00089 return (p1.second->lat == myP0.second->lat) && (p1.second->lon
00090 == myP0.second->lon);
00091 }
00092
00093 private:
00094 std::pair<int, NIOSMNode*> myP0;
00095 };
00096
00099 class NIImporter_OpenStreetMap::SubstituteNode: public std::unary_function<
00100 std::pair<std::string, Edge*>, void> {
00101 public:
00111 SubstituteNode(const NIOSMNode* const toSubstitute,
00112 const NIOSMNode* const substituteWith) :
00113 myToSubstitute(toSubstitute), mySubstituteWith(substituteWith) {
00114 }
00123 void operator()(const std::pair<std::string, Edge*>& p) const {
00124 std::vector<int>& edgeNodes = p.second->myCurrentNodes;
00125
00126 std::replace_if(edgeNodes.begin(), edgeNodes.end(), std::bind2nd(
00127 std::equal_to<int>(), myToSubstitute->id), mySubstituteWith->id);
00128
00129
00130 std::vector<int>::iterator newEnd = std::unique(edgeNodes.begin(),
00131 edgeNodes.end());
00132 edgeNodes.erase(newEnd, edgeNodes.end());
00133 }
00134
00135 private:
00136 const NIOSMNode * const myToSubstitute, * const mySubstituteWith;
00137 };
00138
00141 class NIImporter_OpenStreetMap::SimilarEdge : public std::unary_function<
00142 std::pair<std::string, Edge*>, bool> {
00143 public:
00148 SimilarEdge(const std::pair<std::string, Edge*>& p0) :
00149 myP0(p0) {
00150 }
00151
00159 bool operator()(const std::pair<std::string, Edge*>& p1) const {
00160 return
00161 myP0.second->myNoLanes==p1.second->myNoLanes &&
00162 myP0.second->myMaxSpeed==p1.second->myMaxSpeed &&
00163 myP0.second->myHighWayType==p1.second->myHighWayType &&
00164 myP0.second->myIsOneWay==p1.second->myIsOneWay &&
00165 myP0.second->myCurrentNodes==p1.second->myCurrentNodes &&
00166 myP0.second->myCurrentIsRoad==p1.second->myCurrentIsRoad;
00167 }
00168
00169 private:
00170 std::pair<std::string, Edge*> myP0;
00171 };
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 void
00182 NIImporter_OpenStreetMap::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) {
00183
00184 if (!oc.isSet("osm-files")) {
00185 return;
00186 }
00187
00188
00189 NBTypeCont &tc = nb.getTypeCont();
00190 tc.insert("highway.motorway", 3, (SUMOReal)(160./3.6), 13, SVC_UNKNOWN, true);
00191 tc.insert("highway.motorway_link", 1, (SUMOReal)(80./3.6), 12, SVC_UNKNOWN, true);
00192 tc.insert("highway.trunk", 2, (SUMOReal)(100./3.6), 11);
00193 tc.insert("highway.trunk_link", 1, (SUMOReal)(80./3.6), 10);
00194 tc.insert("highway.primary", 2, (SUMOReal)(100./3.6), 9);
00195 tc.insert("highway.primary_link", 1, (SUMOReal)(80./3.6), 8);
00196 tc.insert("highway.secondary", 2, (SUMOReal)(100./3.6), 7);
00197 tc.insert("highway.tertiary", 1, (SUMOReal)(80./3.6), 6);
00198 tc.insert("highway.unclassified", 1, (SUMOReal)(80./3.6), 5);
00199 tc.insert("highway.residential", 1, (SUMOReal)(50./3.6), 4);
00200 tc.insert("highway.living_street", 1, (SUMOReal)(10./3.6), 3);
00201 tc.insert("highway.service", 1, (SUMOReal)(20./3.6), 2, SVC_DELIVERY);
00202 tc.insert("highway.track", 1, (SUMOReal)(20./3.6), 1);
00203 tc.insert("highway.services", 1, (SUMOReal)(30./3.6), 1);
00204 tc.insert("highway.unsurfaced", 1, (SUMOReal)(30./3.6), 1);
00205 tc.insert("highway.footway", 1, (SUMOReal)(30./3.6), 1, SVC_PEDESTRIAN);
00206 tc.insert("highway.pedestrian", 1, (SUMOReal)(30./3.6), 1, SVC_PEDESTRIAN);
00207
00208 tc.insert("highway.path", 1, (SUMOReal)(10./3.6), 1, SVC_PEDESTRIAN);
00209 tc.insert("highway.bridleway", 1, (SUMOReal)(10./3.6), 1, SVC_PEDESTRIAN);
00210 tc.insert("highway.cycleway", 1, (SUMOReal)(20./3.6), 1, SVC_BICYCLE);
00211 tc.insert("highway.footway", 1, (SUMOReal)(10./3.6), 1, SVC_PEDESTRIAN);
00212 tc.insert("highway.step", 1, (SUMOReal)(5./3.6), 1, SVC_PEDESTRIAN);
00213 tc.insert("highway.steps", 1, (SUMOReal)(5./3.6), 1, SVC_PEDESTRIAN);
00214 tc.insert("highway.stairs", 1, (SUMOReal)(5./3.6), 1, SVC_PEDESTRIAN);
00215 tc.insert("highway.bus_guideway", 1, (SUMOReal)(30./3.6), 1, SVC_BUS);
00216
00217
00218 tc.insert("railway.rail", 1, (SUMOReal)(30./3.6), 1, SVC_RAIL_FAST);
00219 tc.insert("railway.tram", 1, (SUMOReal)(30./3.6), 1, SVC_CITYRAIL);
00220 tc.insert("railway.light_rail", 1, (SUMOReal)(30./3.6), 1, SVC_LIGHTRAIL);
00221 tc.insert("railway.subway", 1, (SUMOReal)(30./3.6), 1, SVC_CITYRAIL);
00222 tc.insert("railway.preserved", 1, (SUMOReal)(30./3.6), 1, SVC_LIGHTRAIL);
00223 tc.insert("railway.monorail", 1, (SUMOReal)(30./3.6), 1, SVC_LIGHTRAIL);
00224
00225
00226
00227
00228 std::vector<std::string> files = oc.getStringVector("osm-files");
00229
00230 std::map<int, NIOSMNode*> nodes;
00231 NodesHandler nodesHandler(nodes);
00232 for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00233
00234 if (!FileHelpers::exists(*file)) {
00235 MsgHandler::getErrorInstance()->inform("Could not open osm-file '" + *file + "'.");
00236 return;
00237 }
00238 nodesHandler.setFileName(*file);
00239 MsgHandler::getMessageInstance()->beginProcessMsg("Parsing nodes from osm-file '" + *file + "'...");
00240 XMLSubSys::runParser(nodesHandler, *file);
00241 MsgHandler::getMessageInstance()->endProcessMsg("done.");
00242 }
00243
00244 std::map<std::string, Edge*> edges;
00245 EdgesHandler edgesHandler(nodes, edges);
00246 for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00247
00248 edgesHandler.setFileName(*file);
00249 MsgHandler::getMessageInstance()->beginProcessMsg("Parsing edges from osm-file '" + *file + "'...");
00250 XMLSubSys::runParser(edgesHandler, *file);
00251 MsgHandler::getMessageInstance()->endProcessMsg("done.");
00252 }
00253
00254
00255
00256
00257
00258
00259 MsgHandler::getMessageInstance()->beginProcessMsg("Removing duplicate nodes...");
00260 if (nodes.size() > 1) {
00261
00262
00263 for (std::map<int, NIOSMNode*>::iterator it = nodes.begin(), itnext =++nodes.begin(); itnext != nodes.end(); ++it, ++itnext) {
00264 std::map<int, NIOSMNode*>::iterator dupNode = find_if(itnext, nodes.end(), CompareNodesInPairs(*it));
00265 if (dupNode != nodes.end()) {
00266 MsgHandler::getMessageInstance()->inform("Found duplicate nodes. Substitute " + toString(dupNode->second->id) + " with " + toString(it->second->id));
00267 for_each(edges.begin(), edges.end(), SubstituteNode(dupNode->second, it->second));
00268 }
00269 }
00270 }
00271 MsgHandler::getMessageInstance()->endProcessMsg(" done.");
00272
00273
00274 MsgHandler::getMessageInstance()->beginProcessMsg("Removing duplicate edges...");
00275 if (edges.size() > 1) {
00276 std::set<std::string> toRemove;
00277 for (std::map<std::string, Edge*>::iterator it = edges.begin(), itnext =++edges.begin(); itnext != edges.end(); ++it, ++itnext) {
00278 std::map<std::string, Edge*>::iterator dupEdge = find_if(itnext, edges.end(), SimilarEdge(*it));
00279 while (dupEdge != edges.end()) {
00280 MsgHandler::getMessageInstance()->inform("Found duplicate edges. Removing " + toString(dupEdge->first));
00281 toRemove.insert(dupEdge->first);
00282 dupEdge = find_if(++dupEdge, edges.end(), SimilarEdge(*it));
00283 }
00284 }
00285 for (std::set<std::string>::iterator i=toRemove.begin(); i!=toRemove.end(); ++i) {
00286 std::map<std::string, Edge*>::iterator j=edges.find(*i);
00287 delete(*j).second;
00288 edges.erase(j);
00289 }
00290 }
00291 MsgHandler::getMessageInstance()->endProcessMsg(" done.");
00292
00293
00294
00295
00296 std::map<int, int> nodeUsage;
00297
00298 for (std::map<std::string, Edge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
00299 Edge *e = (*i).second;
00300 if (!e->myCurrentIsRoad) {
00301 continue;
00302 }
00303 for (std::vector<int>::const_iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
00304 if (nodeUsage.find(*j)==nodeUsage.end()) {
00305 nodeUsage[*j] = 0;
00306 }
00307 nodeUsage[*j] = nodeUsage[*j] + 1;
00308 }
00309 }
00310
00311 for (std::map<int, NIOSMNode*>::const_iterator nodesIt = nodes.begin(); nodesIt != nodes.end(); ++nodesIt) {
00312 if (nodesIt->second->tlsControlled) {
00313
00314
00315 nodeUsage[nodesIt->first] += 1;
00316 }
00317 }
00318
00319
00320
00321 NBNodeCont &nc = nb.getNodeCont();
00322 NBEdgeCont &ec = nb.getEdgeCont();
00323 NBTrafficLightLogicCont &tlsc = nb.getTLLogicCont();
00324 for (std::map<std::string, Edge*>::iterator i=edges.begin(); i!=edges.end(); ++i) {
00325 Edge *e = (*i).second;
00326 if (!e->myCurrentIsRoad) {
00327 continue;
00328 }
00329
00330
00331
00332 NBNode *currentFrom = insertNodeChecking(*e->myCurrentNodes.begin(), nodes, nc, tlsc);
00333 NBNode *last = insertNodeChecking(*(e->myCurrentNodes.end()-1), nodes, nc, tlsc);
00334 int running = 0;
00335 std::vector<int> passed;
00336 for (std::vector<int>::iterator j=e->myCurrentNodes.begin(); j!=e->myCurrentNodes.end(); ++j) {
00337 passed.push_back(*j);
00338 if (nodeUsage[*j] > 1 && j != e->myCurrentNodes.end()-1 && j != e->myCurrentNodes.begin()) {
00339 NBNode *currentTo = insertNodeChecking(*j, nodes, nc, tlsc);
00340 insertEdge(e, running, currentFrom, currentTo, passed, nodes, nc, ec, tc);
00341 currentFrom = currentTo;
00342 running++;
00343 passed.clear();
00344 }
00345 }
00346 if (running==0) {
00347 running = -1;
00348 }
00349 insertEdge(e, running, currentFrom, last, passed, nodes, nc, ec, tc);
00350 }
00351
00352
00353 for (std::map<int, NIOSMNode*>::const_iterator i=nodes.begin(); i!=nodes.end(); ++i) {
00354 delete(*i).second;
00355 }
00356
00357 for (std::map<std::string, Edge*>::iterator i=edges.begin(); i!=edges.end(); ++i) {
00358 delete(*i).second;
00359 }
00360 }
00361
00362
00363 NBNode *
00364 NIImporter_OpenStreetMap::insertNodeChecking(int id, const std::map<int, NIOSMNode*> &osmNodes, NBNodeCont &nc,
00365 NBTrafficLightLogicCont &tlsc) throw(ProcessError) {
00366 NBNode *from = nc.retrieve(toString(id));
00367 if (from==0) {
00368 NIOSMNode *n = osmNodes.find(id)->second;
00369 Position2D pos(n->lon, n->lat);
00370 if (!GeoConvHelper::x2cartesian(pos, true, n->lon, n->lat)) {
00371 MsgHandler::getErrorInstance()->inform("Unable to project coordinates for node " + toString(id) + ".");
00372 delete from;
00373 return 0;
00374 }
00375 from = new NBNode(toString(id), pos);
00376 if (!nc.insert(from)) {
00377 MsgHandler::getErrorInstance()->inform("Could not insert node '" + toString(id) + "').");
00378 delete from;
00379 return 0;
00380 }
00381 if (n->tlsControlled) {
00382
00383
00384 NBOwnTLDef *tlDef = new NBOwnTLDef(toString(id), from);
00385 if (!tlsc.insert(tlDef)) {
00386
00387 delete tlDef;
00388 throw ProcessError("Could not allocate tls '" + toString(id) + "'.");
00389 }
00390 }
00391 }
00392 return from;
00393 }
00394
00395
00396 void
00397 NIImporter_OpenStreetMap::insertEdge(Edge *e, int index, NBNode *from, NBNode *to,
00398 const std::vector<int> &passed, const std::map<int, NIOSMNode*> &osmNodes,
00399 NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc) throw(ProcessError) {
00400
00401 std::string id = e->id;
00402 if (index>=0) {
00403 id = id + "#" + toString(index);
00404 }
00405
00406 Position2DVector shape;
00407 for (std::vector<int>::const_iterator i=passed.begin(); i!=passed.end(); ++i) {
00408 NIOSMNode *n = osmNodes.find(*i)->second;
00409 Position2D pos(n->lon, n->lat);
00410 if (!GeoConvHelper::x2cartesian(pos, true, n->lon, n->lat)) {
00411 throw ProcessError("Unable to project coordinates for edge " + id + ".");
00412 }
00413 shape.push_back_noDoublePos(pos);
00414 }
00415 if (!tc.knows(e->myHighWayType)) {
00416
00417 return;
00418 }
00419
00420 int noLanes = tc.getNoLanes(e->myHighWayType);
00421 SUMOReal speed = tc.getSpeed(e->myHighWayType);
00422 bool defaultsToOneWay = tc.getIsOneWay(e->myHighWayType);
00423 std::vector<SUMOVehicleClass> allowedClasses = tc.getAllowedClasses(e->myHighWayType);
00424 std::vector<SUMOVehicleClass> disallowedClasses = tc.getDisallowedClasses(e->myHighWayType);
00425
00426 bool addSecond = true;
00427 if (e->myIsOneWay=="true"||e->myIsOneWay=="yes"||e->myIsOneWay=="1"||(defaultsToOneWay && e->myIsOneWay!="no" && e->myIsOneWay!="false" && e->myIsOneWay!="0")) {
00428 addSecond = false;
00429 }
00430
00431 if (e->myNoLanes >= 0) {
00432 if (!addSecond) {
00433 noLanes = e->myNoLanes;
00434 } else {
00435 noLanes = e->myNoLanes / 2;
00436 }
00437 }
00438
00439 if (e->myMaxSpeed >= 0) {
00440 speed = (SUMOReal)(e->myMaxSpeed / 3.6);
00441 }
00442
00443 if (noLanes!=0&&speed!=0) {
00444 if (e->myIsOneWay!=""&&e->myIsOneWay!="false"&&e->myIsOneWay!="no"&&e->myIsOneWay!="true"&&e->myIsOneWay!="yes"&&e->myIsOneWay!="-1"&&e->myIsOneWay!="1") {
00445 WRITE_WARNING("New value for oneway found: " + e->myIsOneWay);
00446 }
00447 NBEdge::LaneSpreadFunction lsf = addSecond ? NBEdge::LANESPREAD_RIGHT : NBEdge::LANESPREAD_CENTER;
00448 if (e->myIsOneWay!="-1") {
00449 NBEdge *nbe = new NBEdge(id, from, to, e->myHighWayType, speed, noLanes, tc.getPriority(e->myHighWayType), shape, lsf);
00450 nbe->setVehicleClasses(allowedClasses, disallowedClasses);
00451 if (!ec.insert(nbe)) {
00452 delete nbe;
00453 throw ProcessError("Could not add edge '" + id + "'.");
00454 }
00455 }
00456 if (addSecond) {
00457 if (e->myIsOneWay!="-1") {
00458 id = "-" + id;
00459 }
00460 NBEdge *nbe = new NBEdge(id, to, from, e->myHighWayType, speed, noLanes, tc.getPriority(e->myHighWayType), shape.reverse(), lsf);
00461 nbe->setVehicleClasses(allowedClasses, disallowedClasses);
00462 if (!ec.insert(nbe)) {
00463 delete nbe;
00464 throw ProcessError("Could not add edge '-" + id + "'.");
00465 }
00466 }
00467 }
00468 }
00469
00470
00471
00472
00473
00474 NIImporter_OpenStreetMap::NodesHandler::NodesHandler(std::map<int, NIOSMNode*> &toFill) throw()
00475 : SUMOSAXHandler("osm - file"), myToFill(toFill), myLastNodeID(-1), myIsInValidNodeTag(false), myHierarchyLevel(0) {}
00476
00477
00478 NIImporter_OpenStreetMap::NodesHandler::~NodesHandler() throw() {}
00479
00480
00481 void
00482 NIImporter_OpenStreetMap::NodesHandler::myStartElement(SumoXMLTag element, const SUMOSAXAttributes &attrs) throw(ProcessError) {
00483 ++myHierarchyLevel;
00484 if (element == SUMO_TAG_NODE) {
00485 if (myHierarchyLevel != 2) {
00486 MsgHandler::getErrorInstance()->inform("Node element on wrong XML hierarchy level.");
00487 return;
00488 }
00489 bool ok = true;
00490 int id = attrs.getIntReporting(SUMO_ATTR_ID, "node", 0, ok);
00491 std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
00492 if (action=="delete") {
00493 return;
00494 }
00495 if (!ok) {
00496 return;
00497 }
00498 myLastNodeID = -1;
00499 if (myToFill.find(id) == myToFill.end()) {
00500 myLastNodeID = id;
00501
00502
00503 bool ok = true;
00504 double tlat, tlon;
00505 std::istringstream lon(attrs.getStringReporting(SUMO_ATTR_LON, "node", toString(id).c_str(), ok));
00506 if (!ok) {
00507 return;
00508 }
00509 lon >> tlon;
00510 if (lon.fail()) {
00511 MsgHandler::getErrorInstance()->inform("Node's '" + toString(id) + "' lon information is not numeric.");
00512 return;
00513 }
00514 std::istringstream lat(attrs.getStringReporting(SUMO_ATTR_LAT, "node", toString(id).c_str(), ok));
00515 if (!ok) {
00516 return;
00517 }
00518 lat >> tlat;
00519 if (lat.fail()) {
00520 MsgHandler::getErrorInstance()->inform("Node's '" + toString(id) + "' lat information is not numeric.");
00521 return;
00522 }
00523 NIOSMNode *toAdd = new NIOSMNode();
00524 toAdd->id = id;
00525 toAdd->tlsControlled = false;
00526 toAdd->lat = tlat;
00527 toAdd->lon = tlon;
00528 myToFill[toAdd->id] = toAdd;
00529 myIsInValidNodeTag = true;
00530 }
00531 }
00532 if (element == SUMO_TAG_TAG && myIsInValidNodeTag) {
00533 if (myHierarchyLevel != 3) {
00534 MsgHandler::getErrorInstance()->inform("Tag element on wrong XML hierarchy level.");
00535 return;
00536 }
00537 bool ok = true;
00538 std::string key = attrs.getStringReporting(SUMO_ATTR_K, "tag", toString(myLastNodeID).c_str(), ok);
00539 std::string value = attrs.getStringReporting(SUMO_ATTR_V, "tag", toString(myLastNodeID).c_str(), ok);
00540 if (!ok) {
00541 return;
00542 }
00543 if (key == "highway" && value.find("traffic_signal") != std::string::npos) {
00544 myToFill[myLastNodeID]->tlsControlled = true;
00545 }
00546 }
00547 }
00548
00549
00550 void
00551 NIImporter_OpenStreetMap::NodesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00552 if (element==SUMO_TAG_NODE && myHierarchyLevel == 2) {
00553 myLastNodeID = -1;
00554 myIsInValidNodeTag = false;
00555 }
00556 --myHierarchyLevel;
00557 }
00558
00559
00560
00561
00562
00563 NIImporter_OpenStreetMap::EdgesHandler::EdgesHandler(
00564 const std::map<int, NIOSMNode*> &osmNodes,
00565 std::map<std::string, Edge*> &toFill) throw()
00566 : SUMOSAXHandler("osm - file"),
00567 myOSMNodes(osmNodes), myEdgeMap(toFill) {
00568 }
00569
00570
00571 NIImporter_OpenStreetMap::EdgesHandler::~EdgesHandler() throw() {
00572 }
00573
00574
00575 void
00576 NIImporter_OpenStreetMap::EdgesHandler::myStartElement(SumoXMLTag element,
00577 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00578 myParentElements.push_back(element);
00579
00580 if (element==SUMO_TAG_WAY) {
00581 bool ok = true;
00582 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "way", 0, ok);
00583 std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
00584 if (action=="delete") {
00585 myCurrentEdge = 0;
00586 return;
00587 }
00588 if (!ok) {
00589 myCurrentEdge = 0;
00590 return;
00591 }
00592 myCurrentEdge = new Edge();
00593 myCurrentEdge->id = id;
00594 myCurrentEdge->myNoLanes = -1;
00595 myCurrentEdge->myMaxSpeed = -1;
00596 myCurrentEdge->myCurrentIsRoad = false;
00597 }
00598
00599 if (element==SUMO_TAG_ND) {
00600 bool ok = true;
00601 int ref = attrs.getIntReporting(SUMO_ATTR_REF, "nd", 0, ok);
00602 if (ok) {
00603 if (myOSMNodes.find(ref)==myOSMNodes.end()) {
00604 MsgHandler::getErrorInstance()->inform("The referenced geometry information (ref='" + toString(ref) + "') is not known");
00605 return;
00606 }
00607 myCurrentEdge->myCurrentNodes.push_back(ref);
00608 }
00609 }
00610
00611 if (element==SUMO_TAG_TAG&&myParentElements.size()>2&&myParentElements[myParentElements.size()-2]==SUMO_TAG_WAY) {
00612 if (myCurrentEdge==0) {
00613 return;
00614 }
00615 bool ok = true;
00616 std::string key = attrs.getStringReporting(SUMO_ATTR_K, "way", toString(myCurrentEdge->id).c_str(), ok);
00617 std::string value = attrs.getStringReporting(SUMO_ATTR_V, "way", toString(myCurrentEdge->id).c_str(), ok);
00618 if (!ok) {
00619 return;
00620 }
00621 if (key=="highway"||key=="railway") {
00622 myCurrentEdge->myHighWayType = key + "." + value;
00623 myCurrentEdge->myCurrentIsRoad = true;
00624 } else if (key=="lanes") {
00625 try {
00626 myCurrentEdge->myNoLanes = TplConvert<char>::_2int(value.c_str());
00627 } catch (NumberFormatException &) {
00628 MsgHandler::getErrorInstance()->inform("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" + myCurrentEdge->id + "'.");
00629 }
00630 } else if (key=="maxspeed") {
00631 try {
00632 myCurrentEdge->myMaxSpeed = TplConvert<char>::_2SUMOReal(value.c_str());
00633 } catch (NumberFormatException &) {
00634 WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" + myCurrentEdge->id + "'.");
00635 }
00636 } else if (key=="junction") {
00637 if ((value == "roundabout") && (myCurrentEdge->myIsOneWay == "")) {
00638 myCurrentEdge->myIsOneWay = "yes";
00639 }
00640 } else if (key=="oneway") {
00641 myCurrentEdge->myIsOneWay = value;
00642 }
00643 }
00644 }
00645
00646
00647 void
00648 NIImporter_OpenStreetMap::EdgesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00649 myParentElements.pop_back();
00650 if (element==SUMO_TAG_WAY) {
00651 if (myCurrentEdge!=0 && myCurrentEdge->myCurrentIsRoad) {
00652 myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
00653 } else {
00654 delete myCurrentEdge;
00655 }
00656 myCurrentEdge = 0;
00657 }
00658 }
00659
00660
00661
00662
00663
00664