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.dlr.de/
13 // Copyright (C) 2001-2015 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<long long int, 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  /* Parse file(s)
137  * Each file is parsed twice: first for nodes, second for edges. */
138  std::vector<std::string> files = oc.getStringVector("osm-files");
139  // load nodes, first
140  NodesHandler nodesHandler(myOSMNodes, myUniqueNodes, oc.getBool("osm.elevation"));
141  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
142  // nodes
143  if (!FileHelpers::isReadable(*file)) {
144  WRITE_ERROR("Could not open osm-file '" + *file + "'.");
145  return;
146  }
147  nodesHandler.setFileName(*file);
148  PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'");
149  if (!XMLSubSys::runParser(nodesHandler, *file)) {
150  return;
151  }
153  }
154  // load edges, then
155  EdgesHandler edgesHandler(myOSMNodes, myEdges);
156  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
157  // edges
158  edgesHandler.setFileName(*file);
159  PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'");
160  XMLSubSys::runParser(edgesHandler, *file);
162  }
163 
164  /* Remove duplicate edges with the same shape and attributes */
165  if (!oc.getBool("osm.skip-duplicates-check")) {
166  PROGRESS_BEGIN_MESSAGE("Removing duplicate edges");
167  if (myEdges.size() > 1) {
168  std::set<const Edge*, CompareEdges> dupsFinder;
169  for (std::map<long long int, Edge*>::iterator it = myEdges.begin(); it != myEdges.end();) {
170  if (dupsFinder.count(it->second) > 0) {
171  WRITE_MESSAGE("Found duplicate edges. Removing " + toString(it->first));
172  delete it->second;
173  myEdges.erase(it++);
174  } else {
175  dupsFinder.insert(it->second);
176  it++;
177  }
178  }
179  }
181  }
182 
183  /* Mark which nodes are used (by edges or traffic lights).
184  * This is necessary to detect which OpenStreetMap nodes are for
185  * geometry only */
186  std::map<long long int, int> nodeUsage;
187  // Mark which nodes are used by edges (begin and end)
188  for (std::map<long long int, Edge*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
189  Edge* e = (*i).second;
190  assert(e->myCurrentIsRoad);
191  for (std::vector<long long int>::const_iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
192  if (nodeUsage.find(*j) == nodeUsage.end()) {
193  nodeUsage[*j] = 0;
194  }
195  nodeUsage[*j] = nodeUsage[*j] + 1;
196  }
197  }
198  // Mark which nodes are used by traffic lights
199  for (std::map<long long int, NIOSMNode*>::const_iterator nodesIt = myOSMNodes.begin(); nodesIt != myOSMNodes.end(); ++nodesIt) {
200  if (nodesIt->second->tlsControlled) {
201  // If the key is not found in the map, the value is automatically
202  // initialized with 0.
203  nodeUsage[nodesIt->first] += 1;
204  }
205  }
206  /* Instantiate edges
207  * Only those nodes in the middle of an edge which are used by more than
208  * one edge are instantiated. Other nodes are considered as geometry nodes. */
209  NBNodeCont& nc = nb.getNodeCont();
211  for (std::map<long long int, Edge*>::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
212  Edge* e = (*i).second;
213  assert(e->myCurrentIsRoad);
214  if (e->myCurrentNodes.size() < 2) {
215  WRITE_WARNING("Discarding way '" + toString(e->id) + "' because it has only " +
216  toString(e->myCurrentNodes.size()) + " node(s)");
217  continue;
218  }
219  // build nodes;
220  // - the from- and to-nodes must be built in any case
221  // - the in-between nodes are only built if more than one edge references them
222  NBNode* currentFrom = insertNodeChecking(*e->myCurrentNodes.begin(), nc, tlsc);
223  NBNode* last = insertNodeChecking(*(e->myCurrentNodes.end() - 1), nc, tlsc);
224  int running = 0;
225  std::vector<long long int> passed;
226  for (std::vector<long long int>::iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
227  passed.push_back(*j);
228  if (nodeUsage[*j] > 1 && j != e->myCurrentNodes.end() - 1 && j != e->myCurrentNodes.begin()) {
229  NBNode* currentTo = insertNodeChecking(*j, nc, tlsc);
230  running = insertEdge(e, running, currentFrom, currentTo, passed, nb);
231  currentFrom = currentTo;
232  passed.clear();
233  }
234  }
235  if (running == 0) {
236  running = -1;
237  }
238  insertEdge(e, running, currentFrom, last, passed, nb);
239  }
240 
241  // load relations (after edges are built since we want to apply
242  // turn-restrictions directly to NBEdges)
243  RelationHandler relationHandler(myOSMNodes, myEdges);
244  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
245  // relations
246  relationHandler.setFileName(*file);
247  PROGRESS_BEGIN_MESSAGE("Parsing relations from osm-file '" + *file + "'");
248  XMLSubSys::runParser(relationHandler, *file);
250  }
251 }
252 
253 
254 NBNode*
256  NBNode* node = nc.retrieve(toString(id));
257  if (node == 0) {
258  NIOSMNode* n = myOSMNodes.find(id)->second;
259  Position pos(n->lon, n->lat, n->ele);
260  if (!NBNetBuilder::transformCoordinates(pos, true)) {
261  WRITE_ERROR("Unable to project coordinates for node " + toString(id) + ".");
262  return 0;
263  }
264  node = new NBNode(toString(id), pos);
265  if (!nc.insert(node)) {
266  WRITE_ERROR("Could not insert node '" + toString(id) + "').");
267  delete node;
268  return 0;
269  }
270  n->node = node;
271  if (n->tlsControlled) {
272  // ok, this node is a traffic light node where no other nodes
273  // participate
274  // @note: The OSM-community has not settled on a schema for differentiating between fixed and actuated lights
276  NBOwnTLDef* tlDef = new NBOwnTLDef(toString(id), node, 0, type);
277  if (!tlsc.insert(tlDef)) {
278  // actually, nothing should fail here
279  delete tlDef;
280  throw ProcessError("Could not allocate tls '" + toString(id) + "'.");
281  }
282  }
283  }
284  return node;
285 }
286 
287 
288 int
290  const std::vector<long long int>& passed, NBNetBuilder& nb) {
291  NBNodeCont& nc = nb.getNodeCont();
292  NBEdgeCont& ec = nb.getEdgeCont();
293  NBTypeCont& tc = nb.getTypeCont();
295  // patch the id
296  std::string id = toString(e->id);
297  if (from == 0 || to == 0) {
298  WRITE_ERROR("Discarding edge " + id + " because the nodes could not be built.");
299  return index;
300  }
301  if (index >= 0) {
302  id = id + "#" + toString(index);
303  } else {
304  index = 0;
305  }
306  if (from == to) {
307  // in the special case of a looped way split again using passed
308  assert(passed.size() >= 2);
309  std::vector<long long int> geom(passed);
310  geom.pop_back(); // remove to-node
311  NBNode* intermediate = insertNodeChecking(geom.back(), nc, tlsc);
312  index = insertEdge(e, index, from, intermediate, geom, nb);
313  geom.clear();
314  return insertEdge(e, index, intermediate, to, geom, nb);
315  }
316  const int newIndex = index + 1;
317 
318  // convert the shape
319  PositionVector shape;
320  shape.push_back(from->getPosition());
321  for (std::vector<long long int>::const_iterator i = passed.begin(); i != passed.end(); ++i) {
322  NIOSMNode* n = myOSMNodes.find(*i)->second;
323  Position pos(n->lon, n->lat, n->ele);
324  if (!NBNetBuilder::transformCoordinates(pos, true)) {
325  WRITE_ERROR("Unable to project coordinates for edge " + id + ".");
326  }
327  shape.push_back_noDoublePos(pos);
328  }
329  shape.push_back_noDoublePos(to->getPosition());
330 
331  std::string type = e->myHighWayType;
332  if (!tc.knows(type)) {
333  if (myUnusableTypes.count(type) > 0) {
334  return newIndex;
335  } else if (myKnownCompoundTypes.count(type) > 0) {
336  type = myKnownCompoundTypes[type];
337  } else {
338  // this edge has a type which does not yet exist in the TypeContainer
340  std::vector<std::string> types;
341  while (tok.hasNext()) {
342  std::string t = tok.next();
343  if (tc.knows(t)) {
344  if (std::find(types.begin(), types.end(), t) == types.end()) {
345  types.push_back(t);
346  }
347  } else if (tok.size() > 1) {
348  WRITE_WARNING("Discarding unknown compound \"" + t + "\" in type \"" + type + "\" (first occurence for edge \"" + id + "\").");
349  }
350  }
351  if (types.size() == 0) {
352  WRITE_WARNING("Discarding unusable type \"" + type + "\" (first occurence for edge \"" + id + "\").");
353  myUnusableTypes.insert(type);
354  return newIndex;
355  } else {
356  const std::string newType = joinToString(types, "|");
357  if (tc.knows(newType)) {
358  myKnownCompoundTypes[type] = newType;
359  type = newType;
360  } else if (myKnownCompoundTypes.count(newType) > 0) {
361  type = myKnownCompoundTypes[newType];
362  } else {
363  // build a new type by merging all values
364  int numLanes = 0;
365  SUMOReal maxSpeed = 0;
366  int prio = 0;
368  SUMOReal sidewalkWidth = NBEdge::UNSPECIFIED_WIDTH;
369  SUMOReal bikelaneWidth = NBEdge::UNSPECIFIED_WIDTH;
370  bool defaultIsOneWay = false;
371  SVCPermissions permissions = 0;
372  bool discard = true;
373  for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); it++) {
374  if (!tc.getShallBeDiscarded(*it)) {
375  numLanes = MAX2(numLanes, tc.getNumLanes(*it));
376  maxSpeed = MAX2(maxSpeed, tc.getSpeed(*it));
377  prio = MAX2(prio, tc.getPriority(*it));
378  defaultIsOneWay &= tc.getIsOneWay(*it);
379  permissions |= tc.getPermissions(*it);
380  width = MAX2(width, tc.getWidth(*it));
381  sidewalkWidth = MAX2(sidewalkWidth, tc.getSidewalkWidth(*it));
382  bikelaneWidth = MAX2(bikelaneWidth, tc.getBikeLaneWidth(*it));
383  discard = false;
384  }
385  }
386  if (width != NBEdge::UNSPECIFIED_WIDTH) {
387  width = MAX2(width, SUMO_const_laneWidth);
388  }
389  if (discard) {
390  WRITE_WARNING("Discarding compound type \"" + newType + "\" (first occurence for edge \"" + id + "\").");
391  myUnusableTypes.insert(newType);
392  return newIndex;
393  } else {
394  WRITE_MESSAGE("Adding new type \"" + type + "\" (first occurence for edge \"" + id + "\").");
395  tc.insert(newType, numLanes, maxSpeed, prio, permissions, width, defaultIsOneWay, sidewalkWidth, bikelaneWidth);
396  for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); it++) {
397  if (!tc.getShallBeDiscarded(*it)) {
398  tc.copyRestrictionsAndAttrs(*it, newType);
399  }
400  }
401  myKnownCompoundTypes[type] = newType;
402  type = newType;
403  }
404  }
405  }
406  }
407  }
408 
409  // otherwise it is not an edge and will be ignored
410  bool ok = true;
411  int numLanesForward = tc.getNumLanes(type);
412  int numLanesBackward = tc.getNumLanes(type);
413  SUMOReal speed = tc.getSpeed(type);
414  bool defaultsToOneWay = tc.getIsOneWay(type);
415  SVCPermissions forwardPermissions = tc.getPermissions(type);
416  SVCPermissions backwardPermissions = tc.getPermissions(type);
417  SUMOReal forwardWidth = tc.getWidth(type);
418  SUMOReal backwardWidth = tc.getWidth(type);
419  const bool addSidewalk = (tc.getSidewalkWidth(type) != NBEdge::UNSPECIFIED_WIDTH);
420  const bool addBikeLane = (tc.getBikeLaneWidth(type) != NBEdge::UNSPECIFIED_WIDTH);
421  // check directions
422  bool addForward = true;
423  bool addBackward = true;
424  if (e->myIsOneWay == "true" || e->myIsOneWay == "yes" || e->myIsOneWay == "1" || (defaultsToOneWay && e->myIsOneWay != "no" && e->myIsOneWay != "false" && e->myIsOneWay != "0")) {
425  addBackward = false;
426  }
427  if (e->myIsOneWay == "-1" || e->myIsOneWay == "reverse") {
428  // one-way in reversed direction of way
429  addForward = false;
430  addBackward = true;
431  }
432  if (e->myIsOneWay != "" && e->myIsOneWay != "false" && e->myIsOneWay != "no" && e->myIsOneWay != "true" && e->myIsOneWay != "yes" && e->myIsOneWay != "-1" && e->myIsOneWay != "1" && e->myIsOneWay != "reverse") {
433  WRITE_WARNING("New value for oneway found: " + e->myIsOneWay);
434  }
435  // if we had been able to extract the number of lanes, override the highway type default
436  if (e->myNoLanes > 0) {
437  if (addForward && !addBackward) {
438  numLanesForward = e->myNoLanes;
439  } else if (!addForward && addBackward) {
440  numLanesBackward = e->myNoLanes;
441  } else {
442  if (e->myNoLanesForward > 0) {
443  numLanesForward = e->myNoLanesForward;
444  } else if (e->myNoLanesForward < 0) {
445  numLanesForward = e->myNoLanes + e->myNoLanesForward;
446  } else {
447  numLanesForward = (int)std::ceil(e->myNoLanes / 2.0);
448  }
449  numLanesBackward = e->myNoLanes - numLanesForward;
450  // sometimes ways are tagged according to their physical width of a single
451  // lane but they are intended for traffic in both directions
452  numLanesForward = MAX2(1, numLanesForward);
453  numLanesBackward = MAX2(1, numLanesBackward);
454  }
455  } else if (e->myNoLanes == 0) {
456  WRITE_WARNING("Skipping edge '" + id + "' because it has zero lanes.");
457  ok = false;
458  }
459  // if we had been able to extract the maximum speed, override the type's default
460  if (e->myMaxSpeed != MAXSPEED_UNGIVEN) {
461  speed = (SUMOReal)(e->myMaxSpeed / 3.6);
462  }
463  if (speed <= 0) {
464  WRITE_WARNING("Skipping edge '" + id + "' because it has speed " + toString(speed));
465  ok = false;
466  }
467  // deal with cycleways that run in the opposite direction of a one-way street
468  if (addBikeLane) {
469  if (!addForward && (e->myCyclewayType & WAY_FORWARD) != 0) {
470  addForward = true;
471  forwardPermissions = SVC_BICYCLE;
472  forwardWidth = tc.getBikeLaneWidth(type);
473  numLanesForward = 1;
474  // do not add an additional cycle lane
476  }
477  if (!addBackward && (e->myCyclewayType & WAY_BACKWARD) != 0) {
478  addBackward = true;
479  backwardPermissions = SVC_BICYCLE;
480  backwardWidth = tc.getBikeLaneWidth(type);
481  numLanesBackward = 1;
482  // do not add an additional cycle lane
484  }
485  }
486  // deal with busways that run in the opposite direction of a one-way street
487  if (!addForward && (e->myBuswayType & WAY_FORWARD) != 0) {
488  addForward = true;
489  forwardPermissions = SVC_BUS;
490  numLanesForward = 1;
491  }
492  if (!addBackward && (e->myBuswayType & WAY_BACKWARD) != 0) {
493  addBackward = true;
494  backwardPermissions = SVC_BUS;
495  numLanesBackward = 1;
496  }
497 
498  if (ok) {
500  if (addForward) {
501  assert(numLanesForward > 0);
502  NBEdge* nbe = new NBEdge(StringUtils::escapeXML(id), from, to, type, speed, numLanesForward, tc.getPriority(type),
503  forwardWidth, NBEdge::UNSPECIFIED_OFFSET, shape, StringUtils::escapeXML(e->streetName), lsf, true);
504  nbe->setPermissions(forwardPermissions);
505  if ((e->myBuswayType & WAY_FORWARD) != 0) {
506  nbe->setPermissions(SVC_BUS, 0);
507  }
508  if (addBikeLane && (e->myCyclewayType == WAY_UNKNOWN || (e->myCyclewayType & WAY_FORWARD) != 0)) {
509  nbe->addBikeLane(tc.getBikeLaneWidth(type));
510  }
511  if (addSidewalk) {
512  nbe->addSidewalk(tc.getSidewalkWidth(type));
513  }
514  if (!ec.insert(nbe)) {
515  delete nbe;
516  throw ProcessError("Could not add edge '" + id + "'.");
517  }
518  id = "-" + id;
519  }
520  if (addBackward) {
521  assert(numLanesBackward > 0);
522  NBEdge* nbe = new NBEdge(StringUtils::escapeXML(id), to, from, type, speed, numLanesBackward, tc.getPriority(type),
523  backwardWidth, NBEdge::UNSPECIFIED_OFFSET, shape.reverse(), StringUtils::escapeXML(e->streetName), lsf, true);
524  nbe->setPermissions(backwardPermissions);
525  if ((e->myBuswayType & WAY_BACKWARD) != 0) {
526  nbe->setPermissions(SVC_BUS, 0);
527  }
528  if (addBikeLane && (e->myCyclewayType == WAY_UNKNOWN || (e->myCyclewayType & WAY_BACKWARD) != 0)) {
529  nbe->addBikeLane(tc.getBikeLaneWidth(type));
530  }
531  if (addSidewalk) {
532  nbe->addSidewalk(tc.getSidewalkWidth(type));
533  }
534  if (!ec.insert(nbe)) {
535  delete nbe;
536  throw ProcessError("Could not add edge " + id + "'.");
537  }
538  }
539  }
540  return newIndex;
541 }
542 
543 
544 // ---------------------------------------------------------------------------
545 // definitions of NIImporter_OpenStreetMap::NodesHandler-methods
546 // ---------------------------------------------------------------------------
548  std::map<long long int, NIOSMNode*>& toFill,
549  std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
550  bool importElevation) :
551  SUMOSAXHandler("osm - file"),
552  myToFill(toFill),
553  myLastNodeID(-1),
554  myIsInValidNodeTag(false),
555  myHierarchyLevel(0),
556  myUniqueNodes(uniqueNodes),
557  myImportElevation(importElevation)
558 { }
559 
560 
562 
563 
564 void
566  ++myHierarchyLevel;
567  if (element == SUMO_TAG_NODE) {
568  bool ok = true;
569  if (myHierarchyLevel != 2) {
570  WRITE_ERROR("Node element on wrong XML hierarchy level (id='" + toString(attrs.get<long long int>(SUMO_ATTR_ID, 0, ok)) + "', level='" + toString(myHierarchyLevel) + "').");
571  return;
572  }
573  long long int id = attrs.get<long long int>(SUMO_ATTR_ID, 0, ok);
574  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
575  if (action == "delete") {
576  return;
577  }
578  if (!ok) {
579  return;
580  }
581  myLastNodeID = -1;
582  if (myToFill.find(id) == myToFill.end()) {
583  myLastNodeID = id;
584  // assume we are loading multiple files...
585  // ... so we won't report duplicate nodes
586  bool ok = true;
587  double tlat, tlon;
588  std::istringstream lon(attrs.get<std::string>(SUMO_ATTR_LON, toString(id).c_str(), ok));
589  if (!ok) {
590  return;
591  }
592  lon >> tlon;
593  if (lon.fail()) {
594  WRITE_ERROR("Node's '" + toString(id) + "' lon information is not numeric.");
595  return;
596  }
597  std::istringstream lat(attrs.get<std::string>(SUMO_ATTR_LAT, toString(id).c_str(), ok));
598  if (!ok) {
599  return;
600  }
601  lat >> tlat;
602  if (lat.fail()) {
603  WRITE_ERROR("Node's '" + toString(id) + "' lat information is not numeric.");
604  return;
605  }
606  NIOSMNode* toAdd = new NIOSMNode(id, tlon, tlat);
607  myIsInValidNodeTag = true;
608 
609  std::set<NIOSMNode*, CompareNodes>::iterator similarNode = myUniqueNodes.find(toAdd);
610  if (similarNode == myUniqueNodes.end()) {
611  myUniqueNodes.insert(toAdd);
612  } else {
613  delete toAdd;
614  toAdd = *similarNode;
615  WRITE_MESSAGE("Found duplicate nodes. Substituting " + toString(id) + " with " + toString(toAdd->id));
616  }
617  myToFill[id] = toAdd;
618  }
619  }
620  if (element == SUMO_TAG_TAG && myIsInValidNodeTag) {
621  if (myHierarchyLevel != 3) {
622  WRITE_ERROR("Tag element on wrong XML hierarchy level.");
623  return;
624  }
625  bool ok = true;
626  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myLastNodeID).c_str(), ok, false);
627  // we check whether the key is relevant (and we really need to transcode the value) to avoid hitting #1636
628  if (key == "highway" || key == "ele" || key == "crossing") {
629  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myLastNodeID).c_str(), ok, false);
630  if (key == "highway" && value.find("traffic_signal") != std::string::npos) {
631  myToFill[myLastNodeID]->tlsControlled = true;
632  } else if (key == "crossing" && value.find("traffic_signals") != std::string::npos) {
633  myToFill[myLastNodeID]->tlsControlled = true;
634  } else if (myImportElevation && key == "ele") {
635  try {
636  myToFill[myLastNodeID]->ele = TplConvert::_2SUMOReal(value.c_str());
637  } catch (...) {
638  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in node '" +
639  toString(myLastNodeID) + "'.");
640  }
641  }
642  }
643  }
644 }
645 
646 
647 void
649  if (element == SUMO_TAG_NODE && myHierarchyLevel == 2) {
650  myLastNodeID = -1;
651  myIsInValidNodeTag = false;
652  }
653  --myHierarchyLevel;
654 }
655 
656 
657 // ---------------------------------------------------------------------------
658 // definitions of NIImporter_OpenStreetMap::EdgesHandler-methods
659 // ---------------------------------------------------------------------------
661  const std::map<long long int, NIOSMNode*>& osmNodes,
662  std::map<long long int, Edge*>& toFill) :
663  SUMOSAXHandler("osm - file"),
664  myOSMNodes(osmNodes),
665  myEdgeMap(toFill) {
666  mySpeedMap["signals"] = MAXSPEED_UNGIVEN;
667  mySpeedMap["none"] = 300.;
668  mySpeedMap["no"] = 300.;
669  mySpeedMap["walk"] = 5.;
670  mySpeedMap["DE:rural"] = 100.;
671  mySpeedMap["DE:urban"] = 50.;
672  mySpeedMap["DE:living_street"] = 10.;
673 
674 }
675 
676 
678 }
679 
680 
681 void
683  const SUMOSAXAttributes& attrs) {
684  myParentElements.push_back(element);
685  // parse "way" elements
686  if (element == SUMO_TAG_WAY) {
687  bool ok = true;
688  long long int id = attrs.get<long long int>(SUMO_ATTR_ID, 0, ok);
689  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
690  if (action == "delete") {
691  myCurrentEdge = 0;
692  return;
693  }
694  if (!ok) {
695  myCurrentEdge = 0;
696  return;
697  }
698  myCurrentEdge = new Edge(id);
699  }
700  // parse "nd" (node) elements
701  if (element == SUMO_TAG_ND) {
702  bool ok = true;
703  long long int ref = attrs.get<long long int>(SUMO_ATTR_REF, 0, ok);
704  if (ok) {
705  std::map<long long int, NIOSMNode*>::const_iterator node = myOSMNodes.find(ref);
706  if (node == myOSMNodes.end()) {
707  WRITE_WARNING("The referenced geometry information (ref='" + toString(ref) + "') is not known");
708  return;
709  } else {
710  ref = node->second->id; // node may have been substituted
711  if (myCurrentEdge->myCurrentNodes.size() == 0 ||
712  myCurrentEdge->myCurrentNodes.back() != ref) { // avoid consecutive duplicates
713  myCurrentEdge->myCurrentNodes.push_back(ref);
714  }
715  }
716  }
717  }
718  // parse values
719  if (element == SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] == SUMO_TAG_WAY) {
720  if (myCurrentEdge == 0) {
721  return;
722  }
723  bool ok = true;
724  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myCurrentEdge->id).c_str(), ok, false);
725  if (key.size() > 8 && StringUtils::startsWith(key, "cycleway:")) {
726  // handle special busway keys
727  const std::string cyclewaySpec = key.substr(9);
728  key = "cycleway";
729  if (cyclewaySpec == "right") {
730  myCurrentEdge->myCyclewayType = (WayType)(myCurrentEdge->myCyclewayType | WAY_FORWARD);
731  } else if (cyclewaySpec == "left") {
732  myCurrentEdge->myCyclewayType = (WayType)(myCurrentEdge->myCyclewayType | WAY_BACKWARD);
733  } else if (cyclewaySpec == "both") {
734  myCurrentEdge->myCyclewayType = (WayType)(myCurrentEdge->myCyclewayType | WAY_BOTH);
735  } else {
736  key = "ignore";
737  }
738  if ((myCurrentEdge->myCyclewayType & WAY_BOTH) != 0) {
739  // now we have some info on directionality
740  myCurrentEdge->myCyclewayType = (WayType)(myCurrentEdge->myCyclewayType & !WAY_UNKNOWN);
741  }
742  } else if (key.size() > 6 && StringUtils::startsWith(key, "busway:")) {
743  // handle special busway keys
744  const std::string buswaySpec = key.substr(7);
745  key = "busway";
746  if (buswaySpec == "right") {
747  myCurrentEdge->myBuswayType = (WayType)(myCurrentEdge->myBuswayType | WAY_FORWARD);
748  } else if (buswaySpec == "left") {
749  myCurrentEdge->myBuswayType = (WayType)(myCurrentEdge->myBuswayType | WAY_BACKWARD);
750  } else if (buswaySpec == "both") {
751  myCurrentEdge->myBuswayType = (WayType)(myCurrentEdge->myBuswayType | WAY_BOTH);
752  } else {
753  key = "ignore";
754  }
755  }
756 
757  // we check whether the key is relevant (and we really need to transcode the value) to avoid hitting #1636
758  if (!StringUtils::endsWith(key, "way") && !StringUtils::startsWith(key, "lanes") && key != "maxspeed" && key != "junction" && key != "name" && key != "tracks") {
759  return;
760  }
761  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myCurrentEdge->id).c_str(), ok, false);
762 
763  if (key == "highway" || key == "railway" || key == "waterway" || key == "cycleway" || key == "busway") {
764  myCurrentEdge->myCurrentIsRoad = true;
765  // special cycleway stuff
766  if (key == "cycleway") {
767  if (value == "no") {
768  return;
769  } else if (value == "opposite_track") {
770  myCurrentEdge->myCyclewayType = WAY_BACKWARD;
771  } else if (value == "opposite_lane") {
772  myCurrentEdge->myCyclewayType = WAY_BACKWARD;
773  }
774  }
775  // special busway stuff
776  if (key == "busway") {
777  if (value == "no") {
778  return;
779  } else if (value == "opposite_track") {
780  myCurrentEdge->myBuswayType = WAY_BACKWARD;
781  } else if (value == "opposite_lane") {
782  myCurrentEdge->myBuswayType = WAY_BACKWARD;
783  }
784  // no need to extend the type id
785  return;
786  }
787  // build type id
788  const std::string singleTypeID = key + "." + value;
789  if (myCurrentEdge->myHighWayType != "") {
790  // osm-ways may be used by more than one mode (eg railway.tram + highway.residential. this is relevant for multimodal traffic)
791  // we create a new type for this kind of situation which must then be resolved in insertEdge()
792  std::vector<std::string> types = StringTokenizer(myCurrentEdge->myHighWayType, compoundTypeSeparator).getVector();
793  types.push_back(singleTypeID);
794  myCurrentEdge->myHighWayType = joinToStringSorting(types, compoundTypeSeparator);
795  } else {
796  myCurrentEdge->myHighWayType = singleTypeID;
797  }
798  } else if (key == "lanes") {
799  try {
800  myCurrentEdge->myNoLanes = TplConvert::_2int(value.c_str());
801  } catch (NumberFormatException&) {
802  // might be a list of values
803  StringTokenizer st(value, ";", true);
804  std::vector<std::string> list = st.getVector();
805  if (list.size() >= 2) {
806  int minLanes = std::numeric_limits<int>::max();
807  try {
808  for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i) {
809  int numLanes = TplConvert::_2int(StringUtils::prune(*i).c_str());
810  minLanes = MIN2(minLanes, numLanes);
811  }
812  myCurrentEdge->myNoLanes = minLanes;
813  WRITE_WARNING("Using minimum lane number from list (" + value + ") for edge '" + toString(myCurrentEdge->id) + "'.");
814  } catch (NumberFormatException&) {
815  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
816  toString(myCurrentEdge->id) + "'.");
817  }
818  }
819  } catch (EmptyData&) {
820  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
821  toString(myCurrentEdge->id) + "'.");
822  }
823  } else if (key == "lanes:forward") {
824  try {
825  myCurrentEdge->myNoLanesForward = TplConvert::_2int(value.c_str());
826  } catch (...) {
827  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
828  toString(myCurrentEdge->id) + "'.");
829  }
830  } else if (key == "lanes:backward") {
831  try {
832  // denote backwards count with a negative sign
833  myCurrentEdge->myNoLanesForward = -TplConvert::_2int(value.c_str());
834  } catch (...) {
835  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
836  toString(myCurrentEdge->id) + "'.");
837  }
838  } else if (key == "maxspeed") {
839  if (mySpeedMap.find(value) != mySpeedMap.end()) {
840  myCurrentEdge->myMaxSpeed = mySpeedMap[value];
841  } else {
842  SUMOReal conversion = 1; // OSM default is km/h
843  if (StringUtils::to_lower_case(value).find("km/h") != std::string::npos) {
844  value = StringUtils::prune(value.substr(0, value.find_first_not_of("0123456789")));
845  } else if (StringUtils::to_lower_case(value).find("mph") != std::string::npos) {
846  value = StringUtils::prune(value.substr(0, value.find_first_not_of("0123456789")));
847  conversion = 1.609344; // kilometers per mile
848  }
849  try {
850  myCurrentEdge->myMaxSpeed = TplConvert::_2SUMOReal(value.c_str()) * conversion;
851  } catch (...) {
852  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
853  toString(myCurrentEdge->id) + "'.");
854  }
855  }
856  } else if (key == "junction") {
857  if ((value == "roundabout") && (myCurrentEdge->myIsOneWay == "")) {
858  myCurrentEdge->myIsOneWay = "yes";
859  }
860  } else if (key == "oneway") {
861  myCurrentEdge->myIsOneWay = value;
862  } else if (key == "name") {
863  myCurrentEdge->streetName = value;
864  } else if (key == "tracks") {
865  try {
866  if (TplConvert::_2int(value.c_str()) > 1) {
867  myCurrentEdge->myIsOneWay = "false";
868  } else {
869  myCurrentEdge->myIsOneWay = "true";
870  }
871  } catch (...) {
872  WRITE_WARNING("Value of key '" + key + "' is not numeric ('" + value + "') in edge '" +
873  toString(myCurrentEdge->id) + "'.");
874  }
875  }
876  }
877 }
878 
879 
880 void
882  myParentElements.pop_back();
883  if (element == SUMO_TAG_WAY) {
884  if (myCurrentEdge != 0 && myCurrentEdge->myCurrentIsRoad) {
885  myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
886  } else {
887  delete myCurrentEdge;
888  }
889  myCurrentEdge = 0;
890  }
891 }
892 
893 
894 // ---------------------------------------------------------------------------
895 // definitions of NIImporter_OpenStreetMap::RelationHandler-methods
896 // ---------------------------------------------------------------------------
898  const std::map<long long int, NIOSMNode*>& osmNodes,
899  const std::map<long long int, Edge*>& osmEdges) :
900  SUMOSAXHandler("osm - file"),
901  myOSMNodes(osmNodes),
902  myOSMEdges(osmEdges) {
903  resetValues();
904 }
905 
906 
908 }
909 
910 void
912  myCurrentRelation = INVALID_ID;
913  myIsRestriction = false;
914  myFromWay = INVALID_ID;
915  myToWay = INVALID_ID;
916  myViaNode = INVALID_ID;
917  myViaWay = INVALID_ID;
918  myRestrictionType = RESTRICTION_UNKNOWN;
919 }
920 
921 void
923  const SUMOSAXAttributes& attrs) {
924  myParentElements.push_back(element);
925  // parse "way" elements
926  if (element == SUMO_TAG_RELATION) {
927  bool ok = true;
928  myCurrentRelation = attrs.get<long long int>(SUMO_ATTR_ID, 0, ok);
929  std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
930  if (action == "delete" || !ok) {
931  myCurrentRelation = INVALID_ID;
932  }
933  return;
934  } else if (myCurrentRelation == INVALID_ID) {
935  return;
936  }
937  // parse member elements
938  if (element == SUMO_TAG_MEMBER) {
939  bool ok = true;
940  std::string role = attrs.hasAttribute("role") ? attrs.getStringSecure("role", "") : "";
941  long long int ref = attrs.get<long long int>(SUMO_ATTR_REF, 0, ok);
942  if (role == "via") {
943  // u-turns for divided ways may be given with 2 via-nodes or 1 via-way
944  std::string memberType = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
945  if (memberType == "way" && checkEdgeRef(ref)) {
946  myViaWay = ref;
947  } else if (memberType == "node") {
948  if (myOSMNodes.find(ref) != myOSMNodes.end()) {
949  myViaNode = ref;
950  } else {
951  WRITE_WARNING("No node found for reference '" + toString(ref) + "' in relation '" + toString(myCurrentRelation) + "'");
952  }
953  }
954  } else if (role == "from" && checkEdgeRef(ref)) {
955  myFromWay = ref;
956  } else if (role == "to" && checkEdgeRef(ref)) {
957  myToWay = ref;
958  }
959  return;
960  }
961  // parse values
962  if (element == SUMO_TAG_TAG) {
963  bool ok = true;
964  std::string key = attrs.get<std::string>(SUMO_ATTR_K, toString(myCurrentRelation).c_str(), ok, false);
965  // we check whether the key is relevant (and we really need to transcode the value) to avoid hitting #1636
966  if (key == "type" || key == "restriction") {
967  std::string value = attrs.get<std::string>(SUMO_ATTR_V, toString(myCurrentRelation).c_str(), ok, false);
968  if (key == "type" && value == "restriction") {
969  myIsRestriction = true;
970  return;
971  }
972  if (key == "restriction") {
973  // @note: the 'right/left/straight' part is ignored since the information is
974  // redundantly encoded in the 'from', 'to' and 'via' members
975  if (value.substr(0, 5) == "only_") {
976  myRestrictionType = RESTRICTION_ONLY;
977  } else if (value.substr(0, 3) == "no_") {
978  myRestrictionType = RESTRICTION_NO;
979  } else {
980  WRITE_WARNING("Found unknown restriction type '" + value + "' in relation '" + toString(myCurrentRelation) + "'");
981  }
982  return;
983  }
984  }
985  }
986 }
987 
988 
989 bool
991  if (myOSMEdges.find(ref) != myOSMEdges.end()) {
992  return true;
993  } else {
994  WRITE_WARNING("No way found for reference '" + toString(ref) + "' in relation '" + toString(myCurrentRelation) + "'");
995  return false;
996  }
997 }
998 
999 
1000 void
1002  myParentElements.pop_back();
1003  if (element == SUMO_TAG_RELATION) {
1004  if (myIsRestriction) {
1005  assert(myCurrentRelation != INVALID_ID);
1006  bool ok = true;
1007  if (myRestrictionType == RESTRICTION_UNKNOWN) {
1008  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown type.");
1009  ok = false;
1010  }
1011  if (myFromWay == INVALID_ID) {
1012  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown from-way.");
1013  ok = false;
1014  }
1015  if (myToWay == INVALID_ID) {
1016  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown to-way.");
1017  ok = false;
1018  }
1019  if (myViaNode == INVALID_ID && myViaWay == INVALID_ID) {
1020  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "' with unknown via.");
1021  ok = false;
1022  }
1023  if (ok && !applyRestriction()) {
1024  WRITE_WARNING("Ignoring restriction relation '" + toString(myCurrentRelation) + "'.");
1025  }
1026  }
1027  // other relations might use similar subelements so reset in any case
1028  resetValues();
1029  }
1030 }
1031 
1032 
1033 bool
1035  // since OSM ways are bidirectional we need the via to figure out which direction was meant
1036  if (myViaNode != INVALID_ID) {
1037  NBNode* viaNode = myOSMNodes.find(myViaNode)->second->node;
1038  if (viaNode == 0) {
1039  WRITE_WARNING("Via-node '" + toString(myViaNode) + "' was not instantiated");
1040  return false;
1041  }
1042  NBEdge* from = findEdgeRef(myFromWay, viaNode->getIncomingEdges());
1043  NBEdge* to = findEdgeRef(myToWay, viaNode->getOutgoingEdges());
1044  if (from == 0) {
1045  WRITE_WARNING("from-edge of restriction relation could not be determined");
1046  return false;
1047  }
1048  if (to == 0) {
1049  WRITE_WARNING("to-edge of restriction relation could not be determined");
1050  return false;
1051  }
1052  if (myRestrictionType == RESTRICTION_ONLY) {
1053  from->addEdge2EdgeConnection(to);
1054  } else {
1055  from->removeFromConnections(to, -1, -1, true);
1056  }
1057  } else {
1058  // XXX interpreting via-ways or via-node lists not yet implemented
1059  WRITE_WARNING("direction of restriction relation could not be determined");
1060  return false;
1061  }
1062  return true;
1063 }
1064 
1065 
1066 NBEdge*
1067 NIImporter_OpenStreetMap::RelationHandler::findEdgeRef(long long int wayRef, const std::vector<NBEdge*>& candidates) const {
1068  const std::string prefix = toString(wayRef);
1069  const std::string backPrefix = "-" + prefix;
1070  NBEdge* result = 0;
1071  int found = 0;
1072  for (EdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); ++it) {
1073  if (((*it)->getID().substr(0, prefix.size()) == prefix) ||
1074  ((*it)->getID().substr(0, backPrefix.size()) == backPrefix)) {
1075  result = *it;
1076  found++;
1077  }
1078  }
1079  if (found > 1) {
1080  WRITE_WARNING("Ambigous way reference '" + prefix + "' in restriction relation");
1081  result = 0;
1082  }
1083  return result;
1084 }
1085 
1086 
1087 /****************************************************************************/
1088 
const SUMOReal lat
The latitude the node is located at.
An internal definition of a loaded edge.
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&#39;s incoming edges.
Definition: NBNode.h:247
const long long int id
The edge&#39;s id.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:203
std::string streetName
The edge&#39;s street name.
NBTypeCont & getTypeCont()
Returns the type container.
Definition: NBNetBuilder.h:170
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:46
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...
const long long int id
The node&#39;s id.
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:58
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.
WayType myBuswayType
Information about the kind of busway along this road.
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:242
A container for traffic light definitions and built programs.
bool applyRestriction() const
try to apply the parsed restriction and return whether successful
void addSidewalk(SUMOReal width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:2459
vehicle is a bicycle
void myEndElement(int element)
Called when a closing tag occurs.
int SVCPermissions
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
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 getIsOneWay(const std::string &type) const
Returns whether edges are one-way per default for the given type.
Definition: NBTypeCont.cpp:193
T MAX2(T a, T b)
Definition: StdDefs.h:74
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:2346
void myEndElement(int element)
Called when a closing tag occurs.
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:205
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&#39;s ok.
Definition: XMLSubSys.cpp:114
std::vector< long long int > myCurrentNodes
The list of nodes this edge is made of.
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].
Definition: NBTypeCont.cpp:217
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
std::string joinToStringSorting(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:175
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
SUMOReal ele
The elevation of this node.
NBNode * node
the NBNode that was instantiated
PositionVector reverse() const
static const SUMOReal MAXSPEED_UNGIVEN
SUMOReal getSidewalkWidth(const std::string &type) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:223
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given OSM file.
Functor which compares two Edges.
WayType myCyclewayType
Information about the kind of cycleway along this road.
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges.
Definition: NBNode.h:255
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:646
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:235
RelationHandler(const std::map< long long int, NIOSMNode * > &osmNodes, const std::map< long long int, Edge * > &osmEdges)
Constructor.
#define max(a, b)
Definition: polyfonts.c:65
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:181
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
void setFileName(const std::string &name)
Sets the current file name.
SUMOReal getBikeLaneWidth(const std::string &type) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:229
A class which extracts OSM-edges from a parsed OSM-file.
int insertEdge(Edge *e, int index, NBNode *from, NBNode *to, const std::vector< long long int > &passed, NBNetBuilder &nb)
Builds an NBEdge.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:189
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:175
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
A list of positions.
int getPriority(const std::string &type) const
Returns the priority for the given type.
Definition: NBTypeCont.cpp:187
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:68
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:202
size_t size() const
NodesHandler(std::map< long long int, NIOSMNode * > &toFill, std::set< NIOSMNode *, CompareNodes > &uniqueNodes, bool importElevation)
Contructor.
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:75
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:893
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myMaxSpeed
maximum speed in km/h, or MAXSPEED_UNGIVEN
void insert(const std::string &id, int numLanes, SUMOReal maxSpeed, int prio, SVCPermissions permissions, SUMOReal width, bool oneWayIsDefault, SUMOReal sidewalkWidth, SUMOReal bikeLaneWidth)
Adds a type into the list.
Definition: NBTypeCont.cpp:61
bool checkEdgeRef(long long int ref) const
check whether a referenced way has a corresponding edge
std::map< long long int, Edge * > myEdges
the map from OSM way ids to edge objects
std::vector< std::string > getVector()
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
int myNoLanes
number of lanes, or -1 if unknown
vehicle is a bus
void push_back(const PositionVector &p)
Appends all positions from the given vector.
void addBikeLane(SUMOReal width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:2465
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< long long int, NIOSMNode * > &osmNodes, std::map< long long int, Edge * > &toFill)
Constructor.
const SUMOReal lon
The longitude the node is located at.
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:162
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
bool getShallBeDiscarded(const std::string &type) const
Returns the information whether edges of this type shall be discarded.
Definition: NBTypeCont.cpp:199
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.
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 copyRestrictionsAndAttrs(const std::string &fromId, const std::string &toId)
Copy restrictions to a type.
Definition: NBTypeCont.cpp:114
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&#39;s lateral offset shal...
NBEdge * findEdgeRef(long long int wayRef, const std::vector< NBEdge * > &candidates) const
try to find the way segment among candidates
A class which extracts OSM-nodes from a parsed OSM-file.
Represents a single node (junction) during network building.
Definition: NBNode.h:75
void resetValues()
reset members to their defaults for parsing a new relation
NBNode * insertNodeChecking(long long int id, NBNodeCont &nc, NBTrafficLightLogicCont &tlsc)
Builds an NBNode.
T get(const std::string &str) const
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:159
std::string myHighWayType
The type, stored in &quot;highway&quot; key.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
Importer for networks stored in OpenStreetMap format.
static const long long int INVALID_ID
#define SUMOReal
Definition: config.h:215
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:108
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Definition: NBTypeCont.cpp:211
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:203
std::map< long long int, NIOSMNode * > myOSMNodes
the map from OSM node ids to actual nodes
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
std::set< NIOSMNode *, CompareNodes > myUniqueNodes
the set of unique nodes used in NodesHandler, used when freeing memory
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:62
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.