SUMO - Simulation of Urban MObility
NIXMLEdgesHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // Importer for network edges stored in XML
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <string>
36 #include <iostream>
37 #include <map>
38 #include <cmath>
39 #include <xercesc/sax/HandlerBase.hpp>
40 #include <xercesc/sax/AttributeList.hpp>
41 #include <xercesc/sax/SAXParseException.hpp>
42 #include <xercesc/sax/SAXException.hpp>
44 #include <netbuild/NBNodeCont.h>
45 #include <netbuild/NBTypeCont.h>
46 #include <netbuild/NBNetBuilder.h>
52 #include <utils/common/ToString.h>
55 #include "NIXMLNodesHandler.h"
56 #include "NIXMLEdgesHandler.h"
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
63  NBEdgeCont& ec,
64  NBTypeCont& tc,
65  NBDistrictCont& dc,
67  OptionsCont& options)
68  : SUMOSAXHandler("xml-edges - file"),
69  myOptions(options),
70  myNodeCont(nc),
71  myEdgeCont(ec),
72  myTypeCont(tc),
73  myDistrictCont(dc),
74  myTLLogicCont(tlc),
75  myCurrentEdge(0), myHaveReportedAboutOverwriting(false),
76  myHaveReportedAboutTypeOverride(false),
77  myHaveWarnedAboutDeprecatedLaneId(false),
78  myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
79 }
80 
81 
83 
84 
85 void
87  const SUMOSAXAttributes& attrs) {
88  switch (element) {
89  case SUMO_TAG_EDGE:
90  addEdge(attrs);
91  break;
92  case SUMO_TAG_LANE:
93  addLane(attrs);
94  break;
95  case SUMO_TAG_NEIGH:
97  break;
98  case SUMO_TAG_SPLIT:
99  addSplit(attrs);
100  break;
101  case SUMO_TAG_DELETE:
102  deleteEdge(attrs);
103  break;
104  case SUMO_TAG_ROUNDABOUT:
105  addRoundabout(attrs);
106  break;
107  default:
108  break;
109  }
110 }
111 
112 
113 void
115  myIsUpdate = false;
116  bool ok = true;
117  // initialise the edge
118  myCurrentEdge = 0;
119  mySplits.clear();
120  // get the id, report an error if not given or empty...
121  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
122  if (!ok) {
123  return;
124  }
126  // check deprecated (unused) attributes
127  // use default values, first
131  if (myCurrentEdge != 0) {
132  // update existing edge. only update lane-specific settings when explicitly requested
133  myIsUpdate = true;
137  } else {
138  // this is a completely new edge. get the type specific defaults
142  }
143  myCurrentType = "";
147  myCurrentStreetName = "";
148  myReinitKeepEdgeShape = false;
151  // check whether a type's values shall be used
152  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
153  myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
154  if (!ok) {
155  return;
156  }
157  if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
158  WRITE_ERROR("Type '" + myCurrentType + "' used by edge '" + myCurrentID + "' was not defined (ignore with option --ignore-errors.edge-type).");
159  return;
160  }
168  }
169  // use values from the edge to overwrite if existing, then
170  if (myIsUpdate) {
172  WRITE_MESSAGE("Duplicate edge id occurred ('" + myCurrentID + "'); assuming overwriting is wished.");
174  }
177  WRITE_MESSAGE("Edge '" + myCurrentID + "' changed it's type; assuming type override is wished.");
179  }
180  }
181  if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
183  myCurrentEdge = 0;
184  return;
185  }
190  myReinitKeepEdgeShape = true;
191  }
195  }
197  }
198  // speed, priority and the number of lanes have now default values;
199  // try to read the real values from the file
200  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
201  myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
202  }
203  if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
204  myCurrentSpeed = myCurrentSpeed / (double) 3.6;
205  }
206  // try to get the number of lanes
207  if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
208  myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
209  }
210  // try to get the priority
211  if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
212  myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
213  }
214  // try to get the width
215  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
216  myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
217  }
218  // try to get the offset of the stop line from the intersection
219  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
220  myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
221  }
222  // try to get the street name
223  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
224  myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
225  if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
226  myOptions.set("output.street-names", "true");
227  }
228  }
229 
230  // try to get the allowed/disallowed classes
232  std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
233  std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
234  // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
235  myPermissions = parseVehicleClasses(allowS, disallowS);
236  }
237  // try to set the nodes
238  if (!setNodes(attrs)) {
239  // return if this failed
240  return;
241  }
242  // try to get the shape
243  myShape = tryGetShape(attrs);
244  // try to get the spread type
246  // try to get the length
247  myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
248  // try to get the sidewalkWidth
250  // try to get the bikeLaneWidth
252  // insert the parsed edge into the edges map
253  if (!ok) {
254  return;
255  }
256  // check whether a previously defined edge shall be overwritten
257  if (myCurrentEdge != 0) {
263  } else {
264  // the edge must be allocated in dependence to whether a shape is given
265  if (myShape.size() == 0) {
269  } else {
274  }
275  }
279  }
280 }
281 
282 
283 void
285  if (myCurrentEdge == 0) {
286  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
287  WRITE_ERROR("Additional lane information could not be set - the edge with id '" + myCurrentID + "' is not known.");
288  }
289  return;
290  }
291  bool ok = true;
292  int lane;
293  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
294  lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
297  WRITE_WARNING("'" + toString(SUMO_ATTR_ID) + "' is deprecated, please use '" + toString(SUMO_ATTR_INDEX) + "' instead.");
298  }
299  } else {
300  lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
301  }
302  if (!ok) {
303  return;
304  }
305  // check whether this lane exists
306  if (lane >= myCurrentEdge->getNumLanes()) {
307  WRITE_ERROR("Lane index is larger than number of lanes (edge '" + myCurrentID + "').");
308  return;
309  }
310  // set information about allowed / disallowed vehicle classes (if specified)
312  const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, 0, ok, "");
313  const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, 0, ok, "");
314  myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
315  }
316  if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
317  const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, 0, ok);
319  }
320  // try to get the width
321  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
322  myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
323  }
324  // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
325  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
326  myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
327  }
328  // try to get lane specific speed (should not occur for german networks)
329  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
330  myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
331  }
332  // check whether this is an acceleration lane
334  myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
335  }
336 
337  // check whether this is an acceleration lane
338  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
339  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
341  const std::string laneID = myCurrentID + "_" + toString(lane);
342  WRITE_ERROR("Unable to project coordinates for lane '" + laneID + "'.");
343  }
344  myCurrentEdge->setLaneShape(lane, shape);
345  }
346 }
347 
348 
350  if (myCurrentEdge == 0) {
351  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
352  WRITE_WARNING("Ignoring 'split' because it cannot be assigned to an edge");
353  }
354  return;
355  }
356  bool ok = true;
357  Split e;
358  e.pos = attrs.get<double>(SUMO_ATTR_POSITION, 0, ok);
359  if (ok) {
360  if (fabs(e.pos) > myCurrentEdge->getGeometry().length()) {
361  WRITE_ERROR("Edge '" + myCurrentID + "' has a split at invalid position " + toString(e.pos) + ".");
362  return;
363  }
364  std::vector<Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
365  if (i != mySplits.end()) {
366  WRITE_ERROR("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + ".");
367  return;
368  }
369  e.nameID = myCurrentID + "." + toString((int)e.pos);
370  if (e.pos < 0) {
372  }
373  std::vector<std::string> lanes;
374  SUMOSAXAttributes::parseStringVector(attrs.getOpt<std::string>(SUMO_ATTR_LANES, 0, ok, ""), lanes);
375  for (std::vector<std::string>::iterator i = lanes.begin(); i != lanes.end(); ++i) {
376  try {
377  int lane = TplConvert::_2int((*i).c_str());
378  e.lanes.push_back(lane);
379  } catch (NumberFormatException&) {
380  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
381  } catch (EmptyData&) {
382  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
383  }
384  }
385  if (e.lanes.empty()) {
386  for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
387  e.lanes.push_back(l);
388  }
389  }
390  e.speed = attrs.getOpt(SUMO_ATTR_SPEED, 0, ok, myCurrentEdge->getSpeed());
391  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
392  e.speed /= (double) 3.6;
393  }
394  e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, 0, ok, std::string(""));
395  e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, 0, ok, std::string(""));
396  if (!ok) {
397  return;
398  }
399  const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, 0, ok, e.nameID);
400  e.node = myNodeCont.retrieve(nodeID);
401  if (e.node == 0) {
402  e.node = new NBNode(nodeID, myCurrentEdge->getGeometry().positionAtOffset(e.pos));
403  }
406  mySplits.push_back(e);
407  }
408 }
409 
410 
411 bool
413  // the names and the coordinates of the beginning and the end node
414  // may be found, try
415  bool ok = true;
416  std::string begNodeID = myIsUpdate ? myCurrentEdge->getFromNode()->getID() : "";
417  std::string endNodeID = myIsUpdate ? myCurrentEdge->getToNode()->getID() : "";
418  std::string oldBegID = begNodeID;
419  std::string oldEndID = endNodeID;
420  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
421  begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
422  } else if (!myIsUpdate) {
423  WRITE_ERROR("The from-node is not given for edge '" + myCurrentID + "'.");
424  ok = false;
425  }
426  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
427  endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
428  } else if (!myIsUpdate) {
429  WRITE_ERROR("The to-node is not given for edge '" + myCurrentID + "'.");
430  ok = false;
431  }
432  if (!ok) {
433  return false;
434  }
435  myFromNode = myNodeCont.retrieve(begNodeID);
436  myToNode = myNodeCont.retrieve(endNodeID);
437  if (myFromNode == 0) {
438  WRITE_ERROR("Edge's '" + myCurrentID + "' from-node '" + begNodeID + "' is not known.");
439  }
440  if (myToNode == 0) {
441  WRITE_ERROR("Edge's '" + myCurrentID + "' to-node '" + endNodeID + "' is not known.");
442  }
443  if (myFromNode != 0 && myToNode != 0) {
444  if (myIsUpdate && (myFromNode->getID() != oldBegID || myToNode->getID() != oldEndID)) {
446  }
447  }
448  return myFromNode != 0 && myToNode != 0;
449 }
450 
451 
454  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
455  return myShape;
456  }
457  // try to build shape
458  bool ok = true;
459  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
460  myReinitKeepEdgeShape = false;
461  return PositionVector();
462  }
465  WRITE_ERROR("Unable to project coordinates for edge '" + myCurrentID + "'.");
466  }
468  return shape;
469 }
470 
471 
474  bool ok = true;
476  std::string lsfS = toString(result);
477  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
478  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
480  } else {
481  WRITE_WARNING("Ignoring unknown spreadType '" + lsfS + "' for edge '" + myCurrentID + "'.");
482  }
483  return result;
484 }
485 
486 
487 void
489  bool ok = true;
490  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
491  if (!ok) {
492  return;
493  }
495  if (edge == 0) {
496  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DELETE) + "' for unknown edge '" +
497  myCurrentID + "'");
498  return;
499  }
500  const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
501  if (lane < 0) {
502  myEdgeCont.extract(myDistrictCont, edge, true);
503  } else {
504  edge->removeFromConnections(0, lane, -1, false, true);
505  const EdgeVector incoming = edge->getIncomingEdges();
506  for (EdgeVector::const_iterator e = incoming.begin(); e != incoming.end(); ++e) {
507  (*e)->removeFromConnections(edge, -1, lane, false, true);
508  }
509  edge->deleteLane(lane, false);
510  }
511 }
512 
513 
514 void
516  if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) {
517  // add bike lane, wait until lanes are loaded to avoid building if it already exists
520  }
521  // add sidewalk, wait until lanes are loaded to avoid building if it already exists
524  }
525  if (!myIsUpdate) {
526  try {
528  WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'");
529  delete myCurrentEdge;
530  }
531  } catch (InvalidArgument& e) {
532  WRITE_ERROR(e.what());
533  throw;
534  } catch (...) {
535  WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'.");
536  }
537  }
538  if (mySplits.size() != 0) {
539  std::vector<Split>::iterator i;
540  NBEdge* e = myCurrentEdge;
541  sort(mySplits.begin(), mySplits.end(), split_sorter());
542  int noLanesMax = e->getNumLanes();
543  // compute the node positions and sort the lanes
544  for (i = mySplits.begin(); i != mySplits.end(); ++i) {
545  sort((*i).lanes.begin(), (*i).lanes.end());
546  noLanesMax = MAX2(noLanesMax, (int)(*i).lanes.size());
547  }
548  // split the edge
549  std::vector<int> currLanes;
550  for (int l = 0; l < e->getNumLanes(); ++l) {
551  currLanes.push_back(l);
552  }
553  if (e->getNumLanes() != (int)mySplits.back().lanes.size()) {
554  // invalidate traffic light definitions loaded from a SUMO network
555  e->getToNode()->invalidateTLS(myTLLogicCont, true, true);
556  // if the number of lanes changes the connections should be
557  // recomputed
558  e->invalidateConnections(true);
559  }
560 
561  std::string firstID = "";
562  double seen = 0;
563  for (i = mySplits.begin(); i != mySplits.end(); ++i) {
564  const Split& exp = *i;
565  assert(exp.lanes.size() != 0);
566  if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) {
567  myNodeCont.insert(exp.node);
569  // split the edge
570  std::string idBefore = exp.idBefore == "" ? e->getID() : exp.idBefore;
571  std::string idAfter = exp.idAfter == "" ? exp.nameID : exp.idAfter;
572  if (firstID == "") {
573  firstID = idBefore;
574  }
575  const bool ok = myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, exp.node,
576  idBefore, idAfter, e->getNumLanes(), (int) exp.lanes.size(), exp.speed);
577  if (!ok) {
578  WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "').");
579  }
580  seen = exp.pos;
581  std::vector<int> newLanes = exp.lanes;
582  NBEdge* pe = myEdgeCont.retrieve(idBefore);
583  NBEdge* ne = myEdgeCont.retrieve(idAfter);
584  // reconnect lanes
585  pe->invalidateConnections(true);
586  // new on right
587  int rightMostP = currLanes[0];
588  int rightMostN = newLanes[0];
589  for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) {
590  pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
591  }
592  // new on left
593  int leftMostP = currLanes.back();
594  int leftMostN = newLanes.back();
595  for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) {
596  pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true);
597  }
598  // all other connected
599  for (int l = 0; l < noLanesMax; ++l) {
600  if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
601  continue;
602  }
603  if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
604  continue;
605  }
606  pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true);
607  }
608  // move to next
609  e = ne;
610  currLanes = newLanes;
611  } else if (exp.pos == 0) {
612  const int laneCountDiff = e->getNumLanes() - (int)exp.lanes.size();
613  if (laneCountDiff < 0) {
614  e->incLaneNo(-laneCountDiff);
615  } else {
616  e->decLaneNo(laneCountDiff);
617  }
618  currLanes = exp.lanes;
619  // invalidate traffic light definition loaded from a SUMO network
620  // XXX it would be preferable to reconstruct the phase definitions heuristically
621  e->getFromNode()->invalidateTLS(myTLLogicCont, true, true);
622  } else {
623  WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "').");
624  }
625  }
626  // patch lane offsets
627  e = myEdgeCont.retrieve(firstID);
628  if (mySplits.front().pos != 0) {
629  // add a dummy split at the beginning to ensure correct offset
630  Split start;
631  start.pos = 0;
632  for (int lane = 0; lane < (int)e->getNumLanes(); ++lane) {
633  start.lanes.push_back(lane);
634  }
635  mySplits.insert(mySplits.begin(), start);
636  }
637  i = mySplits.begin();
638  for (; i != mySplits.end(); ++i) {
639  int maxLeft = (*i).lanes.back();
640  double offset = 0;
641  if (maxLeft < noLanesMax) {
643  offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft);
644  } else {
645  offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft);
646  }
647  }
648  int maxRight = (*i).lanes.front();
649  if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) {
650  offset -= SUMO_const_halfLaneAndOffset * maxRight;
651  }
652  if (offset != 0) {
653  PositionVector g = e->getGeometry();
654  g.move2side(offset);
655  e->setGeometry(g);
656  }
657  if (e->getToNode()->getOutgoingEdges().size() != 0) {
658  e = e->getToNode()->getOutgoingEdges()[0];
659  }
660  }
661  }
662  myCurrentEdge = 0;
663  }
664 }
665 
666 
667 void
669  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
670  std::vector<std::string> edgeIDs = attrs.getStringVector(SUMO_ATTR_EDGES);
671  EdgeSet roundabout;
672  for (std::vector<std::string>::iterator it = edgeIDs.begin(); it != edgeIDs.end(); ++it) {
673  NBEdge* edge = myEdgeCont.retrieve(*it);
674  if (edge == 0) {
675  if (!myEdgeCont.wasIgnored(*it)) {
676  WRITE_ERROR("Unknown edge '" + (*it) + "' in roundabout");
677  }
678  } else {
679  roundabout.insert(edge);
680  }
681  }
682  myEdgeCont.addRoundabout(roundabout);
683  } else {
684  WRITE_ERROR("Empty edges in roundabout.");
685  }
686 }
687 
688 
689 
690 /****************************************************************************/
691 
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1254
The information about how to spread the lanes from the given position.
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:972
LaneSpreadFunction myLanesSpread
Information about how to spread the lanes.
split something
Finds a split at the given position.
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:271
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:500
begin/end of the description of a single lane
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2913
std::string myCurrentID
The current edge&#39;s id.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
void markAsSplit(const NBNode *node)
mark a node as being created form a split
Definition: NBNodeCont.h:285
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:491
PositionVector myShape
The shape of the edge.
A container for traffic light definitions and built programs.
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2929
double getWidth(const std::string &type) const
Returns the lane width for the given type [m].
Definition: NBTypeCont.cpp:217
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
bool setNodes(const SUMOSAXAttributes &attrs)
Sets from/to node information of the currently parsed edge.
const double SUMO_const_halfLaneAndOffset
Definition: StdDefs.h:55
double myCurrentSpeed
The current edge&#39;s maximum speed.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:71
const double SUMO_const_laneWidthAndOffset
Definition: StdDefs.h:54
NBNode * myFromNode
The nodes the edge starts and ends at.
A container for districts.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
Definition: NBEdge.cpp:1132
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:259
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1187
NIXMLEdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, OptionsCont &options)
Constructor.
T MAX2(T a, T b)
Definition: StdDefs.h:74
bool myHaveReportedAboutOverwriting
Information whether at least one edge&#39;s attributes were overwritten.
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:2960
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:508
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:3003
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:416
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
NBDistrictCont & myDistrictCont
The districts container (needed if an edge must be split)
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1161
SAX-handler base for SUMO-files.
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:3086
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:524
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:256
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The connection was computed and validated.
Definition: NBEdge.h:115
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:2952
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:2944
const bool myKeepEdgeShape
Whether the edge shape shall be kept generally.
bool myReinitKeepEdgeShape
Whether the edge shape shall be kept at reinitilization.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
~NIXMLEdgesHandler()
Destructor.
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:262
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:248
const std::string & getID() const
Returns the id.
Definition: Named.h:66
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
Definition: NBNode.cpp:338
void incLaneNo(int by)
increment lane
Definition: NBEdge.cpp:2790
static void parseStringVector(const std::string &def, std::vector< std::string > &into)
Splits the given string.
const Position & getPosition() const
Definition: NBNode.h:235
std::vector< Split > mySplits
The list of this edge&#39;s splits.
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:51
the edges of a route
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:421
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:158
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
bool myHaveWarnedAboutDeprecatedLaneId
void decLaneNo(int by)
decrement lane
Definition: NBEdge.cpp:2816
Encapsulated SAX-Attributes.
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
Definition: NBEdgeCont.cpp:392
void deleteEdge(const SUMOSAXAttributes &attrs)
parses delete tag and deletes the specified edge or lane
int getNumLanes(const std::string &type) const
Returns the number of lanes for the given type.
Definition: NBTypeCont.cpp:175
void deleteLane(int index, bool recompute=true)
delete lane
Definition: NBEdge.cpp:2801
A structure which describes changes of lane number or speed along the road.
A list of positions.
double pos
The position of this change.
void addSplit(const SUMOSAXAttributes &attrs)
Parses a split and stores it in mySplits. Splits are executed Upon reading the end tag of an edge...
std::string nameID
the default node id
std::string myCurrentType
The current edge&#39;s type.
int getPriority(const std::string &type) const
Returns the priority for the given type.
Definition: NBTypeCont.cpp:187
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:501
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:414
double length() const
Returns the length.
double myLength
The current edge&#39;s length.
roundabout defined in junction
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
std::vector< int > lanes
The lanes after this change.
double myCurrentEndOffset
The current edge&#39;s offset till the destination node.
NBNodeCont & myNodeCont
The nodes container (for retrieval of referenced nodes)
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...
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to (when invalidating tls because of splits) ...
static void processNodeType(const SUMOSAXAttributes &attrs, NBNode *node, const std::string &nodeID, const Position &position, bool updateEdgeGeometries, NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
parses node attributes (not related to positioning)
Sorts splits by their position (increasing)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:75
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
LaneSpreadFunction tryGetLaneSpread(const SUMOSAXAttributes &attrs)
Tries to parse the spread type.
begin/end of the description of a neighboring lane
void reinit(NBNode *from, NBNode *to, const std::string &type, double speed, int nolanes, int priority, PositionVector geom, double width, double offset, const std::string &streetName, LaneSpreadFunction spread=LANESPREAD_RIGHT, bool tryIgnoreNodePositions=false)
Resets initial values.
Definition: NBEdge.cpp:328
double myBikeLaneWidth
The width of the bike lane that shall be added to the current edge.
void move2side(double amount)
move position vector to side using certain ammount
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
begin/end of the description of an edge
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:156
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:435
double getSidewalkWidth(const std::string &type) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:223
SVCPermissions myPermissions
Information about lane permissions.
std::string idAfter
The id for the edge after the split.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
bool myIsUpdate
Whether this edge definition is an update of a previously inserted edge.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:41
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:2974
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:596
void myEndElement(int element)
Called when a closing tag occurs.
A storage for options typed value containers)
Definition: OptionsCont.h:99
NBEdge * myCurrentEdge
The currently processed edge.
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:385
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:77
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:3098
OptionsCont & myOptions
A reference to the program&#39;s options.
double myCurrentWidth
The current edge&#39;s lane width.
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge&#39;s lateral offset shal...
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)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:913
double speed
The speed after this change.
NBTypeCont & myTypeCont
The types container (for retrieval of type defaults)
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:678
Represents a single node (junction) during network building.
Definition: NBNode.h:75
T get(const std::string &str) const
bool myHaveReportedAboutTypeOverride
Information whether at least one edge&#39;s type was changed.
double getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
Definition: NBTypeCont.cpp:181
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:474
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
NBEdgeCont & myEdgeCont
The edges container (for insertion of build edges)
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:106
int myCurrentLaneNo
The current edge&#39;s number of lanes.
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Definition: NBTypeCont.cpp:211
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
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 myCurrentStreetName
The current edge&#39;s street name.
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
delete certain element
double mySidewalkWidth
The width of the sidewalk that shall be added to the current edge.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
std::string idBefore
The id for the edge before the split.
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:537
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and modifies myCurrentEdge according to the given attribures.
int myCurrentPriority
The current edge&#39;s priority.
NBNode * node
The new node that is created for this split.
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2874
A storage for available types of edges.
Definition: NBTypeCont.h:62
PositionVector tryGetShape(const SUMOSAXAttributes &attrs)
Tries to parse the shape definition.
double getBikeLaneWidth(const std::string &type) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:229
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:428