#include <NIImporter_OpenStreetMap.h>
Definition at line 59 of file NIImporter_OpenStreetMap.h.
Static Public Member Functions | |
| static void | loadNetwork (const OptionsCont &oc, NBNetBuilder &nb) |
| Loads content of the optionally given OSM file. | |
Static Private Member Functions | |
| static void | insertEdge (Edge *e, int index, NBNode *from, NBNode *to, const std::vector< int > &passed, const std::map< int, NIOSMNode * > &osmNodes, NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc) throw (ProcessError) |
| Builds an NBEdge. | |
| static NBNode * | insertNodeChecking (int id, const std::map< int, NIOSMNode * > &osmNodes, NBNodeCont &nc, NBTrafficLightLogicCont &tlsc) throw (ProcessError) |
| Builds an NBNode. | |
Data Structures | |
| class | CompareNodesInPairs |
| Functor which compares two NIOSMNodes according to their coordinates. More... | |
| struct | Edge |
| An internal definition of a loaded edge. More... | |
| class | EdgesHandler |
| A class which extracts OSM-edges from a parsed OSM-file. More... | |
| struct | NIOSMNode |
| An internal representation of an OSM-node. More... | |
| class | NodesHandler |
| A class which extracts OSM-nodes from a parsed OSM-file. More... | |
| class | SimilarEdge |
| Functor which compares two Edges according to all values but id. More... | |
| class | SubstituteNode |
| A functor to substitute a node in the node list of an Edge. More... | |
| void NIImporter_OpenStreetMap::insertEdge | ( | Edge * | e, | |
| int | index, | |||
| NBNode * | from, | |||
| NBNode * | to, | |||
| const std::vector< int > & | passed, | |||
| const std::map< int, NIOSMNode * > & | osmNodes, | |||
| NBNodeCont & | nc, | |||
| NBEdgeCont & | ec, | |||
| NBTypeCont & | tc | |||
| ) | throw (ProcessError) [static, private] |
Builds an NBEdge.
| [in] | e | The definition of the edge |
| [in] | index | The index of the edge (in the case it is split along her nodes) |
| [in] | from | The origin node of the edge |
| [in] | to | The destination node of the edge |
| [in] | passed | The list of passed nodes (geometry information) |
| [in] | osmNodes | Container of node definitions for getting information about nodes from |
| [in] | nc | The container for built nodes |
| [in,out] | The | edge container to add the built edge to |
| [in] | tc | The type container to get information about the edge from |
| ProcessError | If the edge could not be added to the container |
Definition at line 397 of file NIImporter_OpenStreetMap.cpp.
References NBEdge::LANESPREAD_CENTER, NBEdge::LANESPREAD_RIGHT, NIImporter_OpenStreetMap::NIOSMNode::lat, NIImporter_OpenStreetMap::NIOSMNode::lon, Position2DVector::push_back_noDoublePos(), Position2DVector::reverse(), NBEdge::setVehicleClasses(), SUMOReal, toString(), WRITE_WARNING, and GeoConvHelper::x2cartesian().
Referenced by loadNetwork().
00399 { 00400 // patch the id 00401 std::string id = e->id; 00402 if (index>=0) { 00403 id = id + "#" + toString(index); 00404 } 00405 // convert the shape 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 // we do not know the type -> something else, ignore 00417 return; 00418 } 00419 // otherwise it is not an edge and will be ignored 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 // check directions 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 // if we had been able to extract the number of lanes, override the highway type default 00431 if (e->myNoLanes >= 0) { 00432 if (!addSecond) { 00433 noLanes = e->myNoLanes; 00434 } else { 00435 noLanes = e->myNoLanes / 2; 00436 } 00437 } 00438 // if we had been able to extract the maximum speed, override the highway type default 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 }
| NBNode * NIImporter_OpenStreetMap::insertNodeChecking | ( | int | id, | |
| const std::map< int, NIOSMNode * > & | osmNodes, | |||
| NBNodeCont & | nc, | |||
| NBTrafficLightLogicCont & | tlsc | |||
| ) | throw (ProcessError) [static, private] |
Builds an NBNode.
If a node with the given id is already known, nothing is done. Otherwise, the position and other information of the node is retrieved from the given node map, the node is built and added to the given node container. If the node is controlled by a tls, the according tls is built and added to the tls container.
| [in] | id | The id of the node to build |
| [in] | osmNodes | Map of node ids to information about these |
| [in,out] | nc | The node container to add the built node to |
| [in,out] | tlsc | The traffic lights logic container to add the built tls to |
| ProcessError | If the tls could not be added to the container |
Definition at line 364 of file NIImporter_OpenStreetMap.cpp.
References MsgHandler::getErrorInstance(), MsgHandler::inform(), NIImporter_OpenStreetMap::NIOSMNode::lat, NIImporter_OpenStreetMap::NIOSMNode::lon, NIImporter_OpenStreetMap::NIOSMNode::tlsControlled, toString(), and GeoConvHelper::x2cartesian().
Referenced by loadNetwork().
00365 { 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 // ok, this node is a traffic light node where no other nodes 00383 // participate 00384 NBOwnTLDef *tlDef = new NBOwnTLDef(toString(id), from); 00385 if (!tlsc.insert(tlDef)) { 00386 // actually, nothing should fail here 00387 delete tlDef; 00388 throw ProcessError("Could not allocate tls '" + toString(id) + "'."); 00389 } 00390 } 00391 } 00392 return from; 00393 }
| void NIImporter_OpenStreetMap::loadNetwork | ( | const OptionsCont & | oc, | |
| NBNetBuilder & | nb | |||
| ) | [static] |
Loads content of the optionally given OSM file.
If the option "osm-files" is set, the file(s) stored therein is read and the network definition stored therein is stored within the given network builder.
If the option "osm-files" is not set, this method simply returns.
| [in] | oc | The options to use |
| [in] | nb | The network builder to fill |
Definition at line 182 of file NIImporter_OpenStreetMap.cpp.
References MsgHandler::beginProcessMsg(), MsgHandler::endProcessMsg(), FileHelpers::exists(), NBNetBuilder::getEdgeCont(), MsgHandler::getErrorInstance(), MsgHandler::getMessageInstance(), NBNetBuilder::getNodeCont(), OptionsCont::getStringVector(), NBNetBuilder::getTLLogicCont(), NBNetBuilder::getTypeCont(), MsgHandler::inform(), NBTypeCont::insert(), insertEdge(), insertNodeChecking(), OptionsCont::isSet(), NIImporter_OpenStreetMap::Edge::myCurrentIsRoad, NIImporter_OpenStreetMap::Edge::myCurrentNodes, XMLSubSys::runParser(), GenericSAXHandler::setFileName(), SUMOReal, SVC_BICYCLE, SVC_BUS, SVC_CITYRAIL, SVC_DELIVERY, SVC_LIGHTRAIL, SVC_PEDESTRIAN, SVC_RAIL_FAST, SVC_UNKNOWN, and toString().
Referenced by NILoader::load().
00182 { 00183 // check whether the option is set (properly) 00184 if (!oc.isSet("osm-files")) { 00185 return; 00186 } 00187 // preset types 00188 // for highways 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); // !!! 130km/h? 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); // actually, maybe one lane for parking would be nice... 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); // additional 00205 tc.insert("highway.footway", 1, (SUMOReal)(30./3.6), 1, SVC_PEDESTRIAN); // additional 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); // no horse stuff 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); // additional 00213 tc.insert("highway.steps", 1, (SUMOReal)(5./3.6), 1, SVC_PEDESTRIAN); // :-) do not run too fast 00214 tc.insert("highway.stairs", 1, (SUMOReal)(5./3.6), 1, SVC_PEDESTRIAN); // additional 00215 tc.insert("highway.bus_guideway", 1, (SUMOReal)(30./3.6), 1, SVC_BUS); 00216 00217 // for railways 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); // rail stuff has to be discussed 00224 00225 00226 /* Parse file(s) 00227 * Each file is parsed twice: first for nodes, second for edges. */ 00228 std::vector<std::string> files = oc.getStringVector("osm-files"); 00229 // load nodes, first 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 // nodes 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 // load edges, then 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 // edges 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 /* Remove duplicate nodes with the same coordinates 00255 * 00256 * Without that, insertEdge can fail, if both nodes start 00257 * the shape of an edge. (NBEdge::init calls Position2DVector::push_front 00258 * with the second, which has the same coordinates as the first.) */ 00259 MsgHandler::getMessageInstance()->beginProcessMsg("Removing duplicate nodes..."); 00260 if (nodes.size() > 1) { 00261 // The algorithm compares a node (it) with the remaining part 00262 // of the list ( [itnext; end()[ ). 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 /* Remove duplicate edges with the same shape and attributes */ 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 /* Mark which nodes are used (by edges or traffic lights). 00294 * This is necessary to detect which OpenStreetMap nodes are for 00295 * geometry only */ 00296 std::map<int, int> nodeUsage; 00297 // Mark which nodes are used by edges (begin and end) 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 // Mark which nodes are used by traffic lights 00311 for (std::map<int, NIOSMNode*>::const_iterator nodesIt = nodes.begin(); nodesIt != nodes.end(); ++nodesIt) { 00312 if (nodesIt->second->tlsControlled) { 00313 // If the key is not found in the map, the value is automatically 00314 // initialized with 0. 00315 nodeUsage[nodesIt->first] += 1; 00316 } 00317 } 00318 /* Instantiate edges 00319 * Only those nodes in the middle of an edge which are used by more than 00320 * one edge are instantiated. Other nodes are considered as geometry nodes. */ 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 // build nodes; 00330 // the from- and to-nodes must be built in any case 00331 // the geometry nodes are only built if more than one edge references them 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 /* Clean up */ 00352 // delete nodes 00353 for (std::map<int, NIOSMNode*>::const_iterator i=nodes.begin(); i!=nodes.end(); ++i) { 00354 delete(*i).second; 00355 } 00356 // delete edges 00357 for (std::map<std::string, Edge*>::iterator i=edges.begin(); i!=edges.end(); ++i) { 00358 delete(*i).second; 00359 } 00360 }
1.5.6