SUMO - Simulation of Urban MObility
NIImporter_SUMO.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Importer for networks stored in SUMO format
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 #include <string>
32 #include <utils/common/ToString.h>
36 #include <utils/xml/XMLSubSys.h>
40 #include <netbuild/NBEdge.h>
41 #include <netbuild/NBEdgeCont.h>
42 #include <netbuild/NBNode.h>
43 #include <netbuild/NBNodeCont.h>
45 #include <netbuild/NBNetBuilder.h>
46 #include "NILoader.h"
47 #include "NIXMLTypesHandler.h"
48 #include "NIImporter_SUMO.h"
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 // ---------------------------------------------------------------------------
55 // static methods (interface in this case)
56 // ---------------------------------------------------------------------------
57 void
59  NIImporter_SUMO importer(nb);
60  importer._loadNetwork(oc);
61 }
62 
63 
64 // ---------------------------------------------------------------------------
65 // loader methods
66 // ---------------------------------------------------------------------------
68  : SUMOSAXHandler("sumo-network"),
69  myNetBuilder(nb),
70  myNodeCont(nb.getNodeCont()),
71  myTLLCont(nb.getTLLogicCont()),
72  myCurrentEdge(nullptr),
73  myCurrentLane(nullptr),
74  myCurrentTL(nullptr),
75  myLocation(nullptr),
77  myAmLefthand(false),
78  myCornerDetail(0),
79  myLinkDetail(-1),
80  myRectLaneCut(false),
81  myWalkingAreas(false),
82  myLimitTurnSpeed(-1),
83  myCheckLaneFoesAll(false),
85 {
86 }
87 
88 
90  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
91  EdgeAttrs* ed = (*i).second;
92  for (std::vector<LaneAttrs*>::const_iterator j = ed->lanes.begin(); j != ed->lanes.end(); ++j) {
93  delete *j;
94  }
95  delete ed;
96  }
97  delete myLocation;
98 }
99 
100 
101 void
103  // check whether the option is set (properly)
104  if (!oc.isUsableFileList("sumo-net-file")) {
105  return;
106  }
107  // parse file(s)
109  std::vector<std::string> files = oc.getStringVector("sumo-net-file");
110  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
111  if (!FileHelpers::isReadable(*file)) {
112  WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
113  return;
114  }
115  setFileName(*file);
116  PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'");
117  XMLSubSys::runParser(*this, *file, true);
118  XMLSubSys::runParser(*typesHandler, *file, true);
120  }
121  // build edges
122  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
123  EdgeAttrs* ed = (*i).second;
124  // skip internal edges
125  if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) {
126  continue;
127  }
128  // get and check the nodes
129  NBNode* from = myNodeCont.retrieve(ed->fromNode);
130  NBNode* to = myNodeCont.retrieve(ed->toNode);
131  if (from == nullptr) {
132  WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
133  continue;
134  }
135  if (to == nullptr) {
136  WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
137  continue;
138  }
139  if (from == to) {
140  WRITE_ERROR("Edge's '" + ed->id + "' from-node and to-node '" + ed->toNode + "' art identical.");
141  continue;
142  }
143  // edge shape
144  PositionVector geom;
145  if (ed->shape.size() > 0) {
146  geom = ed->shape;
147  } else {
148  // either the edge has default shape consisting only of the two node
149  // positions or we have a legacy network
150  geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition());
151  }
152  // build and insert the edge
153  NBEdge* e = new NBEdge(ed->id, from, to,
154  ed->type, ed->maxSpeed,
155  (int) ed->lanes.size(),
157  geom, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape
158  e->setLoadedLength(ed->length);
159  e->updateParameter(ed->getParametersMap());
160  if (!myNetBuilder.getEdgeCont().insert(e)) {
161  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
162  delete e;
163  continue;
164  }
166  if (ed->builtEdge != nullptr) {
167  ed->builtEdge->setStopOffsets(-1, ed->stopOffsets);
168  }
169  }
170  // assign further lane attributes (edges are built)
171  EdgeVector toRemove;
172  const bool dismissVclasses = oc.getBool("dismiss-vclasses");
173  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
174  EdgeAttrs* ed = (*i).second;
175  NBEdge* nbe = ed->builtEdge;
176  if (nbe == nullptr) { // inner edge or removed by explicit list, vclass, ...
177  continue;
178  }
179  for (int fromLaneIndex = 0; fromLaneIndex < (int) ed->lanes.size(); ++fromLaneIndex) {
180  LaneAttrs* lane = ed->lanes[fromLaneIndex];
181  // connections
182  const std::vector<Connection>& connections = lane->connections;
183  for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) {
184  const Connection& c = *c_it;
185  if (myEdges.count(c.toEdgeID) == 0) {
186  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
187  continue;
188  }
189  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
190  if (toEdge == nullptr) { // removed by explicit list, vclass, ...
191  continue;
192  }
193  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
194  WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'.");
195  }
197  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED,
199 
200  // maybe we have a tls-controlled connection
201  if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) {
202  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
203  if (programs.size() > 0) {
204  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
205  for (it = programs.begin(); it != programs.end(); it++) {
206  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
207  if (tlDef) {
208  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkIndex, false);
209  } else {
210  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
211  }
212  }
213  } else {
214  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
215  }
216  }
217  }
218  // allow/disallow XXX preferred
219  if (!dismissVclasses) {
220  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex);
221  }
222  // width, offset
223  nbe->setLaneWidth(fromLaneIndex, lane->width);
224  nbe->setEndOffset(fromLaneIndex, lane->endOffset);
225  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
226  nbe->setAcceleration(fromLaneIndex, lane->accelRamp);
227  nbe->getLaneStruct(fromLaneIndex).oppositeID = lane->oppositeID;
228  nbe->getLaneStruct(fromLaneIndex).updateParameter(lane->getParametersMap());
229  if (lane->customShape) {
230  nbe->setLaneShape(fromLaneIndex, lane->shape);
231  }
232  // stop offset for lane
233  bool stopOffsetSet = false;
234  if (lane->stopOffsets.size() != 0 || nbe->getStopOffsets().size() == 0) {
235  // apply lane-specific stopOffset (might be none as well)
236  stopOffsetSet = nbe->setStopOffsets(fromLaneIndex, lane->stopOffsets);
237  }
238  if (!stopOffsetSet) {
239  // apply default stop offset to lane
240  nbe->setStopOffsets(fromLaneIndex, nbe->getStopOffsets());
241  }
242  }
244  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
245  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
246  }
248  nbe->setEndOffset(-1, nbe->getEndOffset(0));
249  }
250  if (!nbe->hasLaneSpecificStopOffsets() && nbe->getStopOffsets().size() != 0) {
251  nbe->setStopOffsets(-1, nbe->getStopOffsets());
252  }
253  // check again after permissions are set
256  toRemove.push_back(nbe);
257  }
258  }
259  for (EdgeVector::iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
261  }
262  // insert loaded prohibitions
263  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
264  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
265  NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge;
266  NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge;
267  NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge;
268  if (prohibitedFrom == nullptr) {
269  WRITE_WARNING("Edge '" + it->prohibitedFrom + "' in prohibition was not built");
270  } else if (prohibitedTo == nullptr) {
271  WRITE_WARNING("Edge '" + it->prohibitedTo + "' in prohibition was not built");
272  } else if (prohibitorFrom == nullptr) {
273  WRITE_WARNING("Edge '" + it->prohibitorFrom + "' in prohibition was not built");
274  } else if (prohibitorTo == nullptr) {
275  WRITE_WARNING("Edge '" + it->prohibitorTo + "' in prohibition was not built");
276  } else {
277  NBNode* n = prohibitedFrom->getToNode();
279  NBConnection(prohibitorFrom, prohibitorTo),
280  NBConnection(prohibitedFrom, prohibitedTo));
281  }
282  }
283  if (!myHaveSeenInternalEdge && oc.isDefault("no-internal-links")) {
284  oc.set("no-internal-links", "true");
285  }
286  if (oc.isDefault("lefthand")) {
287  oc.set("lefthand", toString(myAmLefthand));
288  }
289  if (oc.isDefault("junctions.corner-detail")) {
290  oc.set("junctions.corner-detail", toString(myCornerDetail));
291  }
292  if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) {
293  oc.set("junctions.internal-link-detail", toString(myLinkDetail));
294  }
295  if (oc.isDefault("rectangular-lane-cut")) {
296  oc.set("rectangular-lane-cut", toString(myRectLaneCut));
297  }
298  if (oc.isDefault("walkingareas")) {
299  oc.set("walkingareas", toString(myWalkingAreas));
300  }
301  if (oc.isDefault("junctions.limit-turn-speed")) {
302  oc.set("junctions.limit-turn-speed", toString(myLimitTurnSpeed));
303  }
304  if (oc.isDefault("check-lane-foes.all") && oc.getBool("check-lane-foes.all") != myCheckLaneFoesAll) {
305  oc.set("check-lane-foes.all", toString(myCheckLaneFoesAll));
306  }
307  if (oc.isDefault("check-lane-foes.roundabout") && oc.getBool("check-lane-foes.roundabout") != myCheckLaneFoesRoundabout) {
308  oc.set("check-lane-foes.roundabout", toString(myCheckLaneFoesRoundabout));
309  }
310  if (!deprecatedVehicleClassesSeen.empty()) {
311  WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
313  }
314  if (!oc.getBool("no-internal-links")) {
315  // add loaded crossings
316  for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
317  NBNode* node = myNodeCont.retrieve((*it).first);
318  for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
319  const Crossing& crossing = (*it_c);
320  EdgeVector edges;
321  for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
322  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
323  // edge might have been removed due to options
324  if (edge != nullptr) {
325  edges.push_back(edge);
326  }
327  }
328  if (edges.size() > 0) {
329  node->addCrossing(edges, crossing.width, crossing.priority, crossing.customTLIndex, crossing.customTLIndex2, crossing.customShape, true);
330  }
331  }
332  }
333  // add walking area custom shapes
334  for (auto item : myWACustomShapes) {
335  std::string nodeID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(item.first);
336  NBNode* node = myNodeCont.retrieve(nodeID);
337  std::vector<std::string> edgeIDs;
338  if (item.second.fromEdges.size() + item.second.toEdges.size() == 0) {
339  // must be a split crossing
340  assert(item.second.fromCrossed.size() > 0);
341  assert(item.second.toCrossed.size() > 0);
342  edgeIDs = item.second.fromCrossed;
343  edgeIDs.insert(edgeIDs.end(), item.second.toCrossed.begin(), item.second.toCrossed.end());
344  } else if (item.second.fromEdges.size() > 0) {
345  edgeIDs = item.second.fromEdges;
346  } else {
347  edgeIDs = item.second.toEdges;
348  }
349  EdgeVector edges;
350  for (std::string edgeID : edgeIDs) {
351  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeID);
352  // edge might have been removed due to options
353  if (edge != nullptr) {
354  edges.push_back(edge);
355  }
356  }
357  if (edges.size() > 0) {
358  node->addWalkingAreaShape(edges, item.second.shape);
359  }
360  }
361  }
362  // add roundabouts
363  for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
364  EdgeSet roundabout;
365  for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
366  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
367  if (edge == nullptr) {
368  if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
369  WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
370  }
371  } else {
372  roundabout.insert(edge);
373  }
374  }
375  myNetBuilder.getEdgeCont().addRoundabout(roundabout);
376  }
377 }
378 
379 
380 
381 void
383  const SUMOSAXAttributes& attrs) {
384  /* our goal is to reproduce the input net faithfully
385  * there are different types of objects in the netfile:
386  * 1) those which must be loaded into NBNetBuilder-Containers for processing
387  * 2) those which can be ignored because they are recomputed based on group 1
388  * 3) those which are of no concern to NBNetBuilder but should be exposed to
389  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
390  * and hand them over to NETEDIT
391  * alternative idea: those shouldn't really be contained within the
392  * network but rather in separate files. teach NETEDIT how to open those
393  * (POI?)
394  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
395  * must be copied over - need to patch NBNetBuilder for this.
396  * copy unknown by default
397  */
398  switch (element) {
399  case SUMO_TAG_NET: {
400  bool ok;
401  myAmLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
402  myCornerDetail = attrs.getOpt<int>(SUMO_ATTR_CORNERDETAIL, nullptr, ok, 0);
403  myLinkDetail = attrs.getOpt<int>(SUMO_ATTR_LINKDETAIL, nullptr, ok, -1);
404  myRectLaneCut = attrs.getOpt<bool>(SUMO_ATTR_RECTANGULAR_LANE_CUT, nullptr, ok, false);
405  myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
406  myLimitTurnSpeed = attrs.getOpt<double>(SUMO_ATTR_LIMIT_TURN_SPEED, nullptr, ok, -1);
407  myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
408  myCheckLaneFoesAll = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ALL, nullptr, ok, false);
409  myCheckLaneFoesRoundabout = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ALL, nullptr, ok, true);
410  break;
411  }
412  case SUMO_TAG_EDGE:
413  addEdge(attrs);
414  break;
415  case SUMO_TAG_LANE:
416  addLane(attrs);
417  break;
418  case SUMO_TAG_STOPOFFSET: {
419  bool ok = true;
420  addStopOffsets(attrs, ok);
421  }
422  break;
423  case SUMO_TAG_NEIGH:
425  break;
426  case SUMO_TAG_JUNCTION:
427  addJunction(attrs);
428  break;
429  case SUMO_TAG_REQUEST:
430  addRequest(attrs);
431  break;
432  case SUMO_TAG_CONNECTION:
433  addConnection(attrs);
434  break;
435  case SUMO_TAG_TLLOGIC:
437  if (myCurrentTL) {
438  myLastParameterised.push_back(myCurrentTL);
439  }
440  break;
441  case SUMO_TAG_PHASE:
442  addPhase(attrs, myCurrentTL);
443  break;
444  case SUMO_TAG_LOCATION:
445  myLocation = loadLocation(attrs);
446  break;
448  addProhibition(attrs);
449  break;
450  case SUMO_TAG_ROUNDABOUT:
451  addRoundabout(attrs);
452  break;
453  case SUMO_TAG_PARAM:
454  if (myLastParameterised.size() != 0) {
455  bool ok = true;
456  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
457  // circumventing empty string test
458  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
459  myLastParameterised.back()->setParameter(key, val);
460  }
461  break;
462  default:
463  break;
464  }
465 }
466 
467 
468 void
470  switch (element) {
471  case SUMO_TAG_EDGE:
472  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
473  WRITE_ERROR("Edge '" + myCurrentEdge->id + "' occurred at least twice in the input.");
474  } else {
476  }
477  myCurrentEdge = nullptr;
478  myLastParameterised.pop_back();
479  break;
480  case SUMO_TAG_LANE:
481  if (myCurrentEdge != nullptr) {
483  myCurrentEdge->lanes.push_back(myCurrentLane);
484  }
485  myCurrentLane = nullptr;
486  myLastParameterised.pop_back();
487  break;
488  case SUMO_TAG_TLLOGIC:
489  if (!myCurrentTL) {
490  WRITE_ERROR("Unmatched closing tag for tl-logic.");
491  } else {
492  if (!myTLLCont.insert(myCurrentTL)) {
493  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
494  delete myCurrentTL;
495  }
496  myCurrentTL = nullptr;
497  myLastParameterised.pop_back();
498  }
499  break;
500  case SUMO_TAG_JUNCTION:
501  if (myCurrentJunction.node != nullptr) {
502  myLastParameterised.pop_back();
503  }
504  break;
505  case SUMO_TAG_CONNECTION:
506  break;
507  default:
508  break;
509  }
510 }
511 
512 
513 void
515  // get the id, report an error if not given or empty...
516  bool ok = true;
517  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
518  if (!ok) {
519  return;
520  }
521  myCurrentEdge = new EdgeAttrs();
523  myCurrentEdge->builtEdge = nullptr;
524  myCurrentEdge->id = id;
525  // get the function
526  myCurrentEdge->func = attrs.getEdgeFunc(ok);
528  // add the crossing but don't do anything else
529  Crossing c(id);
532  return;
534  myHaveSeenInternalEdge = true;
535  return; // skip internal edges
536  }
537  // get the type
538  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
539  // get the origin and the destination node
540  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
541  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
542  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
543  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
547  myCurrentEdge->maxSpeed = 0;
548  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
549  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
550  OptionsCont::getOptions().set("output.street-names", "true");
551  }
552 
553  std::string lsfS = toString(LANESPREAD_RIGHT);
554  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, lsfS);
555  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
557  } else {
558  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
559  }
560 }
561 
562 
563 void
565  bool ok = true;
566  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
567  if (!ok) {
568  return;
569  }
570  if (!myCurrentEdge) {
571  WRITE_ERROR("Found lane '" + id + "' not within edge element");
572  return;
573  }
574  myCurrentLane = new LaneAttrs();
576  myCurrentLane->customShape = attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false);
577  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
579  // save the width and the lane id of the crossing but don't do anything else
581  assert(crossings.size() > 0);
582  crossings.back().width = attrs.get<double>(SUMO_ATTR_WIDTH, id.c_str(), ok);
583  if (myCurrentLane->customShape) {
584  crossings.back().customShape = myCurrentLane->shape;
585  }
586  } else if (myCurrentEdge->func == EDGEFUNC_WALKINGAREA) {
587  // save custom shape if needed but don't do anything else
588  if (myCurrentLane->customShape) {
590  wacs.shape = myCurrentLane->shape;
593  }
594  return;
595  } else if (myCurrentEdge->func == EDGEFUNC_INTERNAL) {
596  return; // skip internal edges
597  }
598  if (attrs.hasAttribute("maxspeed")) {
599  // !!! deprecated
600  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
601  } else {
602  myCurrentLane->maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
603  }
604  try {
605  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
606  } catch (EmptyData&) {
607  // !!! deprecated
608  myCurrentLane->allow = "";
609  }
610  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
611  myCurrentLane->width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_WIDTH);
612  myCurrentLane->endOffset = attrs.getOpt<double>(SUMO_ATTR_ENDOFFSET, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_OFFSET);
613  myCurrentLane->accelRamp = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
614  // lane coordinates are derived (via lane spread) do not include them in convex boundary
616 }
617 
618 
619 void
621  std::map<SVCPermissions, double> offsets = parseStopOffsets(attrs, ok);
622  if (!ok) {
623  return;
624  }
625  assert(offsets.size() == 1);
626  // Admissibility of value will be checked in _loadNetwork(), when lengths are known
627  if (myCurrentLane == nullptr) {
628  if (myCurrentEdge->stopOffsets.size() != 0) {
629  std::stringstream ss;
630  ss << "Duplicate definition of stopOffset for edge " << myCurrentEdge->id << ".\nIgnoring duplicate specification.";
631  WRITE_WARNING(ss.str());
632  return;
633  } else {
634  myCurrentEdge->stopOffsets = offsets;
635  }
636  } else {
637  if (myCurrentLane->stopOffsets.size() != 0) {
638  std::stringstream ss;
639  ss << "Duplicate definition of lane's stopOffset on edge " << myCurrentEdge->id << ".\nIgnoring duplicate specifications.";
640  WRITE_WARNING(ss.str());
641  return;
642  } else {
643  myCurrentLane->stopOffsets = offsets;
644  }
645  }
646 }
647 
648 
649 void
651  // get the id, report an error if not given or empty...
652  myCurrentJunction.node = nullptr;
653  myCurrentJunction.intLanes.clear();
654  myCurrentJunction.response.clear();
655  bool ok = true;
656  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
657  if (!ok) {
658  return;
659  }
660  if (id[0] == ':') { // internal node
661  return;
662  }
663  SumoXMLNodeType type = attrs.getNodeType(ok);
664  if (ok) {
665  if (type == NODETYPE_DEAD_END_DEPRECATED || type == NODETYPE_DEAD_END) {
666  // dead end is a computed status. Reset this to unknown so it will
667  // be corrected if additional connections are loaded
668  type = NODETYPE_UNKNOWN;
669  }
670  } else {
671  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
672  }
673  Position pos = readPosition(attrs, id, ok);
675  NBNode* node = new NBNode(id, pos, type);
676  myLastParameterised.push_back(node);
677  if (!myNodeCont.insert(node)) {
678  WRITE_ERROR("Problems on adding junction '" + id + "'.");
679  delete node;
680  return;
681  }
682  myCurrentJunction.node = node;
684  // set optional radius
685  if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
686  node->setRadius(attrs.get<double>(SUMO_ATTR_RADIUS, id.c_str(), ok));
687  }
688  // handle custom shape
689  if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false)) {
690  node->setCustomShape(attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok));
691  }
692  if (type == NODETYPE_RAIL_SIGNAL || type == NODETYPE_RAIL_CROSSING) {
693  // both types of nodes come without a tlLogic
694  myRailSignals.insert(id);
695  }
697  node->setRightOfWay(attrs.getRightOfWay(ok));
698  }
699 }
700 
701 
702 void
704  if (myCurrentJunction.node != nullptr) {
705  bool ok = true;
706  myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok));
707  }
708 }
709 
710 
711 void
713  bool ok = true;
714  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
715  if (myEdges.count(fromID) == 0) {
716  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
717  return;
718  }
719  EdgeAttrs* from = myEdges[fromID];
720  Connection conn;
721  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
722  int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
723  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
724  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
725  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, nullptr, ok, false);
726  conn.keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
727  conn.contPos = attrs.getOpt<double>(SUMO_ATTR_CONTPOS, nullptr, ok, NBEdge::UNSPECIFIED_CONTPOS);
729  conn.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, NBEdge::UNSPECIFIED_SPEED);
732  if (conn.tlID != "") {
733  conn.tlLinkIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
734  }
735  if ((int)from->lanes.size() <= fromLaneIdx) {
736  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
737  return;
738  }
739  from->lanes[fromLaneIdx]->connections.push_back(conn);
740 
741  // determine crossing priority and tlIndex
742  if (myPedestrianCrossings.size() > 0) {
743  if (from->func == EDGEFUNC_WALKINGAREA && myEdges[conn.toEdgeID]->func == EDGEFUNC_CROSSING) {
744  // connection from walkingArea to crossing
745  std::vector<Crossing>& crossings = myPedestrianCrossings[SUMOXMLDefinitions::getJunctionIDFromInternalEdge(fromID)];
746  for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
747  if (conn.toEdgeID == (*it).edgeID) {
748  if (conn.tlID != "") {
749  (*it).priority = true;
750  (*it).customTLIndex = conn.tlLinkIndex;
751  } else {
752  LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
753  (*it).priority = state == LINKSTATE_MAJOR;
754  }
755  }
756  }
757  } else if (from->func == EDGEFUNC_CROSSING && myEdges[conn.toEdgeID]->func == EDGEFUNC_WALKINGAREA) {
758  // connection from crossing to walkingArea (set optional linkIndex2)
760  if (fromID == c.edgeID) {
761  c.customTLIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok, -1);
762  }
763  }
764  }
765  }
766  // determine walking area reference edges
767  if (myWACustomShapes.size() > 0) {
768  EdgeAttrs* to = myEdges[conn.toEdgeID];
769  if (from->func == EDGEFUNC_WALKINGAREA) {
770  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(fromID);
771  if (it != myWACustomShapes.end()) {
772  if (to->func == EDGEFUNC_NORMAL) {
773  // add target sidewalk as reference
774  it->second.toEdges.push_back(conn.toEdgeID);
775  } else if (to->func == EDGEFUNC_CROSSING) {
776  // add target crossing edges as reference
778  if (conn.toEdgeID == crossing.edgeID) {
779  it->second.toCrossed.insert(it->second.toCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
780  }
781  }
782  }
783  }
784  } else if (to->func == EDGEFUNC_WALKINGAREA) {
785  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(conn.toEdgeID);
786  if (it != myWACustomShapes.end()) {
787  if (from->func == EDGEFUNC_NORMAL) {
788  // add origin sidewalk as reference
789  it->second.fromEdges.push_back(fromID);
790  } else if (from->func == EDGEFUNC_CROSSING) {
791  // add origin crossing edges as reference
793  if (fromID == crossing.edgeID) {
794  it->second.fromCrossed.insert(it->second.fromCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
795  }
796  }
797  }
798  }
799  }
800  }
801 }
802 
803 
804 void
806  bool ok = true;
807  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, nullptr, ok, "");
808  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, nullptr, ok, "");
809  if (!ok) {
810  return;
811  }
812  Prohibition p;
815  if (!ok) {
816  return;
817  }
818  myProhibitions.push_back(p);
819 }
820 
821 
823 NIImporter_SUMO::getLaneAttrsFromID(EdgeAttrs* edge, std::string lane_id) {
824  std::string edge_id;
825  int index;
826  NBHelpers::interpretLaneID(lane_id, edge_id, index);
827  assert(edge->id == edge_id);
828  if ((int)edge->lanes.size() <= index) {
829  WRITE_ERROR("Unknown lane '" + lane_id + "' given in succedge.");
830  return nullptr;
831  } else {
832  return edge->lanes[index];
833  }
834 }
835 
836 
839  if (currentTL) {
840  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
841  return nullptr;
842  }
843  bool ok = true;
844  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
845  SUMOTime offset = TIME2STEPS(attrs.get<double>(SUMO_ATTR_OFFSET, id.c_str(), ok));
846  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
847  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, nullptr, ok);
848  TrafficLightType type;
849  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
851  } else {
852  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
853  return nullptr;
854  }
855  if (ok) {
856  return new NBLoadedSUMOTLDef(id, programID, offset, type);
857  } else {
858  return nullptr;
859  }
860 }
861 
862 
863 void
865  if (!currentTL) {
866  WRITE_ERROR("found phase without tl-logic");
867  return;
868  }
869  const std::string& id = currentTL->getID();
870  bool ok = true;
871  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
872  SUMOTime duration = TIME2STEPS(attrs.get<double>(SUMO_ATTR_DURATION, id.c_str(), ok));
873  if (duration < 0) {
874  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
875  return;
876  }
877  // if the traffic light is an actuated traffic light, try to get
878  // the minimum and maximum durations
881  if (ok) {
882  currentTL->addPhase(duration, state, minDuration, maxDuration);
883  }
884 }
885 
886 
888 NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) {
889  PositionVector result;
890  result.push_back(from);
891 
892  if (edge->lanes[0]->customShape) {
893  // this is a new network where edge shapes are writen if they exist.
894  result.push_back(to);
895  return result;
896  }
897  const PositionVector& firstLane = edge->lanes[0]->shape;
898 
899  // reverse logic of NBEdge::computeLaneShape
900  // !!! this will only work for old-style constant width lanes
901  const int noLanes = (int)edge->lanes.size();
902  double offset;
903  if (edge->lsf == LANESPREAD_RIGHT) {
904  offset = (SUMO_const_laneWidth + SUMO_const_laneOffset) / 2.; // @todo: why is the lane offset counted in here?
905  } else {
906  offset = (SUMO_const_laneWidth) / 2. - (SUMO_const_laneWidth * (double)noLanes - 1) / 2.;
907  }
908  for (int i = 1; i < (int)firstLane.size() - 1; i++) {
909  const Position& from = firstLane[i - 1];
910  const Position& me = firstLane[i];
911  const Position& to = firstLane[i + 1];
912  Position offsets = PositionVector::sideOffset(from, me, offset);
913  Position offsets2 = PositionVector::sideOffset(me, to, offset);
914 
915  PositionVector l1(from - offsets, me - offsets);
916  l1.extrapolate(100);
917  PositionVector l2(me - offsets2, to - offsets2);
918  l2.extrapolate(100);
919  if (l1.intersects(l2)) {
920  result.push_back(l1.intersectionPosition2D(l2));
921  } else {
922  WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'.");
923  }
924  }
925 
926  result.push_back(to);
927  return result;
928 }
929 
930 
933  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
934  bool ok = true;
935  GeoConvHelper* result = nullptr;
936  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
937  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
938  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
939  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
940  if (ok) {
941  Position networkOffset = s[0];
942  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
943  GeoConvHelper::setLoaded(*result);
944  }
945  return result;
946 }
947 
948 
949 Position
950 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
951  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
952  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
953  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
954  return Position(x, y, z);
955 }
956 
957 
958 void
959 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
960  // split from/to
961  const std::string::size_type div = attr.find("->");
962  if (div == std::string::npos) {
963  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
964  ok = false;
965  }
966  from = attr.substr(0, div);
967  to = attr.substr(div + 2);
968  // check whether the definition includes a lane information and discard it
969  if (from.find('_') != std::string::npos) {
970  from = from.substr(0, from.find('_'));
971  }
972  if (to.find('_') != std::string::npos) {
973  to = to.substr(0, to.find('_'));
974  }
975  // check whether the edges are known
976  if (myEdges.count(from) == 0) {
977  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
978  ok = false;
979  }
980  if (myEdges.count(to) == 0) {
981  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
982  ok = false;
983  }
984 }
985 
986 
987 void
989  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
991  } else {
992  WRITE_ERROR("Empty edges in roundabout.");
993  }
994 }
995 
996 
997 /****************************************************************************/
PositionVector customShape
custom shape connection
void addPhase(SUMOTime duration, const std::string &state, SUMOTime minDur, SUMOTime maxDur)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases...
static const PositionVector EMPTY
empty Vector
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.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
Definition: NBEdge.h:285
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:36
std::set< std::string > deprecatedVehicleClassesSeen
NBTypeCont & getTypeCont()
Returns a reference to the type container.
Definition: NBNetBuilder.h:160
Whether vehicles must keep the junction clear.
whether a given shape is user-defined
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:273
bool accelRamp
Whether this lane is an acceleration lane.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
const std::map< int, double > & getStopOffsets() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.h:562
root element of a network file
begin/end of the description of a junction
begin/end of the description of a single lane
bool uncontrolled
if set to true, This connection will not be TLS-controlled despite its node being controlled...
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:506
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:47
NBNodeCont & myNodeCont
The node container to fill.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:270
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3222
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
A loaded (complete) traffic light logic.
std::vector< LaneAttrs * > lanes
This edge&#39;s lanes.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3272
Describes a pedestrian crossing.
connectio between two lanes
Position intersectionPosition2D(const Position &p1, const Position &p2, const double withinDist=0.) const
Returns the position of the intersection.
double maxSpeed
The maximum velocity allowed on this lane.
const double SUMO_const_laneWidth
Definition: StdDefs.h:51
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea ...
The representation of a single edge during network building.
Definition: NBEdge.h:65
A connection description.
foe visibility distance of a link
int tlLinkIndex
The index of this connection within the controlling traffic light.
bool myCheckLaneFoesRoundabout
std::vector< std::string > response
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
link,node: the traffic light id responsible for this link
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:261
std::map< SVCPermissions, double > parseStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
Extract stopOffsets from attributes of stopOffset element.
T MAX2(T a, T b)
Definition: StdDefs.h:76
static const SUMOTime UNSPECIFIED_DURATION
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:3303
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:3346
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:589
double myLimitTurnSpeed
whether turning speed was limited in the network
double width
The width of this lane.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
bool myAmLefthand
whether the loaded network was built for lefthand traffic
const double SUMO_const_laneOffset
Definition: StdDefs.h:52
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
begins the reading of a traffic lights logic
maximum duration of a phase
const std::string & getID() const
Returns the id.
Definition: Named.h:78
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
static StringBijection< LinkState > LinkStates
link states
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1206
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1985
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:113
NIImporter_SUMO(NBNetBuilder &nb)
Constructor.
bool setStopOffsets(int lane, std::map< int, double > offsets, bool overwrite=false)
set lane and vehicle class specific stopOffset (negative lane implies set for all lanes) ...
Definition: NBEdge.cpp:3238
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
Definition: NBEdge.cpp:2025
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
Describes custom shape for a walking area during parsing.
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:258
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:42
prohibition of circulation between two edges
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
Describes the values found in a lane&#39;s definition.
The connection was computed and validated.
Definition: NBEdge.h:109
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:58
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:3295
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:3287
std::string toEdgeID
The id of the target edge.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:264
double maxSpeed
The maximum velocity allowed on this edge (!!!)
The state of a link.
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:998
void addStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
parses stop offsets for the current lane or edge
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and stores the values in "myCurrentLane".
NBNetBuilder & myNetBuilder
The network builder to fill.
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".
virtual RightOfWay getRightOfWay(bool &ok) const =0
Returns the right-of-way method.
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:496
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.
How to compute right of way.
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.
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2003
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:46
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.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2014
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
the edges of a route
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:152
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
std::vector< std::string > crossingEdges
void updateParameter(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
std::string allow
This lane&#39;s allowed vehicle classes.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
std::vector< Parameterised * > myLastParameterised
element to receive parameters
Encapsulated SAX-Attributes.
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:3022
Describes the values found in a prohibition.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
Importer for networks stored in SUMO format.
parameter associated to a certain key
std::string tlID
The id of the traffic light that controls this connection.
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:150
EdgeAttrs * myCurrentEdge
The currently parsed edge&#39;s definition (to add loaded lanes to)
A list of positions.
void parseProhibitionConnection(const std::string &attr, std::string &from, std::string &to, bool &ok)
parses connection string of a prohibition (very old school)
bool myRectLaneCut
whether all lanes of an edge should have the same stop line
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, bool reconstruct=true)
Adds a connection and immediately informs the edges.
double visibility
custom foe visibility for connection
LaneSpreadFunction lsf
The lane spread function.
bool customShape
Whether this lane has a custom shape.
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:267
T get(const std::string &str) const
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1158
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
roundabout defined in junction
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) ...
double length
The length of the edge if set explicitly.
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:243
std::string disallow
This lane&#39;s disallowed vehicle classes.
edge: the shape in xml-definition
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:555
double speed
custom speed for connection
const std::string & getProgramID() const
Returns the ProgramID.
begin/end of the description of a neighboring lane
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.
std::map< SVCPermissions, double > stopOffsets
This edge&#39;s vehicle specific stop offsets (used for lanes, that do not have a specified stopOffset) ...
std::string oppositeID
This lane&#39;s opposite lane.
void _loadNetwork(OptionsCont &oc)
load the network
description of a logic request within the junction
begin/end of the description of an edge
bool keepClear
Whether the junction must be kept clear coming from this connection.
std::vector< std::string > intLanes
double 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.
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false)
add a pedestrian crossing to this node
Definition: NBNode.cpp:2921
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:247
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape)
add custom shape for walkingArea
Definition: NBNode.cpp:2873
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:530
Importer for edge type information stored in XML.
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
virtual double getFloat(int id) const =0
Returns the double-value of the named (by its enum-value) attribute.
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.
std::vector< Connection > connections
This lane&#39;s connections.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
bool myCheckLaneFoesAll
whether foe-relationships where checked at lane-level
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.
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:143
the edges crossed by a pedestrian crossing
double contPos
custom position for internal junction on this connection
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
Instance responsible for building networks.
Definition: NBNetBuilder.h:109
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, int &index)
parses edge-id and index from lane-id
Definition: NBHelpers.cpp:121
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
int myCornerDetail
the level of corner detail in the loaded network
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:245
static Position sideOffset(const Position &beg, const Position &end, const double amount)
get a side position of position vector using a offset
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
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:92
int priority
This edge&#39;s priority.
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:379
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:79
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.
void ignore(std::string id)
mark the given edge id as ignored
Definition: NBEdgeCont.h:508
void declareConnectionsAsLoaded(EdgeBuildingStep step=LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1220
const Position & getPosition() const
Definition: NBNode.h:242
Represents a single node (junction) during network building.
Definition: NBNode.h:68
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
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.
PositionVector shape
This lane&#39;s shape (needed to reconstruct edge shape for legacy networks)
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1417
link: the index of the link within the traffic light
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
a traffic light logic
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:503
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:244
std::map< std::string, WalkingAreaParsedCustomShape > myWACustomShapes
Map from walkingArea edge IDs to custom shapes.
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and saves it.
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:170
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
bool myWalkingAreas
whether walkingareas must be built
std::set< std::string > myRailSignals
list of node id with rail signals (no NBTrafficLightDefinition exists)
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:441
int toLaneIdx
The index of the target lane.
a single phase description
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
std::map< SVCPermissions, double > stopOffsets
This lane&#39;s vehicle specific stop offsets.
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3174
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:173
TrafficLightType
Information on vClass specific stop offsets at lane end.