SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIImporter_OpenStreetMap.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Importer for networks stored in OpenStreetMap format
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 #include <algorithm>
34 #include <set>
35 #include <functional>
36 #include <sstream>
37 #include <limits>
41 #include <utils/common/ToString.h>
45 #include <netbuild/NBEdge.h>
46 #include <netbuild/NBEdgeCont.h>
47 #include <netbuild/NBNode.h>
48 #include <netbuild/NBNodeCont.h>
49 #include <netbuild/NBNetBuilder.h>
50 #include <netbuild/NBOwnTLDef.h>
56 #include <utils/xml/XMLSubSys.h>
57 #include "NILoader.h"
59 
60 #ifdef CHECK_MEMORY_LEAKS
61 #include <foreign/nvwa/debug_new.h>
62 #endif // CHECK_MEMORY_LEAKS
63 
64 // ---------------------------------------------------------------------------
65 // static members
66 // ---------------------------------------------------------------------------
68 
70 
71 // ===========================================================================
72 // Private classes
73 // ===========================================================================
74 
78 public:
79  bool operator()(const Edge* e1, const Edge* e2) const {
80  if (e1->myHighWayType != e2->myHighWayType) {
81  return e1->myHighWayType > e2->myHighWayType;
82  }
83  if (e1->myNoLanes != e2->myNoLanes) {
84  return e1->myNoLanes > e2->myNoLanes;
85  }
86  if (e1->myNoLanesForward != e2->myNoLanesForward) {
87  return e1->myNoLanesForward > e2->myNoLanesForward;
88  }
89  if (e1->myMaxSpeed != e2->myMaxSpeed) {
90  return e1->myMaxSpeed > e2->myMaxSpeed;
91  }
92  if (e1->myIsOneWay != e2->myIsOneWay) {
93  return e1->myIsOneWay > e2->myIsOneWay;
94  }
95  return e1->myCurrentNodes > e2->myCurrentNodes;
96  }
97 };
98 
99 // ===========================================================================
100 // method definitions
101 // ===========================================================================
102 // ---------------------------------------------------------------------------
103 // static methods
104 // ---------------------------------------------------------------------------
106 
107 
108 void
110  NIImporter_OpenStreetMap importer;
111  importer.load(oc, nb);
112 }
113 
114 
116 
117 
119  // delete nodes
120  for (std::set<NIOSMNode*, CompareNodes>::iterator i = myUniqueNodes.begin(); i != myUniqueNodes.end(); i++) {
121  delete *i;
122  }
123  // delete edges
124  for (std::map<SUMOLong, Edge*>::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
125  delete(*i).second;
126  }
127 }
128 
129 
130 void
132  // check whether the option is set (properly)
133  if (!oc.isSet("osm-files")) {
134  return;
135  }
136  // preset types
137  // for highways
138  NBTypeCont& tc = nb.getTypeCont();
139  SUMOReal const WIDTH = NBEdge::UNSPECIFIED_WIDTH;
140  tc.insert("highway.motorway", 3, (SUMOReal)(160. / 3.6), 13, WIDTH, SVC_UNKNOWN, true);
141  tc.insert("highway.motorway_link", 1, (SUMOReal)(80. / 3.6), 12, WIDTH, SVC_UNKNOWN, true);
142  tc.insert("highway.trunk", 2, (SUMOReal)(100. / 3.6), 11, WIDTH); // !!! 130km/h?
143  tc.insert("highway.trunk_link", 1, (SUMOReal)(80. / 3.6), 10, WIDTH);
144  tc.insert("highway.primary", 2, (SUMOReal)(100. / 3.6), 9, WIDTH);
145  tc.insert("highway.primary_link", 1, (SUMOReal)(80. / 3.6), 8, WIDTH);
146  tc.insert("highway.secondary", 2, (SUMOReal)(100. / 3.6), 7, WIDTH);
147  tc.insert("highway.secondary_link", 1, (SUMOReal)(80. / 3.6), 6, WIDTH);
148  tc.insert("highway.tertiary", 1, (SUMOReal)(80. / 3.6), 6, WIDTH);
149  tc.insert("highway.tertiary_link", 1, (SUMOReal)(80. / 3.6), 5, WIDTH);
150  tc.insert("highway.unclassified", 1, (SUMOReal)(80. / 3.6), 5, WIDTH);
151  tc.insert("highway.residential", 1, (SUMOReal)(50. / 3.6), 4, WIDTH); // actually, maybe one lane for parking would be nice...
152  tc.insert("highway.living_street", 1, (SUMOReal)(10. / 3.6), 3, WIDTH);
153  tc.insert("highway.service", 1, (SUMOReal)(20. / 3.6), 2, WIDTH, SVC_DELIVERY);
154  tc.insert("highway.track", 1, (SUMOReal)(20. / 3.6), 1, WIDTH);
155  tc.insert("highway.services", 1, (SUMOReal)(30. / 3.6), 1, WIDTH);
156  tc.insert("highway.unsurfaced", 1, (SUMOReal)(30. / 3.6), 1, WIDTH); // unofficial value, used outside germany
157  tc.insert("highway.footway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN);
158  tc.insert("highway.pedestrian", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN);
159 
160  tc.insert("highway.path", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN);
161  tc.insert("highway.bridleway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_BICYCLE); // no horse stuff
162  tc.insert("highway.cycleway", 1, (SUMOReal)(20. / 3.6), 1, WIDTH, SVC_BICYCLE);
163  tc.insert("highway.footway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN);
164  tc.insert("highway.step", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional
165  tc.insert("highway.steps", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // :-) do not run too fast
166  tc.insert("highway.stairs", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional
167  tc.insert("highway.bus_guideway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_BUS);
168  tc.insert("highway.raceway", 2, (SUMOReal)(300. / 3.6), 14, WIDTH, SVC_VIP);
169  tc.insert("highway.ford", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PUBLIC_ARMY);
170 
171  // for railways
172  const bool oneWay = OptionsCont::getOptions().getBool("osm.railway.oneway-default");
173  tc.insert("railway.rail", 1, (SUMOReal)(300. / 3.6), 15, WIDTH, SVC_RAIL_FAST, oneWay);
174  tc.insert("railway.tram", 1, (SUMOReal)(100. / 3.6), 15, WIDTH, SVC_CITYRAIL, oneWay);
175  tc.insert("railway.light_rail", 1, (SUMOReal)(100. / 3.6), 15, WIDTH, SVC_LIGHTRAIL, oneWay);
176  tc.insert("railway.subway", 1, (SUMOReal)(100. / 3.6), 15, WIDTH, SVC_CITYRAIL, oneWay);
177  tc.insert("railway.preserved", 1, (SUMOReal)(100. / 3.6), 15, WIDTH, SVC_LIGHTRAIL, oneWay);
178  tc.insert("railway.monorail", 1, (SUMOReal)(300. / 3.6), 15, WIDTH, SVC_LIGHTRAIL, oneWay); // rail stuff has to be discussed
179 
180 
181  /* Parse file(s)
182  * Each file is parsed twice: first for nodes, second for edges. */
183  std::vector<std::string> files = oc.getStringVector("osm-files");
184  // load nodes, first
185  NodesHandler nodesHandler(myOSMNodes, myUniqueNodes, oc.getBool("osm.elevation"));
186  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
187  // nodes
188  if (!FileHelpers::exists(*file)) {
189  WRITE_ERROR("Could not open osm-file '" + *file + "'.");
190  return;
191  }
192  nodesHandler.setFileName(*file);
193  PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'");
194  if (!XMLSubSys::runParser(nodesHandler, *file)) {
195  return;
196  }
198  }
199  // load edges, then
200  EdgesHandler edgesHandler(myOSMNodes, myEdges);
201  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
202  // edges
203  edgesHandler.setFileName(*file);
204  PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'");
205  XMLSubSys::runParser(edgesHandler, *file);
207  }
208 
209  /* Remove duplicate edges with the same shape and attributes */
210  if (!OptionsCont::getOptions().getBool("osm.skip-duplicates-check")) {
211  PROGRESS_BEGIN_MESSAGE("Removing duplicate edges");
212  if (myEdges.size() > 1) {
213  std::set<const Edge*, CompareEdges> dupsFinder;
214  for (std::map<SUMOLong, Edge*>::iterator it = myEdges.begin(); it != myEdges.end();) {
215  if (dupsFinder.count(it->second) > 0) {
216  WRITE_MESSAGE("Found duplicate edges. Removing " + toString(it->first));
217  delete it->second;
218  myEdges.erase(it++);
219  } else {
220  dupsFinder.insert(it->second);
221  it++;
222  }
223  }
224  }
226  }
227 
228  /* Mark which nodes are used (by edges or traffic lights).
229  * This is necessary to detect which OpenStreetMap nodes are for
230  * geometry only */
231  std::map<SUMOLong, int> nodeUsage;
232  // Mark which nodes are used by edges (begin and end)
233  for (std::map<SUMOLong, Edge*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
234  Edge* e = (*i).second;
235  assert(e->myCurrentIsRoad);
236  for (std::vector<SUMOLong>::const_iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
237  if (nodeUsage.find(*j) == nodeUsage.end()) {
238  nodeUsage[*j] = 0;
239  }
240  nodeUsage[*j] = nodeUsage[*j] + 1;
241  }
242  }
243  // Mark which nodes are used by traffic lights
244  for (std::map<SUMOLong, NIOSMNode*>::const_iterator nodesIt = myOSMNodes.begin(); nodesIt != myOSMNodes.end(); ++nodesIt) {
245  if (nodesIt->second->tlsControlled) {
246  // If the key is not found in the map, the value is automatically
247  // initialized with 0.
248  nodeUsage[nodesIt->first] += 1;
249  }
250  }
251  /* Instantiate edges
252  * Only those nodes in the middle of an edge which are used by more than
253  * one edge are instantiated. Other nodes are considered as geometry nodes. */
254  NBNodeCont& nc = nb.getNodeCont();
256  for (std::map<SUMOLong, Edge*>::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
257  Edge* e = (*i).second;
258  assert(e->myCurrentIsRoad);
259  if (e->myCurrentNodes.size() < 2) {
260  WRITE_WARNING("Discarding way '" + toString(e->id) + "' because it has only " +
261  toString(e->myCurrentNodes.size()) + " node(s)");
262  continue;
263  }
264  // build nodes;
265  // - the from- and to-nodes must be built in any case
266  // - the in-between nodes are only built if more than one edge references them
267  NBNode* currentFrom = insertNodeChecking(*e->myCurrentNodes.begin(), nc, tlsc);
268  NBNode* last = insertNodeChecking(*(e->myCurrentNodes.end() - 1), nc, tlsc);
269  int running = 0;
270  std::vector<SUMOLong> passed;
271  for (std::vector<SUMOLong>::iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
272  passed.push_back(*j);
273  if (nodeUsage[*j] > 1 && j != e->myCurrentNodes.end() - 1 && j != e->myCurrentNodes.begin()) {
274  NBNode* currentTo = insertNodeChecking(*j, nc, tlsc);
275  running = insertEdge(e, running, currentFrom, currentTo, passed, nb);
276  currentFrom = currentTo;
277  passed.clear();
278  }
279  }
280  if (running == 0) {
281  running = -1;
282  }
283  insertEdge(e, running, currentFrom, last, passed, nb);
284  }
285  // load relations (after edges are built since we want to apply
286  // turn-restrictions directly to NBEdges)
287  RelationHandler relationHandler(myOSMNodes, myEdges);
288  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
289  // relations
290  relationHandler.setFileName(*file);
291  PROGRESS_BEGIN_MESSAGE("Parsing relations from osm-file '" + *file + "'");
292  XMLSubSys::runParser(relationHandler, *file);
294  }
295 }
296 
297 
298 NBNode*
300  NBNode* node = nc.retrieve(toString(id));
301  if (node == 0) {
302  NIOSMNode* n = myOSMNodes.find(id)->second;
303  Position pos(n->lon, n->lat, n->ele);
304  if (!NBNetBuilder::transformCoordinates(pos, true)) {
305  WRITE_ERROR("Unable to project coordinates for node " + toString(id) + ".");
306  return 0;
307  }
308  node = new NBNode(toString(id), pos);
309  if (!nc.insert(node)) {
310  WRITE_ERROR("Could not insert node '" + toString(id) + "').");
311  delete node;
312  return 0;
313  }
314  n->node = node;
315  if (n->tlsControlled) {
316  // ok, this node is a traffic light node where no other nodes
317  // participate
318  // @note: The OSM-community has not settled on a schema for differentiating between fixed and actuated lights
320  NBOwnTLDef* tlDef = new NBOwnTLDef(toString(id), node, 0, type);
321  if (!tlsc.insert(tlDef)) {
322  // actually, nothing should fail here
323  delete tlDef;
324  throw ProcessError("Could not allocate tls '" + toString(id) + "'.");
325  }
326  }
327  }
328  return node;
329 }
330 
331 
332 int
334  const std::vector<SUMOLong>& passed, NBNetBuilder& nb) {
335  NBNodeCont& nc = nb.getNodeCont();
336  NBEdgeCont& ec = nb.getEdgeCont();
337  NBTypeCont& tc = nb.getTypeCont();
339  // patch the id
340  std::string id = toString(e->id);
341  if (from == 0 || to == 0) {
342  WRITE_ERROR("Discarding edge " + id + " because the nodes could not be built.");
343  return index;
344  }
345  if (index >= 0) {
346  id = id + "#" + toString(index);
347  } else {
348  index = 0;
349  }
350  if (from == to) {
351  // in the special case of a looped way split again using passed
352  assert(passed.size() >= 2);
353  std::vector<SUMOLong> geom(passed);
354  geom.pop_back(); // remove to-node
355  NBNode* intermediate = insertNodeChecking(geom.back(), nc, tlsc);
356  index = insertEdge(e, index, from, intermediate, geom, nb);
357  geom.clear();
358  return insertEdge(e, index, intermediate, to, geom, nb);
359  }
360  const int newIndex = index + 1;
361 
362  // convert the shape
363  PositionVector shape;
364  for (std::vector<SUMOLong>::const_iterator i = passed.begin(); i != passed.end(); ++i) {
365  NIOSMNode* n = myOSMNodes.find(*i)->second;
366  Position pos(n->lon, n->lat, n->ele);
367  if (!NBNetBuilder::transformCoordinates(pos, true)) {
368  WRITE_ERROR("Unable to project coordinates for edge " + id + ".");
369  }
370  shape.push_back_noDoublePos(pos);
371  }
372 
373  std::string type = e->myHighWayType;
374  if (!tc.knows(type)) {
375  if (myUnusableTypes.count(type) > 0) {
376  return newIndex;
377  } else if (myKnownCompoundTypes.count(type) > 0) {
378  type = myKnownCompoundTypes[type];
379  } else {
380  // this edge has a type which does not yet exist in the TypeContainer
382  std::vector<std::string> types;
383  while (tok.hasNext()) {
384  std::string t = tok.next();
385  if (tc.knows(t)) {
386  if (std::find(types.begin(), types.end(), t) == types.end()) {
387  types.push_back(t);
388  }
389  } else if (tok.size() > 1) {
390  WRITE_WARNING("Discarding unknown compound \"" + t + "\" in type \"" + type + "\" (first occurence for edge \"" + id + "\").");
391  }
392  }
393  if (types.size() == 0) {
394  WRITE_WARNING("Discarding unusable type \"" + type + "\" (first occurence for edge \"" + id + "\").");
395  myUnusableTypes.insert(type);
396  return newIndex;
397  } else {
398  const std::string newType = joinToString(types, "|");
399  if (tc.knows(newType)) {
400  myKnownCompoundTypes[type] = newType;
401  type = newType;
402  } else if (myKnownCompoundTypes.count(newType) > 0) {
403  type = myKnownCompoundTypes[newType];
404  } else {
405  // build a new type by merging all values
406  int numLanes = 0;
407  SUMOReal maxSpeed = 0;
408  int prio = 0;
410  bool defaultIsOneWay = false;
411  SVCPermissions permissions = 0;
412  for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); it++) {
413  numLanes = MAX2(numLanes, tc.getNumLanes(*it));
414  maxSpeed = MAX2(maxSpeed, tc.getSpeed(*it));
415  prio = MAX2(prio, tc.getPriority(*it));
416  defaultIsOneWay &= tc.getIsOneWay(*it);
417  permissions |= tc.getPermissions(*it);
418  }
419  WRITE_MESSAGE("Adding new type \"" + type + "\" (first occurence for edge \"" + id + "\").");
420  tc.insert(newType, numLanes, maxSpeed, prio, permissions, width, defaultIsOneWay);
421  myKnownCompoundTypes[type] = newType;
422  type = newType;
423  }
424  }
425  }
426  }
427 
428  // otherwise it is not an edge and will be ignored
429  bool ok = true;
430  int numLanesForward = tc.getNumLanes(type);
431  int numLanesBackward = tc.getNumLanes(type);
432  SUMOReal speed = tc.getSpeed(type);
433  bool defaultsToOneWay = tc.getIsOneWay(type);
434  SVCPermissions permissions = tc.getPermissions(type);
435  // check directions
436  bool addForward = true;
437  bool addBackward = true;
438  if (e->myIsOneWay == "true" || e->myIsOneWay == "yes" || e->myIsOneWay == "1" || (defaultsToOneWay && e->myIsOneWay != "no" && e->myIsOneWay != "false" && e->myIsOneWay != "0")) {
439  addBackward = false;
440  }
441  if (e->myIsOneWay == "-1" || e->myIsOneWay == "reverse") {
442  // one-way in reversed direction of way
443  addForward = false;
444  addBackward = true;
445  }
446  if (e->myIsOneWay != "" && e->myIsOneWay != "false" && e->myIsOneWay != "no" && e->myIsOneWay != "true" && e->myIsOneWay != "yes" && e->myIsOneWay != "-1" && e->myIsOneWay != "1" && e->myIsOneWay != "reverse") {
447  WRITE_WARNING("New value for oneway found: " + e->myIsOneWay);
448  }
449  // if we had been able to extract the number of lanes, override the highway type default
450  if (e->myNoLanes > 0) {
451  if (addForward && !addBackward) {
452  numLanesForward = e->myNoLanes;
453  } else if (!addForward && addBackward) {
454  numLanesBackward = e->myNoLanes;
455  } else {
456  if (e->myNoLanesForward > 0) {
457  numLanesForward = e->myNoLanesForward;
458  } else if (e->myNoLanesForward < 0) {
459  numLanesForward = e->myNoLanes + e->myNoLanesForward;
460  } else {
461  numLanesForward = (int)std::ceil(e->myNoLanes / 2.0);
462  }
463  numLanesBackward = e->myNoLanes - numLanesForward;
464  // sometimes ways are tagged according to their physical width of a single
465  // lane but they are intended for traffic in both directions
466  numLanesForward = MAX2(1, numLanesForward);
467  numLanesBackward = MAX2(1, numLanesBackward);
468  }
469  } else if (e->myNoLanes == 0) {
470  WRITE_WARNING("Skipping edge '" + id + "' because it has zero lanes.");
471  ok = false;
472  }
473  // if we had been able to extract the maximum speed, override the type's default
474  if (e->myMaxSpeed != MAXSPEED_UNGIVEN) {
475  speed = (SUMOReal)(e->myMaxSpeed / 3.6);
476  }
477  if (speed <= 0) {
478  WRITE_WARNING("Skipping edge '" + id + "' because it has speed " + toString(speed));
479  ok = false;
480  }
481  if (ok) {
483  if (addForward) {
484  assert(numLanesForward > 0);
485  NBEdge* nbe = new NBEdge(StringUtils::escapeXML(id), from, to, type, speed, numLanesForward, tc.getPriority(type),
487  nbe->setPermissions(permissions);
488  if (!ec.insert(nbe)) {
489  delete nbe;
490  throw ProcessError("Could not add edge '" + id + "'.");
491  }
492  id = "-" + id;
493  }
494  if (addBackward) {
495  assert(numLanesBackward > 0);
496  NBEdge* nbe = new NBEdge(StringUtils::escapeXML(id), to, from, type, speed, numLanesBackward, tc.getPriority(type),
498  nbe->setPermissions(permissions);
499  if (!ec.insert(nbe)) {
500  delete nbe;
501  throw ProcessError("Could not add edge " + id + "'.");
502  }
503  }
504  }
505  return newIndex;
506 }
507 
508 
509 // ---------------------------------------------------------------------------
510 // definitions of NIImporter_OpenStreetMap::NodesHandler-methods
511 // ---------------------------------------------------------------------------
513  std::map<SUMOLong, NIOSMNode*>& toFill,
514  std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
515  bool importElevation) :
516  SUMOSAXHandler("osm - file"),
517  myToFill(toFill),
518  myLastNodeID(-1),
519  myIsInValidNodeTag(false),
520  myHierarchyLevel(0),
521  myUniqueNodes(uniqueNodes),
522  myImportElevation(importElevation)
523 { }
524 
525 
527 
528 
529 void
531  ++myHierarchyLevel;
532  if (element == SUMO_TAG_NODE) {
533  bool ok = true;
534  if (myHierarchyLevel != 2) {
535  WRITE_ERROR("Node element on wrong XML hierarchy level (id='" + toString(attrs.get<SUMOLong>(SUMO_ATTR_ID, 0, ok)) + "', level='" + toString(myHierarchyLevel) + "').");
536  return;
537  }
538  SUMOLong id = attrs.get<SUMOLong>(SUMO_ATTR_ID, 0, ok);
539  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
540  if (action == "delete") {
541  return;
542  }
543  if (!ok) {
544  return;
545  }
546  myLastNodeID = -1;
547  if (myToFill.find(id) == myToFill.end()) {
548  myLastNodeID = id;
549  // assume we are loading multiple files...
550  // ... so we won't report duplicate nodes
551  bool ok = true;
552  double tlat, tlon;
553  std::istringstream lon(attrs.get<std::string>(SUMO_ATTR_LON, toString(id).c_str(), ok));
554  if (!ok) {
555  return;
556  }
557  lon >> tlon;
558  if (lon.fail()) {
559  WRITE_ERROR("Node's '" + toString(id) + "' lon information is not numeric.");
560  return;
561  }
562  std::istringstream lat(attrs.get<std::string>(SUMO_ATTR_LAT, toString(id).c_str(), ok));
563  if (!ok) {
564  return;
565  }
566  lat >> tlat;
567  if (lat.fail()) {
568  WRITE_ERROR("Node's '" + toString(id) + "' lat information is not numeric.");
569  return;
570  }
571  NIOSMNode* toAdd = new NIOSMNode(id, tlon, tlat);
572  myIsInValidNodeTag = true;
573 
574  std::set<NIOSMNode*, CompareNodes>::iterator similarNode = myUniqueNodes.find(toAdd);
575  if (similarNode == myUniqueNodes.end()) {
576  myUniqueNodes.insert(toAdd);
577  } else {
578  delete toAdd;
579  toAdd = *similarNode;
580  WRITE_MESSAGE("Found duplicate nodes. Substituting " + toString(id) + " with " + toString(toAdd->id));
581  }
582  myToFill[id] = toAdd;
583  }
584  }
585  if (element == SUMO_TAG_TAG && myIsInValidNodeTag) {
586  if (myHierarchyLevel != 3) {
587  WRITE_ERROR("Tag element on wrong XML hierarchy level.");
588  return;
589  }
590  bool ok = true;
591  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myLastNodeID).c_str(), ok, false);
592  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myLastNodeID).c_str(), ok, false);
593  if (key == "highway" && value.find("traffic_signal") != std::string::npos) {
594  myToFill[myLastNodeID]->tlsControlled = true;
595  } else if (myImportElevation && key == "ele") {
596  try {
597  myToFill[myLastNodeID]->ele = TplConvert::_2SUMOReal(value.c_str());
598  } catch (...) {
599  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in node '" +
600  toString(myLastNodeID) + "'.");
601  }
602  }
603  }
604 }
605 
606 
607 void
609  if (element == SUMO_TAG_NODE && myHierarchyLevel == 2) {
610  myLastNodeID = -1;
611  myIsInValidNodeTag = false;
612  }
613  --myHierarchyLevel;
614 }
615 
616 
617 // ---------------------------------------------------------------------------
618 // definitions of NIImporter_OpenStreetMap::EdgesHandler-methods
619 // ---------------------------------------------------------------------------
621  const std::map<SUMOLong, NIOSMNode*>& osmNodes,
622  std::map<SUMOLong, Edge*>& toFill) :
623  SUMOSAXHandler("osm - file"),
624  myOSMNodes(osmNodes),
625  myEdgeMap(toFill) {
626  mySpeedMap["signals"] = MAXSPEED_UNGIVEN;
627  mySpeedMap["none"] = 300.;
628  mySpeedMap["no"] = 300.;
629  mySpeedMap["walk"] = 5.;
630  mySpeedMap["DE:rural"] = 100.;
631  mySpeedMap["DE:urban"] = 50.;
632  mySpeedMap["DE:living_street"] = 10.;
633 
634 }
635 
636 
638 }
639 
640 
641 void
643  const SUMOSAXAttributes& attrs) {
644  myParentElements.push_back(element);
645  // parse "way" elements
646  if (element == SUMO_TAG_WAY) {
647  bool ok = true;
648  SUMOLong id = attrs.get<SUMOLong>(SUMO_ATTR_ID, 0, ok);
649  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
650  if (action == "delete") {
651  myCurrentEdge = 0;
652  return;
653  }
654  if (!ok) {
655  myCurrentEdge = 0;
656  return;
657  }
658  myCurrentEdge = new Edge(id);
659  }
660  // parse "nd" (node) elements
661  if (element == SUMO_TAG_ND) {
662  bool ok = true;
663  SUMOLong ref = attrs.get<SUMOLong>(SUMO_ATTR_REF, 0, ok);
664  if (ok) {
665  std::map<SUMOLong, NIOSMNode*>::const_iterator node = myOSMNodes.find(ref);
666  if (node == myOSMNodes.end()) {
667  WRITE_WARNING("The referenced geometry information (ref='" + toString(ref) + "') is not known");
668  return;
669  } else {
670  ref = node->second->id; // node may have been substituted
671  if (myCurrentEdge->myCurrentNodes.size() == 0 ||
672  myCurrentEdge->myCurrentNodes.back() != ref) { // avoid consecutive duplicates
673  myCurrentEdge->myCurrentNodes.push_back(ref);
674  }
675  }
676  }
677  }
678  // parse values
679  if (element == SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] == SUMO_TAG_WAY) {
680  if (myCurrentEdge == 0) {
681  return;
682  }
683  bool ok = true;
684  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myCurrentEdge->id).c_str(), ok, false);
685  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myCurrentEdge->id).c_str(), ok, false);
686 
687  if (key == "highway" || key == "railway") {
688  if (myCurrentEdge->myHighWayType != "") {
689  // osm-ways may be used by more than one mode (eg railway.tram + highway.residential. this is relevant for multimodal traffic)
690  // we create a new type for this kind of situation which must then be resolved in insertEdge()
691  myCurrentEdge->myHighWayType = myCurrentEdge->myHighWayType + compoundTypeSeparator + key + "." + value;
692  } else {
693  myCurrentEdge->myHighWayType = key + "." + value;
694  }
695  myCurrentEdge->myCurrentIsRoad = true;
696  } else if (key == "lanes") {
697  try {
698  myCurrentEdge->myNoLanes = TplConvert::_2int(value.c_str());
699  } catch (NumberFormatException&) {
700  // might be a list of values
701  StringTokenizer st(value, ";", true);
702  std::vector<std::string> list = st.getVector();
703  if (list.size() >= 2) {
704  int minLanes = std::numeric_limits<int>::max();
705  try {
706  for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i) {
707  int numLanes = TplConvert::_2int(StringUtils::prune(*i).c_str());
708  minLanes = MIN2(minLanes, numLanes);
709  }
710  myCurrentEdge->myNoLanes = minLanes;
711  WRITE_WARNING("Using minimum lane number from list (" + value + ") for edge '" + toString(myCurrentEdge->id) + "'.");
712  } catch (NumberFormatException&) {
713  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
714  toString(myCurrentEdge->id) + "'.");
715  }
716  }
717  } catch (EmptyData&) {
718  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
719  toString(myCurrentEdge->id) + "'.");
720  }
721  } else if (key == "lanes:forward") {
722  try {
723  myCurrentEdge->myNoLanesForward = TplConvert::_2int(value.c_str());
724  } catch (...) {
725  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
726  toString(myCurrentEdge->id) + "'.");
727  }
728  } else if (key == "lanes:backward") {
729  try {
730  // denote backwards count with a negative sign
731  myCurrentEdge->myNoLanesForward = -TplConvert::_2int(value.c_str());
732  } catch (...) {
733  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
734  toString(myCurrentEdge->id) + "'.");
735  }
736  } else if (key == "maxspeed") {
737  if (mySpeedMap.find(value) != mySpeedMap.end()) {
738  myCurrentEdge->myMaxSpeed = mySpeedMap[value];
739  } else {
740  SUMOReal conversion = 1; // OSM default is km/h
741  if (StringUtils::to_lower_case(value).find("km/h") != std::string::npos) {
742  value = StringUtils::prune(value.substr(0, value.find_first_not_of("0123456789")));
743  } else if (StringUtils::to_lower_case(value).find("mph") != std::string::npos) {
744  value = StringUtils::prune(value.substr(0, value.find_first_not_of("0123456789")));
745  conversion = 1.609344; // kilometers per mile
746  }
747  try {
748  myCurrentEdge->myMaxSpeed = TplConvert::_2SUMOReal(value.c_str()) * conversion;
749  } catch (...) {
750  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
751  toString(myCurrentEdge->id) + "'.");
752  }
753  }
754  } else if (key == "junction") {
755  if ((value == "roundabout") && (myCurrentEdge->myIsOneWay == "")) {
756  myCurrentEdge->myIsOneWay = "yes";
757  }
758  } else if (key == "oneway") {
759  myCurrentEdge->myIsOneWay = value;
760  } else if (key == "name") {
761  myCurrentEdge->streetName = value;
762  } else if (key == "tracks") {
763  try {
764  if (TplConvert::_2int(value.c_str()) > 1) {
765  myCurrentEdge->myIsOneWay = "false";
766  } else {
767  myCurrentEdge->myIsOneWay = "true";
768  }
769  } catch (...) {
770  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
771  toString(myCurrentEdge->id) + "'.");
772  }
773  }
774  }
775 }
776 
777 
778 void
780  myParentElements.pop_back();
781  if (element == SUMO_TAG_WAY) {
782  if (myCurrentEdge != 0 && myCurrentEdge->myCurrentIsRoad) {
783  myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
784  } else {
785  delete myCurrentEdge;
786  }
787  myCurrentEdge = 0;
788  }
789 }
790 
791 
792 // ---------------------------------------------------------------------------
793 // definitions of NIImporter_OpenStreetMap::RelationHandler-methods
794 // ---------------------------------------------------------------------------
796  const std::map<SUMOLong, NIOSMNode*>& osmNodes,
797  const std::map<SUMOLong, Edge*>& osmEdges) :
798  SUMOSAXHandler("osm - file"),
799  myOSMNodes(osmNodes),
800  myOSMEdges(osmEdges) {
801  resetValues();
802 }
803 
804 
806 }
807 
808 void
810  myCurrentRelation = INVALID_ID;
811  myIsRestriction = false;
812  myFromWay = INVALID_ID;
813  myToWay = INVALID_ID;
814  myViaNode = INVALID_ID;
815  myViaWay = INVALID_ID;
816  myRestrictionType = RESTRICTION_UNKNOWN;
817 }
818 
819 void
821  const SUMOSAXAttributes& attrs) {
822  myParentElements.push_back(element);
823  // parse "way" elements
824  if (element == SUMO_TAG_RELATION) {
825  bool ok = true;
826  myCurrentRelation = attrs.get<SUMOLong>(SUMO_ATTR_ID, 0, ok);
827  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
828  if (action == "delete" || !ok) {
829  myCurrentRelation = INVALID_ID;
830  }
831  return;
832  } else if (myCurrentRelation == INVALID_ID) {
833  return;
834  }
835  // parse member elements
836  if (element == SUMO_TAG_MEMBER) {
837  bool ok = true;
838  std::string role = attrs.hasAttribute("role") ? attrs.getStringSecure("role", "") : "";
839  SUMOLong ref = attrs.get<SUMOLong>(SUMO_ATTR_REF, 0, ok);
840  if (role == "via") {
841  // u-turns for divided ways may be given with 2 via-nodes or 1 via-way
842  std::string memberType = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
843  if (memberType == "way" && checkEdgeRef(ref)) {
844  myViaWay = ref;
845  } else if (memberType == "node") {
846  if (myOSMNodes.find(ref) != myOSMNodes.end()) {
847  myViaNode = ref;
848  } else {
849  WRITE_WARNING("No node found for reference '" + toString(ref) + "' in relation '" + toString(myCurrentRelation) + "'");
850  }
851  }
852  } else if (role == "from" && checkEdgeRef(ref)) {
853  myFromWay = ref;
854  } else if (role == "to" && checkEdgeRef(ref)) {
855  myToWay = ref;
856  }
857  return;
858  }
859  // parse values
860  if (element == SUMO_TAG_TAG) {
861  bool ok = true;
862  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myCurrentRelation).c_str(), ok, false);
863  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myCurrentRelation).c_str(), ok, false);
864 
865  if (key == "type" && value == "restriction") {
866  myIsRestriction = true;
867  return;
868  }
869  if (key == "restriction") {
870  if (value.substr(0, 5) == "only_") {
871  myRestrictionType = RESTRICTION_ONLY;
872  } else if (value.substr(0, 3) == "no_") {
873  myRestrictionType = RESTRICTION_NO;
874  } else {
875  WRITE_WARNING("Found unknown restriction type '" + value + "' in relation '" + toString(myCurrentRelation) + "'");
876  }
877  return;
878  }
879  }
880 }
881 
882 
883 bool
885  if (myOSMEdges.find(ref) != myOSMEdges.end()) {
886  return true;
887  } else {
888  WRITE_WARNING("No way found for reference '" + toString(ref) + "' in relation '" + toString(myCurrentRelation) + "'");
889  return false;
890  }
891 }
892 
893 
894 void
896  myParentElements.pop_back();
897  if (element == SUMO_TAG_RELATION) {
898  if (myIsRestriction) {
899  assert(myCurrentRelation != INVALID_ID);
900  bool ok = true;
901  if (myRestrictionType == RESTRICTION_UNKNOWN) {
902  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown type.");
903  ok = false;
904  }
905  if (myFromWay == INVALID_ID) {
906  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown from-way.");
907  ok = false;
908  }
909  if (myToWay == INVALID_ID) {
910  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown to-way.");
911  ok = false;
912  }
913  if (myViaNode == INVALID_ID && myViaWay == INVALID_ID) {
914  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown via.");
915  ok = false;
916  }
917  if (ok && !applyRestriction()) {
918  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "'.");
919  }
920  }
921  // other relations might use similar subelements so reset in any case
922  resetValues();
923  }
924 }
925 
926 
927 bool
929  // since OSM ways are bidirectional we need the via to figure out which direction was meant
930  if (myViaNode != INVALID_ID) {
931  NBNode* viaNode = myOSMNodes.find(myViaNode)->second->node;
932  if (viaNode == 0) {
933  WRITE_WARNING("Via-node '" + toString(myViaNode) + "' was not instantiated");
934  return false;
935  }
936  NBEdge* from = findEdgeRef(myFromWay, viaNode->getIncomingEdges());
937  NBEdge* to = findEdgeRef(myToWay, viaNode->getOutgoingEdges());
938  if (from == 0) {
939  WRITE_WARNING("from-edge of restriction relation could not be determined");
940  return false;
941  }
942  if (to == 0) {
943  WRITE_WARNING("to-edge of restriction relation could not be determined");
944  return false;
945  }
946  if (myRestrictionType == RESTRICTION_ONLY) {
947  from->addEdge2EdgeConnection(to);
948  } else {
949  from->removeFromConnections(to, -1, -1, true);
950  }
951  } else {
952  // XXX interpreting via-ways or via-node lists not yet implemented
953  WRITE_WARNING("direction of restriction relation could not be determined");
954  return false;
955  }
956  return true;
957 }
958 
959 
960 NBEdge*
961 NIImporter_OpenStreetMap::RelationHandler::findEdgeRef(SUMOLong wayRef, const std::vector<NBEdge*>& candidates) const {
962  const std::string prefix = toString(wayRef);
963  const std::string backPrefix = "-" + prefix;
964  NBEdge* result = 0;
965  int found = 0;
966  for (EdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); ++it) {
967  if (((*it)->getID().substr(0, prefix.size()) == prefix) ||
968  ((*it)->getID().substr(0, backPrefix.size()) == backPrefix)) {
969  result = *it;
970  found++;
971  }
972  }
973  if (found > 1) {
974  WRITE_WARNING("Ambigous way reference '" + prefix + "' in restriction relation");
975  result = 0;
976  }
977  return result;
978 }
979 
980 
981 /****************************************************************************/
982 
NodesHandler(std::map< SUMOLong, NIOSMNode * > &toFill, std::set< NIOSMNode *, CompareNodes > &uniqueNodes, bool importElevation)
Contructor.
An internal definition of a loaded edge.
double lon
The longitude the node is located at.
An internal representation of an OSM-node.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
Definition: NBNode.h:170
double lat
The latitude the node is located at.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
vehicle is a city rail
std::string streetName
The edge's street name.
NBTypeCont & getTypeCont()
Returns the type container.
Definition: NBNetBuilder.h:170
std::map< SUMOLong, Edge * > myEdges
the map from OSM way ids to edge objects
is a pedestrian
std::string next()
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static bool transformCoordinates(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:223
A container for traffic light definitions and built programs.
bool applyRestriction() const
try to apply the parsed restriction and return whether successful
vehicle is a bicycle
void myEndElement(int element)
Called when a closing tag occurs.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:71
vehicle is a small delivery vehicle
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
bool insert(const std::string &id, int noLanes, SUMOReal maxSpeed, int prio, SUMOReal width, SUMOVehicleClass vClasses=SVC_UNKNOWN, bool oneWayIsDefault=false)
Adds a type into the list. This is a simplified convenience form of insert, if only one allowed vehic...
Definition: NBTypeCont.cpp:60
bool getIsOneWay(const std::string &type) const
Returns whether edges are one-way per default for the given type.
Definition: NBTypeCont.cpp:116
T MAX2(T a, T b)
Definition: StdDefs.h:71
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given ...
Definition: NBEdge.cpp:2065
void myEndElement(int element)
Called when a closing tag occurs.
NBNode * insertNodeChecking(SUMOLong id, NBNodeCont &nc, NBTrafficLightLogicCont &tlsc)
Builds an NBNode.
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
SAX-handler base for SUMO-files.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:114
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
SUMOReal getWidth(const std::string &type) const
Returns the lane width for the given type [m/s].
Definition: NBTypeCont.cpp:134
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
NBNode * node
the NBNode that was instantiated
PositionVector reverse() const
static const SUMOReal MAXSPEED_UNGIVEN
std::vector< SUMOLong > myCurrentNodes
The list of nodes this edge is made of.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given OSM file.
Functor which compares two Edges.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
Definition: NBNode.h:178
int myNoLanesForward
number of lanes in forward direction or 0 if unknown, negative if backwards lanes are meant ...
bool addEdge2EdgeConnection(NBEdge *dest)
Adds a connection to another edge.
Definition: NBEdge.cpp:593
#define max(a, b)
Definition: polyfonts.c:61
void load(const OptionsCont &oc, NBNetBuilder &nb)
SUMOReal getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
Definition: NBTypeCont.cpp:104
void setFileName(const std::string &name)
Sets the current file name.
A class which extracts OSM-edges from a parsed OSM-file.
double ele
The elevation of this node.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:164
vehicle is a light rail
Encapsulated SAX-Attributes.
static StringBijection< TrafficLightType > TrafficLightTypes
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
int getNumLanes(const std::string &type) const
Returns the number of lanes for the given type.
Definition: NBTypeCont.cpp:98
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
A list of positions.
army vehicles
int getPriority(const std::string &type) const
Returns the priority for the given type.
Definition: NBTypeCont.cpp:110
static bool exists(std::string path)
Checks whether the given file exists.
Definition: FileHelpers.cpp:57
void myEndElement(int element)
Called when a closing tag occurs.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
T MIN2(T a, T b)
Definition: StdDefs.h:65
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:198
#define SUMOLong
Definition: config.h:212
size_t size() const
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:80
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:828
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myMaxSpeed
maximum speed in km/h, or MAXSPEED_UNGIVEN
NBEdge * findEdgeRef(SUMOLong wayRef, const std::vector< NBEdge * > &candidates) const
try to find the way segment among candidates
std::vector< std::string > getVector()
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
int myNoLanes
number of lanes, or -1 if unknown
vehicle is a bus
static std::string to_lower_case(std::string str)
Transfers the content to lower case.
Definition: StringUtils.cpp:67
static int _2int(const E *const data)
Definition: TplConvert.h:114
bool tlsControlled
Whether this is a tls controlled junction.
std::map< std::string, std::string > myKnownCompoundTypes
The compound types that have already been mapped to other known types.
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:56
EdgesHandler(const std::map< SUMOLong, NIOSMNode * > &osmNodes, std::map< SUMOLong, Edge * > &toFill)
Constructor.
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:162
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
vip vehicles
static const std::string compoundTypeSeparator
The separator within newly created compound type names.
std::map< std::string, SUMOReal > mySpeedMap
A map of non-numeric speed descriptions to their numeric values.
RelationHandler(const std::map< SUMOLong, NIOSMNode * > &osmNodes, const std::map< SUMOLong, Edge * > &osmEdges)
Constructor.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
A storage for options typed value containers)
Definition: OptionsCont.h:108
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
NBTrafficLightLogicCont & getTLLogicCont()
Returns the traffic light logics container.
Definition: NBNetBuilder.h:178
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
A class which extracts OSM-nodes from a parsed OSM-file.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
void resetValues()
reset members to their defaults for parsing a new relation
T get(const std::string &str) const
bool checkEdgeRef(SUMOLong ref) const
check whether a referenced way has a corresponding edge
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:152
std::string myHighWayType
The type, stored in "highway" key.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
Importer for networks stored in OpenStreetMap format.
#define SUMOReal
Definition: config.h:215
int insertEdge(Edge *e, int index, NBNode *from, NBNode *to, const std::vector< SUMOLong > &passed, NBNetBuilder &nb)
Builds an NBEdge.
bool myCurrentIsRoad
Information whether this is a road.
bool operator()(const Edge *e1, const Edge *e2) const
std::set< std::string > myUnusableTypes
The compounds types that do not contain known types.
void push_back_noDoublePos(const Position &p)
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:124
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Definition: NBTypeCont.cpp:128
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:199
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
std::map< SUMOLong, NIOSMNode * > myOSMNodes
the map from OSM node ids to actual nodes
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:197
std::set< NIOSMNode *, CompareNodes > myUniqueNodes
the set of unique nodes used in NodesHandler, used when freeing memory
static const SUMOLong INVALID_ID
vehicle is a fast moving rail
A class which extracts relevant relation information from a parsed OSM-file.
std::string myIsOneWay
Information whether this is an one-way road.
TrafficLightType
A storage for available types of edges.
Definition: NBTypeCont.h:56
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.