SUMO - Simulation of Urban MObility
NIImporter_SUMO.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Importer for networks stored in SUMO format
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2015 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 #include <string>
38 #include <utils/common/ToString.h>
42 #include <utils/xml/XMLSubSys.h>
46 #include <netbuild/NBEdge.h>
47 #include <netbuild/NBEdgeCont.h>
48 #include <netbuild/NBNode.h>
49 #include <netbuild/NBNodeCont.h>
51 #include <netbuild/NBNetBuilder.h>
52 #include "NILoader.h"
53 #include "NIXMLEdgesHandler.h"
54 #include "NIImporter_SUMO.h"
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 
61 // ===========================================================================
62 // method definitions
63 // ===========================================================================
64 // ---------------------------------------------------------------------------
65 // static methods (interface in this case)
66 // ---------------------------------------------------------------------------
67 void
69  NIImporter_SUMO importer(nb);
70  importer._loadNetwork(oc);
71 }
72 
73 
74 // ---------------------------------------------------------------------------
75 // loader methods
76 // ---------------------------------------------------------------------------
78  : SUMOSAXHandler("sumo-network"),
79  myNetBuilder(nb),
80  myNodeCont(nb.getNodeCont()),
81  myTLLCont(nb.getTLLogicCont()),
82  myCurrentEdge(0),
83  myCurrentLane(0),
84  myCurrentTL(0),
85  myLocation(0),
87  myAmLefthand(false),
88  myCornerDetail(0),
89  myLinkDetail(-1)
90 {}
91 
92 
94  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
95  EdgeAttrs* ed = (*i).second;
96  for (std::vector<LaneAttrs*>::const_iterator j = ed->lanes.begin(); j != ed->lanes.end(); ++j) {
97  delete *j;
98  }
99  delete ed;
100  }
101  delete myLocation;
102 }
103 
104 
105 void
107  // check whether the option is set (properly)
108  if (!oc.isUsableFileList("sumo-net-file")) {
109  return;
110  }
111  // parse file(s)
112  std::vector<std::string> files = oc.getStringVector("sumo-net-file");
113  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
114  if (!FileHelpers::isReadable(*file)) {
115  WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
116  return;
117  }
118  setFileName(*file);
119  PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'");
120  XMLSubSys::runParser(*this, *file, true);
122  }
123  // build edges
124  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
125  EdgeAttrs* ed = (*i).second;
126  // skip internal edges
127  if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) {
128  continue;
129  }
130  // get and check the nodes
131  NBNode* from = myNodeCont.retrieve(ed->fromNode);
132  NBNode* to = myNodeCont.retrieve(ed->toNode);
133  if (from == 0) {
134  WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
135  continue;
136  }
137  if (to == 0) {
138  WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
139  continue;
140  }
141  // edge shape
142  PositionVector geom;
143  if (ed->shape.size() > 0) {
144  geom = ed->shape;
145  } else {
146  // either the edge has default shape consisting only of the two node
147  // positions or we have a legacy network
148  geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition());
149  }
150  // build and insert the edge
151  NBEdge* e = new NBEdge(ed->id, from, to,
152  ed->type, ed->maxSpeed,
153  (unsigned int) ed->lanes.size(),
155  geom, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape
156  e->setLoadedLength(ed->length);
157  if (!myNetBuilder.getEdgeCont().insert(e)) {
158  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
159  delete e;
160  continue;
161  }
163  }
164  // assign further lane attributes (edges are built)
165  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
166  EdgeAttrs* ed = (*i).second;
167  NBEdge* nbe = ed->builtEdge;
168  if (nbe == 0) { // inner edge or removed by explicit list, vclass, ...
169  continue;
170  }
171  for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) {
172  LaneAttrs* lane = ed->lanes[fromLaneIndex];
173  // connections
174  const std::vector<Connection>& connections = lane->connections;
175  for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) {
176  const Connection& c = *c_it;
177  if (myEdges.count(c.toEdgeID) == 0) {
178  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
179  continue;
180  }
181  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
182  if (toEdge == 0) { // removed by explicit list, vclass, ...
183  continue;
184  }
185  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
186  WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'.");
187  }
189  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED,
190  true, c.mayDefinitelyPass, c.keepClear, c.contPos);
191 
192  // maybe we have a tls-controlled connection
193  if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) {
194  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
195  if (programs.size() > 0) {
196  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
197  for (it = programs.begin(); it != programs.end(); it++) {
198  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
199  if (tlDef) {
200  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo);
201  } else {
202  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
203  }
204  }
205  } else {
206  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
207  }
208  }
209  }
210  // allow/disallow XXX preferred
211  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex);
212  // width, offset
213  nbe->setLaneWidth(fromLaneIndex, lane->width);
214  nbe->setEndOffset(fromLaneIndex, lane->endOffset);
215  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
216  }
218  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
219  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
220  }
222  nbe->setEndOffset(-1, nbe->getEndOffset(0));
223  }
224  }
225  // insert loaded prohibitions
226  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
227  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
228  NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge;
229  NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge;
230  NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge;
231  if (prohibitedFrom == 0) {
232  WRITE_WARNING("Edge '" + it->prohibitedFrom + "' in prohibition was not built");
233  } else if (prohibitedTo == 0) {
234  WRITE_WARNING("Edge '" + it->prohibitedTo + "' in prohibition was not built");
235  } else if (prohibitorFrom == 0) {
236  WRITE_WARNING("Edge '" + it->prohibitorFrom + "' in prohibition was not built");
237  } else if (prohibitorTo == 0) {
238  WRITE_WARNING("Edge '" + it->prohibitorTo + "' in prohibition was not built");
239  } else {
240  NBNode* n = prohibitedFrom->getToNode();
242  NBConnection(prohibitorFrom, prohibitorTo),
243  NBConnection(prohibitedFrom, prohibitedTo));
244  }
245  }
246  if (!myHaveSeenInternalEdge) {
248  }
249  if (oc.isDefault("lefthand")) {
250  oc.set("lefthand", toString(myAmLefthand));
251  }
252  if (oc.isDefault("junctions.corner-detail")) {
253  oc.set("junctions.corner-detail", toString(myCornerDetail));
254  }
255  if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) {
256  oc.set("junctions.internal-link-detail", toString(myLinkDetail));
257  }
258  if (!deprecatedVehicleClassesSeen.empty()) {
259  WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
261  }
262  // add loaded crossings
263  if (!oc.getBool("no-internal-links")) {
264  for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
265  NBNode* node = myNodeCont.retrieve((*it).first);
266  for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
267  const Crossing& crossing = (*it_c);
268  EdgeVector edges;
269  for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
270  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
271  // edge might have been removed due to options
272  if (edge != 0) {
273  edges.push_back(edge);
274  }
275  }
276  if (edges.size() > 0) {
277  node->addCrossing(edges, crossing.width, crossing.priority, true);
278  }
279  }
280  }
281  }
282  // add roundabouts
283  for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
284  EdgeSet roundabout;
285  for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
286  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
287  if (edge == 0) {
288  if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
289  WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
290  }
291  } else {
292  roundabout.insert(edge);
293  }
294  }
295  myNetBuilder.getEdgeCont().addRoundabout(roundabout);
296  }
297 }
298 
299 
300 
301 void
303  const SUMOSAXAttributes& attrs) {
304  /* our goal is to reproduce the input net faithfully
305  * there are different types of objects in the netfile:
306  * 1) those which must be loaded into NBNetBuilder-Containers for processing
307  * 2) those which can be ignored because they are recomputed based on group 1
308  * 3) those which are of no concern to NBNetBuilder but should be exposed to
309  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
310  * and hand them over to NETEDIT
311  * alternative idea: those shouldn't really be contained within the
312  * network but rather in separate files. teach NETEDIT how to open those
313  * (POI?)
314  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
315  * must be copied over - need to patch NBNetBuilder for this.
316  * copy unknown by default
317  */
318  switch (element) {
319  case SUMO_TAG_NET: {
320  bool ok;
321  myAmLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, 0, ok, false);
322  myCornerDetail = attrs.getOpt<int>(SUMO_ATTR_CORNERDETAIL, 0, ok, 0);
323  myLinkDetail = attrs.getOpt<int>(SUMO_ATTR_LINKDETAIL, 0, ok, -1);
324  break;
325  }
326  case SUMO_TAG_EDGE:
327  addEdge(attrs);
328  break;
329  case SUMO_TAG_LANE:
330  addLane(attrs);
331  break;
332  case SUMO_TAG_JUNCTION:
333  addJunction(attrs);
334  break;
335  case SUMO_TAG_REQUEST:
336  addRequest(attrs);
337  break;
338  case SUMO_TAG_CONNECTION:
339  addConnection(attrs);
340  break;
341  case SUMO_TAG_TLLOGIC:
343  break;
344  case SUMO_TAG_PHASE:
345  addPhase(attrs, myCurrentTL);
346  break;
347  case SUMO_TAG_LOCATION:
348  myLocation = loadLocation(attrs);
349  break;
351  addProhibition(attrs);
352  break;
353  case SUMO_TAG_ROUNDABOUT:
354  addRoundabout(attrs);
355  break;
356  default:
357  break;
358  }
359 }
360 
361 
362 void
364  switch (element) {
365  case SUMO_TAG_EDGE:
366  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
367  WRITE_ERROR("Edge '" + myCurrentEdge->id + "' occured at least twice in the input.");
368  } else {
370  }
371  myCurrentEdge = 0;
372  break;
373  case SUMO_TAG_LANE:
374  if (myCurrentEdge != 0) {
376  myCurrentEdge->lanes.push_back(myCurrentLane);
377  }
378  myCurrentLane = 0;
379  break;
380  case SUMO_TAG_TLLOGIC:
381  if (!myCurrentTL) {
382  WRITE_ERROR("Unmatched closing tag for tl-logic.");
383  } else {
384  if (!myTLLCont.insert(myCurrentTL)) {
385  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
386  delete myCurrentTL;
387  }
388  myCurrentTL = 0;
389  }
390  break;
391  default:
392  break;
393  }
394 }
395 
396 
397 void
399  // get the id, report an error if not given or empty...
400  bool ok = true;
401  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
402  if (!ok) {
403  return;
404  }
405  myCurrentEdge = new EdgeAttrs();
407  myCurrentEdge->id = id;
408  // get the function
409  myCurrentEdge->func = attrs.getEdgeFunc(ok);
411  // add the crossing but don't do anything else
412  Crossing c;
413  c.edgeID = id;
416  return;
418  return; // skip internal edges
419  }
420  // get the type
421  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
422  // get the origin and the destination node
423  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
424  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
425  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
426  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
430  myCurrentEdge->maxSpeed = 0;
431  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
432  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
433  OptionsCont::getOptions().set("output.street-names", "true");
434  }
435 
436  std::string lsfS = toString(LANESPREAD_RIGHT);
437  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, lsfS);
438  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
440  } else {
441  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
442  }
443 }
444 
445 
446 void
448  bool ok = true;
449  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
450  if (!ok) {
451  return;
452  }
453  if (!myCurrentEdge) {
454  WRITE_ERROR("Found lane '" + id + "' not within edge element");
455  return;
456  }
457  if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, 0, ok, false)) {
458  const std::string nodeID = NBNode::getNodeIDFromInternalLane(id);
459  myCustomShapeMaps[nodeID][id] = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
460  }
461  myCurrentLane = new LaneAttrs;
463  // save the width and the lane id of the crossing but don't do anything else
465  assert(crossings.size() > 0);
466  crossings.back().width = attrs.get<SUMOReal>(SUMO_ATTR_WIDTH, id.c_str(), ok);
467  return;
469  myHaveSeenInternalEdge = true;
470  return; // skip internal lanes
471  }
472  if (attrs.hasAttribute("maxspeed")) {
473  // !!! deprecated
474  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
475  } else {
476  myCurrentLane->maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_SPEED, id.c_str(), ok);
477  }
478  try {
479  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
480  } catch (EmptyData e) {
481  // !!! deprecated
482  myCurrentLane->allow = "";
483  }
484  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
485  myCurrentLane->width = attrs.getOpt<SUMOReal>(SUMO_ATTR_WIDTH, id.c_str(), ok, (SUMOReal) NBEdge::UNSPECIFIED_WIDTH);
486  myCurrentLane->endOffset = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDOFFSET, id.c_str(), ok, (SUMOReal) NBEdge::UNSPECIFIED_OFFSET);
487  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
488  // lane coordinates are derived (via lane spread) do not include them in convex boundary
489  NBNetBuilder::transformCoordinates(myCurrentLane->shape, false, myLocation);
490 }
491 
492 
493 void
495  // get the id, report an error if not given or empty...
497  myCurrentJunction.intLanes.clear();
498  myCurrentJunction.response.clear();
499  bool ok = true;
500  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
501  if (!ok) {
502  return;
503  }
504  if (id[0] == ':') { // internal node
505  return;
506  }
507  SumoXMLNodeType type = attrs.getNodeType(ok);
508  if (ok) {
509  if (type == NODETYPE_DEAD_END_DEPRECATED || type == NODETYPE_DEAD_END) {
510  // dead end is a computed status. Reset this to unknown so it will
511  // be corrected if additional connections are loaded
512  type = NODETYPE_UNKNOWN;
513  }
514  } else {
515  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
516  }
517  Position pos = readPosition(attrs, id, ok);
519  NBNode* node = new NBNode(id, pos, type);
520  if (!myNodeCont.insert(node)) {
521  WRITE_ERROR("Problems on adding junction '" + id + "'.");
522  delete node;
523  return;
524  }
525  myCurrentJunction.node = node;
527  // set optional radius
528  if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
529  node->setRadius(attrs.get<SUMOReal>(SUMO_ATTR_RADIUS, id.c_str(), ok));
530  }
531  // handle custom shape
532  if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, 0, ok, false)) {
533  node->setCustomShape(attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok));
534  }
535  if (myCustomShapeMaps.count(id) > 0) {
536  NBNode::CustomShapeMap customShapes = myCustomShapeMaps[id];
537  for (NBNode::CustomShapeMap::const_iterator it = customShapes.begin(); it != customShapes.end(); ++it) {
538  node->setCustomLaneShape(it->first, it->second);
539  }
540  }
541  if (type == NODETYPE_RAIL_SIGNAL) {
542  myRailSignals.insert(id);
543  }
544 }
545 
546 
547 void
549  if (myCurrentJunction.node != 0) {
550  bool ok = true;
551  myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, 0, ok));
552  }
553 }
554 
555 
556 void
558  bool ok = true;
559  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
560  if (myEdges.count(fromID) == 0) {
561  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
562  return;
563  }
564  EdgeAttrs* from = myEdges[fromID];
565  Connection conn;
566  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
567  unsigned int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
568  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
569  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
570  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, 0, ok, false);
571  conn.keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, 0, ok, true);
573  if (conn.tlID != "") {
574  conn.tlLinkNo = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
575  }
576  if (from->lanes.size() <= (size_t) fromLaneIdx) {
577  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
578  return;
579  }
580  from->lanes[fromLaneIdx]->connections.push_back(conn);
581 
582  // determine crossing priority
583  if (myPedestrianCrossings.size() > 0
584  && from->func == EDGEFUNC_WALKINGAREA
585  && myEdges[conn.toEdgeID]->func == EDGEFUNC_CROSSING) {
586  std::vector<Crossing>& crossings = myPedestrianCrossings[SUMOXMLDefinitions::getJunctionIDFromInternalEdge(fromID)];
587  for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
588  if (conn.toEdgeID == (*it).edgeID) {
589  if (conn.tlID != "") {
590  (*it).priority = true;
591  } else {
592  LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, 0, ok));
593  (*it).priority = state == LINKSTATE_MAJOR;
594  }
595  }
596  }
597  }
598 }
599 
600 
601 void
603  bool ok = true;
604  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, 0, ok, "");
605  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, 0, ok, "");
606  if (!ok) {
607  return;
608  }
609  Prohibition p;
612  if (!ok) {
613  return;
614  }
615  myProhibitions.push_back(p);
616 }
617 
618 
620 NIImporter_SUMO::getLaneAttrsFromID(EdgeAttrs* edge, std::string lane_id) {
621  std::string edge_id;
622  unsigned int index;
623  interpretLaneID(lane_id, edge_id, index);
624  assert(edge->id == edge_id);
625  if (edge->lanes.size() <= (size_t) index) {
626  WRITE_ERROR("Unknown lane '" + lane_id + "' given in succedge.");
627  return 0;
628  } else {
629  return edge->lanes[index];
630  }
631 }
632 
633 
634 void
635 NIImporter_SUMO::interpretLaneID(const std::string& lane_id, std::string& edge_id, unsigned int& index) {
636  // assume lane_id = edge_id + '_' + index
637  size_t sep_index = lane_id.rfind('_');
638  if (sep_index == std::string::npos) {
639  WRITE_ERROR("Invalid lane id '" + lane_id + "' (missing '_').");
640  }
641  edge_id = lane_id.substr(0, sep_index);
642  std::string index_string = lane_id.substr(sep_index + 1);
643  try {
644  index = (unsigned int)TplConvert::_2int(index_string.c_str());
645  } catch (NumberFormatException) {
646  WRITE_ERROR("Invalid lane index '" + index_string + "' for lane '" + lane_id + "'.");
647  }
648 }
649 
650 
653  if (currentTL) {
654  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
655  return 0;
656  }
657  bool ok = true;
658  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
659  SUMOTime offset = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_OFFSET, id.c_str(), ok));
660  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
661  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
662  TrafficLightType type;
663  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
665  } else {
666  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
667  return 0;
668  }
669  if (ok) {
670  return new NBLoadedSUMOTLDef(id, programID, offset, type);
671  } else {
672  return 0;
673  }
674 }
675 
676 
677 void
679  if (!currentTL) {
680  WRITE_ERROR("found phase without tl-logic");
681  return;
682  }
683  const std::string& id = currentTL->getID();
684  bool ok = true;
685  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
686  SUMOTime duration = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_DURATION, id.c_str(), ok));
687  if (duration < 0) {
688  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
689  return;
690  }
691  // if the traffic light is an actuated traffic light, try to get
692  // the minimum and maximum durations
693  //SUMOTime minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, -1);
694  //SUMOTime maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, -1);
695  if (ok) {
696  currentTL->addPhase(duration, state);
697  }
698 }
699 
700 
702 NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) {
703  const PositionVector& firstLane = edge->lanes[0]->shape;
704  PositionVector result;
705  result.push_back(from);
706 
707  // reverse logic of NBEdge::computeLaneShape
708  // !!! this will only work for old-style constant width lanes
709  const size_t noLanes = edge->lanes.size();
710  SUMOReal offset;
711  if (edge->lsf == LANESPREAD_RIGHT) {
712  offset = (SUMO_const_laneWidth + SUMO_const_laneOffset) / 2.; // @todo: why is the lane offset counted in here?
713  } else {
714  offset = (SUMO_const_laneWidth) / 2. - (SUMO_const_laneWidth * (SUMOReal)noLanes - 1) / 2.;
715  }
716  for (unsigned int i = 1; i < firstLane.size() - 1; i++) {
717  const Position& from = firstLane[i - 1];
718  const Position& me = firstLane[i];
719  const Position& to = firstLane[i + 1];
720  Position offsets = PositionVector::sideOffset(from, me, offset);
721  Position offsets2 = PositionVector::sideOffset(me, to, offset);
722 
723  PositionVector l1(from - offsets, me - offsets);
724  l1.extrapolate(100);
725  PositionVector l2(me - offsets2, to - offsets2);
726  l2.extrapolate(100);
727  if (l1.intersects(l2)) {
728  result.push_back(l1.intersectionPosition2D(l2));
729  } else {
730  WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'.");
731  }
732  }
733 
734  result.push_back(to);
735  return result;
736 }
737 
738 
741  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
742  bool ok = true;
743  GeoConvHelper* result = 0;
745  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, 0, ok);
746  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, 0, ok);
747  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, 0, ok);
748  if (ok) {
749  Position networkOffset = s[0];
750  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
751  GeoConvHelper::setLoaded(*result);
752  }
753  return result;
754 }
755 
756 
757 Position
758 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
759  SUMOReal x = attrs.get<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok);
760  SUMOReal y = attrs.get<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok);
761  SUMOReal z = 0;
762  if (attrs.hasAttribute(SUMO_ATTR_Z)) {
763  z = attrs.get<SUMOReal>(SUMO_ATTR_Z, id.c_str(), ok);
764  }
765  return Position(x, y, z);
766 }
767 
768 
769 void
770 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
771  // split from/to
772  size_t div = attr.find("->");
773  if (div == std::string::npos) {
774  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
775  ok = false;
776  }
777  from = attr.substr(0, div);
778  to = attr.substr(div + 2);
779  // check whether the definition includes a lane information and discard it
780  if (from.find('_') != std::string::npos) {
781  from = from.substr(0, from.find('_'));
782  }
783  if (to.find('_') != std::string::npos) {
784  to = to.substr(0, to.find('_'));
785  }
786  // check whether the edges are known
787  if (myEdges.count(from) == 0) {
788  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
789  ok = false;
790  }
791  if (myEdges.count(to) == 0) {
792  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
793  ok = false;
794  }
795 }
796 
797 
798 void
800  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
802  } else {
803  WRITE_ERROR("Empty edges in roundabout.");
804  }
805 }
806 
807 
808 /****************************************************************************/
std::map< std::string, EdgeAttrs * > myEdges
Loaded edge definitions.
LaneAttrs * myCurrentLane
The currently parsed lanes&#39;s definition (to add the shape to)
The information about how to spread the lanes from the given position.
static Position sideOffset(const Position &beg, const Position &end, const SUMOReal amount)
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:806
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) ...
PositionVector shape
This edges&#39;s shape.
std::vector< Prohibition > myProhibitions
Loaded prohibitions.
static void addPhase(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
adds a phase to the traffic lights logic currently build
long long int SUMOTime
Definition: SUMOTime.h:43
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
std::set< std::string > deprecatedVehicleClassesSeen
Whether vehicles must keep the junction clear.
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:49
whether a given shape is user-defined
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 bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:58
NBNodeCont & myNodeCont
The node container to fill.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
SUMOReal maxSpeed
The maximum velocity allowed on this lane.
A loaded (complete) traffic light logic.
std::vector< LaneAttrs * > lanes
This edge&#39;s lanes.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1459
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2263
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2318
Describes a pedestrian crossing.
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:500
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea ...
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getProgramID() const
Returns the ProgramID.
The representation of a single edge during network building.
Definition: NBEdge.h:70
void declareConnectionsAsLoaded()
Definition: NBEdge.h:1076
A connection description.
std::vector< std::string > response
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
bool intersects(const Position &p1, const Position &p2) const
bool addLane2LaneConnection(unsigned int fromLane, NBEdge *dest, unsigned int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, SUMOReal contPos=UNSPECIFIED_CONTPOS)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:675
T MAX2(T a, T b)
Definition: StdDefs.h:79
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:447
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:2334
bool myAmLefthand
whether the loaded network was built for lefthand traffic
static NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
begins the reading of a traffic lights logic
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
static const SUMOReal UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:207
const SUMOReal SUMO_const_laneOffset
Definition: StdDefs.h:52
static StringBijection< LinkState > LinkStates
SUMOReal contPos
custom position for internal junction on this connection
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1597
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
NIImporter_SUMO(NBNetBuilder &nb)
Constructor.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
std::map< std::string, NBNode::CustomShapeMap > myCustomShapeMaps
customLaneShape (cannot be added to the NBNode when parsed since the node doesn&#39;t yet exist ...
Describes the values found in a lane&#39;s definition.
The connection was computed and validated.
Definition: NBEdge.h:115
LaneAttrs * getLaneAttrsFromID(EdgeAttrs *edge, std::string lane_id)
Parses lane index from lane ID an retrieve lane from EdgeAttrs.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
std::string toEdgeID
The id of the target edge.
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
The state of a link.
std::map< std::string, PositionVector > CustomShapeMap
Definition: NBNode.h:82
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and stores the values in "myCurrentLane".
NBNetBuilder & myNetBuilder
The network builder to fill.
const std::string & getID() const
Returns the id.
Definition: Named.h:65
std::vector< std::vector< std::string > > myRoundabouts
loaded roundabout edges
void addConnection(const SUMOSAXAttributes &attrs)
Parses a connection and saves it into the lane&#39;s definition stored in "myCurrentLane".
static void parseStringVector(const std::string &def, std::vector< std::string > &into)
Splits the given string.
std::string toNode
The node this edge ends at.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
The turning radius at an intersection in m.
Describes the values found in an edge&#39;s definition and this edge&#39;s lanes.
void setFileName(const std::string &name)
Sets the current file name.
std::set< NBEdge * > EdgeSet
Definition: NBCont.h:51
int myLinkDetail
the level of geometry detail for internal lanes in the loaded network
JunctionAttrs myCurrentJunction
The currently parsed junction definition to help in reconstructing crossings.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:60
the edges of a route
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:161
std::string getLaneID(unsigned int lane) const
Definition: NBEdge.cpp:2135
std::vector< std::string > crossingEdges
std::string allow
This lane&#39;s allowed vehicle classes.
Encapsulated SAX-Attributes.
void setRadius(SUMOReal radius)
set the turning radius
Definition: NBNode.h:510
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
static StringBijection< TrafficLightType > TrafficLightTypes
Describes the values found in a prohibition.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
Importer for networks stored in SUMO format.
std::string tlID
The id of the traffic light that controls this connection.
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
EdgeAttrs * myCurrentEdge
The currently parsed edge&#39;s definition (to add loaded lanes to)
A list of positions.
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
void parseProhibitionConnection(const std::string &attr, std::string &from, std::string &to, bool &ok)
parses connection string of a prohibition (very old school)
void haveLoadedNetworkWithoutInternalEdges()
notify about style of loaded network
Definition: NBNetBuilder.h:200
LaneSpreadFunction lsf
The lane spread function.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
void setCustomLaneShape(const std::string &laneID, const PositionVector &shape)
sets a custom shape for an internal lane
Definition: NBNode.cpp:1604
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:202
std::string disallow
This lane&#39;s disallowed vehicle classes.
unsigned int tlLinkNo
The index of this connection within the controlling traffic light.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2377
NBEdge * builtEdge
The built edge.
virtual SumoXMLNodeType getNodeType(bool &ok) const =0
Returns the value of the named attribute.
static PositionVector reconstructEdgeShape(const EdgeAttrs *edge, const Position &from, const Position &to)
reconstructs the edge shape from the node positions and the given lane shapes since we do not know th...
SumoXMLEdgeFunc func
This edge&#39;s function.
void _loadNetwork(OptionsCont &oc)
load the network
SUMOReal width
The width of this lane.
SUMOReal getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:476
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, unsigned int &index)
parses edge-id and index from lane-id
bool keepClear
Whether the junction must be kept clear coming from this connection.
std::vector< std::string > intLanes
SUMOReal endOffset
This lane&#39;s offset from the intersection.
std::string streetName
This edge&#39;s street name.
static void loadNetwork(OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
SUMOReal maxSpeed
The maximum velocity allowed on this edge (!!!)
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
static int _2int(const E *const data)
Definition: TplConvert.h:114
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
std::vector< Connection > connections
This lane&#39;s connections.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
void addCrossing(EdgeVector edges, SUMOReal width, bool priority, bool fromSumoNet=false)
add a pedestrian crossing to this node
Definition: NBNode.cpp:2391
std::string type
This edge&#39;s type.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:246
static const SUMOReal UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:210
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
unsigned int toLaneIdx
The index of the target lane.
void addPhase(SUMOTime duration, const std::string &state)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases...
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
int myCornerDetail
the level of corner detail in the loaded network
static Position readPosition(const SUMOSAXAttributes &attrs, const std::string &id, bool &ok)
read position from the given attributes, attribute errors to id
std::map< std::string, std::vector< Crossing > > myPedestrianCrossings
The pedestrian crossings found in the network.
A storage for options typed value containers)
Definition: OptionsCont.h:108
int priority
This edge&#39;s priority.
Position intersectionPosition2D(const Position &p1, const Position &p2, const SUMOReal withinDist=0.) const
std::string id
This edge&#39;s id.
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:80
void myEndElement(int element)
Called when a closing tag occurs.
This is an uncontrolled, major link, may pass.
std::string fromNode
The node this edge starts at.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
T get(const std::string &str) const
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
~NIImporter_SUMO()
Destructor.
void addRequest(const SUMOSAXAttributes &attrs)
Parses a reques and saves selected attributes in myCurrentJunction.
GeoConvHelper * myLocation
The coordinate transformation which was used to build the loaded network.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1437
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Definition: NBNode.cpp:1130
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2302
#define SUMOReal
Definition: config.h:214
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
SUMOReal length
The length of the edge if set explicitly.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:464
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:109
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
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
Definition: NBEdgeCont.cpp:941
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and saves it.
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
std::set< std::string > myRailSignals
list of node id with rail signals (no NBTrafficLightDefinition exists)
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex)
Adds a connection and immediately informs the edges.
void extrapolate(const SUMOReal val, const bool onlyFirst=false)
TrafficLightType
static std::string getNodeIDFromInternalLane(const std::string id)
returns the node id for internal lanes, crossings and walkingareas
Definition: NBNode.cpp:2479