SUMO - Simulation of Urban MObility
NIXMLEdgesHandler.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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
21 // Importer for network edges stored in XML
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <iostream>
36 #include <map>
37 #include <cmath>
38 #include <xercesc/sax/HandlerBase.hpp>
39 #include <xercesc/sax/AttributeList.hpp>
40 #include <xercesc/sax/SAXParseException.hpp>
41 #include <xercesc/sax/SAXException.hpp>
43 #include <netbuild/NBNodeCont.h>
44 #include <netbuild/NBTypeCont.h>
45 #include <netbuild/NBNetBuilder.h>
51 #include <utils/common/ToString.h>
54 #include "NIXMLNodesHandler.h"
55 #include "NIXMLEdgesHandler.h"
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
62  NBEdgeCont& ec,
63  NBTypeCont& tc,
64  NBDistrictCont& dc,
66  OptionsCont& options) :
67  SUMOSAXHandler("xml-edges - file"),
68  myOptions(options),
69  myNodeCont(nc),
70  myEdgeCont(ec),
71  myTypeCont(tc),
72  myDistrictCont(dc),
73  myTLLogicCont(tlc),
74  myCurrentEdge(0), myHaveReportedAboutOverwriting(false),
75  myHaveReportedAboutTypeOverride(false),
76  myHaveWarnedAboutDeprecatedLaneId(false),
77  myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
78 }
79 
80 
82 
83 
84 void
86  const SUMOSAXAttributes& attrs) {
87  switch (element) {
88  case SUMO_TAG_EDGE:
89  addEdge(attrs);
90  break;
91  case SUMO_TAG_LANE:
92  addLane(attrs);
93  break;
94  case SUMO_TAG_NEIGH:
96  break;
97  case SUMO_TAG_SPLIT:
98  addSplit(attrs);
99  break;
100  case SUMO_TAG_DELETE:
101  deleteEdge(attrs);
102  break;
103  case SUMO_TAG_ROUNDABOUT:
104  addRoundabout(attrs);
105  break;
106  case SUMO_TAG_PARAM:
107  if (myLastParameterised.size() != 0) {
108  bool ok = true;
109  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, 0, ok);
110  // circumventing empty string test
111  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
112  myLastParameterised.back()->setParameter(key, val);
113  }
114  default:
115  break;
116  }
117 }
118 
119 
120 void
122  myIsUpdate = false;
123  bool ok = true;
124  // initialise the edge
125  myCurrentEdge = 0;
126  mySplits.clear();
127  // get the id, report an error if not given or empty...
128  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
129  if (!ok) {
130  return;
131  }
133  // check deprecated (unused) attributes
134  // use default values, first
138  if (myCurrentEdge != 0) {
139  // update existing edge. only update lane-specific settings when explicitly requested
140  myIsUpdate = true;
144  } else {
145  // this is a completely new edge. get the type specific defaults
149  }
150  myCurrentType = "";
154  myCurrentStreetName = "";
155  myReinitKeepEdgeShape = false;
158  // check whether a type's values shall be used
159  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
160  myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
161  if (!ok) {
162  return;
163  }
164  if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
165  WRITE_ERROR("Type '" + myCurrentType + "' used by edge '" + myCurrentID + "' was not defined (ignore with option --ignore-errors.edge-type).");
166  return;
167  }
175  }
176  // use values from the edge to overwrite if existing, then
177  if (myIsUpdate) {
179  WRITE_MESSAGE("Duplicate edge id occurred ('" + myCurrentID + "'); assuming overwriting is wished.");
181  }
184  WRITE_MESSAGE("Edge '" + myCurrentID + "' changed it's type; assuming type override is wished.");
186  }
187  }
188  if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
190  myCurrentEdge = 0;
191  return;
192  }
197  myReinitKeepEdgeShape = true;
198  }
202  }
204  }
205  // speed, priority and the number of lanes have now default values;
206  // try to read the real values from the file
207  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
208  myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
209  }
210  if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
211  myCurrentSpeed = myCurrentSpeed / (double) 3.6;
212  }
213  // try to get the number of lanes
214  if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
215  myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
216  }
217  // try to get the priority
218  if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
219  myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
220  }
221  // try to get the width
222  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
223  myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
224  }
225  // try to get the offset of the stop line from the intersection
226  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
227  myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
228  }
229  // try to get the street name
230  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
231  myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
232  if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
233  myOptions.set("output.street-names", "true");
234  }
235  }
236 
237  // try to get the allowed/disallowed classes
239  std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
240  std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
241  // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
242  myPermissions = parseVehicleClasses(allowS, disallowS);
243  }
244  // try to set the nodes
245  if (!setNodes(attrs)) {
246  // return if this failed
247  return;
248  }
249  // try to get the shape
250  myShape = tryGetShape(attrs);
251  // try to get the spread type
253  // try to get the length
254  myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
255  // try to get the sidewalkWidth
257  // try to get the bikeLaneWidth
259  // insert the parsed edge into the edges map
260  if (!ok) {
261  return;
262  }
263  // check whether a previously defined edge shall be overwritten
264  if (myCurrentEdge != 0) {
270  } else {
271  // the edge must be allocated in dependence to whether a shape is given
272  if (myShape.size() == 0) {
276  } else {
281  }
282  }
286  }
288 }
289 
290 
291 void
293  if (myCurrentEdge == 0) {
294  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
295  WRITE_ERROR("Additional lane information could not be set - the edge with id '" + myCurrentID + "' is not known.");
296  }
297  return;
298  }
299  bool ok = true;
300  int lane;
301  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
302  lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
305  WRITE_WARNING("'" + toString(SUMO_ATTR_ID) + "' is deprecated, please use '" + toString(SUMO_ATTR_INDEX) + "' instead.");
306  }
307  } else {
308  lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
309  }
310  if (!ok) {
311  return;
312  }
313  // check whether this lane exists
314  if (lane >= myCurrentEdge->getNumLanes()) {
315  WRITE_ERROR("Lane index is larger than number of lanes (edge '" + myCurrentID + "').");
316  return;
317  }
318  // set information about allowed / disallowed vehicle classes (if specified)
320  const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, 0, ok, "");
321  const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, 0, ok, "");
322  myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
323  }
324  if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
325  const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, 0, ok);
327  }
328  // try to get the width
329  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
330  myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
331  }
332  // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
333  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
334  myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
335  }
336  // try to get lane specific speed (should not occur for german networks)
337  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
338  myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
339  }
340  // check whether this is an acceleration lane
342  myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
343  }
344 
345  // check whether this is an acceleration lane
346  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
347  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
349  const std::string laneID = myCurrentID + "_" + toString(lane);
350  WRITE_ERROR("Unable to project coordinates for lane '" + laneID + "'.");
351  }
352  myCurrentEdge->setLaneShape(lane, shape);
353  }
355 }
356 
357 
359  if (myCurrentEdge == 0) {
360  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
361  WRITE_WARNING("Ignoring 'split' because it cannot be assigned to an edge");
362  }
363  return;
364  }
365  bool ok = true;
366  Split e;
367  e.pos = attrs.get<double>(SUMO_ATTR_POSITION, 0, ok);
368  if (ok) {
369  if (fabs(e.pos) > myCurrentEdge->getGeometry().length()) {
370  WRITE_ERROR("Edge '" + myCurrentID + "' has a split at invalid position " + toString(e.pos) + ".");
371  return;
372  }
373  std::vector<Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
374  if (i != mySplits.end()) {
375  WRITE_ERROR("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + ".");
376  return;
377  }
378  e.nameID = myCurrentID + "." + toString((int)e.pos);
379  if (e.pos < 0) {
381  }
382  std::vector<std::string> lanes;
383  SUMOSAXAttributes::parseStringVector(attrs.getOpt<std::string>(SUMO_ATTR_LANES, 0, ok, ""), lanes);
384  for (std::vector<std::string>::iterator i = lanes.begin(); i != lanes.end(); ++i) {
385  try {
386  int lane = TplConvert::_2int((*i).c_str());
387  e.lanes.push_back(lane);
388  } catch (NumberFormatException&) {
389  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
390  } catch (EmptyData&) {
391  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
392  }
393  }
394  if (e.lanes.empty()) {
395  for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
396  e.lanes.push_back(l);
397  }
398  }
399  e.speed = attrs.getOpt(SUMO_ATTR_SPEED, 0, ok, myCurrentEdge->getSpeed());
400  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
401  e.speed /= (double) 3.6;
402  }
403  e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, 0, ok, std::string(""));
404  e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, 0, ok, std::string(""));
405  if (!ok) {
406  return;
407  }
408  const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, 0, ok, e.nameID);
409  e.node = myNodeCont.retrieve(nodeID);
410  if (e.node == 0) {
411  e.node = new NBNode(nodeID, myCurrentEdge->getGeometry().positionAtOffset(e.pos));
412  }
415  mySplits.push_back(e);
416  }
417 }
418 
419 
420 bool
422  // the names and the coordinates of the beginning and the end node
423  // may be found, try
424  bool ok = true;
425  std::string begNodeID = myIsUpdate ? myCurrentEdge->getFromNode()->getID() : "";
426  std::string endNodeID = myIsUpdate ? myCurrentEdge->getToNode()->getID() : "";
427  std::string oldBegID = begNodeID;
428  std::string oldEndID = endNodeID;
429  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
430  begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
431  } else if (!myIsUpdate) {
432  WRITE_ERROR("The from-node is not given for edge '" + myCurrentID + "'.");
433  ok = false;
434  }
435  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
436  endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
437  } else if (!myIsUpdate) {
438  WRITE_ERROR("The to-node is not given for edge '" + myCurrentID + "'.");
439  ok = false;
440  }
441  if (!ok) {
442  return false;
443  }
444  myFromNode = myNodeCont.retrieve(begNodeID);
445  myToNode = myNodeCont.retrieve(endNodeID);
446  if (myFromNode == 0) {
447  WRITE_ERROR("Edge's '" + myCurrentID + "' from-node '" + begNodeID + "' is not known.");
448  }
449  if (myToNode == 0) {
450  WRITE_ERROR("Edge's '" + myCurrentID + "' to-node '" + endNodeID + "' is not known.");
451  }
452  if (myFromNode != 0 && myToNode != 0) {
453  if (myIsUpdate && (myFromNode->getID() != oldBegID || myToNode->getID() != oldEndID)) {
455  }
456  }
457  return myFromNode != 0 && myToNode != 0;
458 }
459 
460 
463  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
464  return myShape;
465  }
466  // try to build shape
467  bool ok = true;
468  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
469  myReinitKeepEdgeShape = false;
470  return PositionVector();
471  }
474  WRITE_ERROR("Unable to project coordinates for edge '" + myCurrentID + "'.");
475  }
477  return shape;
478 }
479 
480 
483  bool ok = true;
485  std::string lsfS = toString(result);
486  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
487  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
489  } else {
490  WRITE_WARNING("Ignoring unknown spreadType '" + lsfS + "' for edge '" + myCurrentID + "'.");
491  }
492  return result;
493 }
494 
495 
496 void
498  bool ok = true;
499  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
500  if (!ok) {
501  return;
502  }
504  if (edge == 0) {
505  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DELETE) + "' for unknown edge '" +
506  myCurrentID + "'");
507  return;
508  }
509  const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
510  if (lane < 0) {
511  myEdgeCont.extract(myDistrictCont, edge, true);
512  } else {
513  edge->removeFromConnections(0, lane, -1, false, true);
514  const EdgeVector incoming = edge->getIncomingEdges();
515  for (EdgeVector::const_iterator e = incoming.begin(); e != incoming.end(); ++e) {
516  (*e)->removeFromConnections(edge, -1, lane, false, true);
517  }
518  edge->deleteLane(lane, false);
519  }
520 }
521 
522 
523 void
525  if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) {
526  myLastParameterised.pop_back();
527  // add bike lane, wait until lanes are loaded to avoid building if it already exists
530  }
531  // add sidewalk, wait until lanes are loaded to avoid building if it already exists
534  }
535  if (!myIsUpdate) {
536  try {
538  WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'");
539  delete myCurrentEdge;
540  }
541  } catch (InvalidArgument& e) {
542  WRITE_ERROR(e.what());
543  throw;
544  } catch (...) {
545  WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'.");
546  }
547  }
548  if (mySplits.size() != 0) {
549  std::vector<Split>::iterator i;
550  NBEdge* e = myCurrentEdge;
551  sort(mySplits.begin(), mySplits.end(), split_sorter());
552  int noLanesMax = e->getNumLanes();
553  // compute the node positions and sort the lanes
554  for (i = mySplits.begin(); i != mySplits.end(); ++i) {
555  sort((*i).lanes.begin(), (*i).lanes.end());
556  noLanesMax = MAX2(noLanesMax, (int)(*i).lanes.size());
557  }
558  // split the edge
559  std::vector<int> currLanes;
560  for (int l = 0; l < e->getNumLanes(); ++l) {
561  currLanes.push_back(l);
562  }
563  if (e->getNumLanes() != (int)mySplits.back().lanes.size()) {
564  // invalidate traffic light definitions loaded from a SUMO network
565  e->getToNode()->invalidateTLS(myTLLogicCont, true, true);
566  // if the number of lanes changes the connections should be
567  // recomputed
568  e->invalidateConnections(true);
569  }
570 
571  std::string firstID = "";
572  double seen = 0;
573  for (i = mySplits.begin(); i != mySplits.end(); ++i) {
574  const Split& exp = *i;
575  assert(exp.lanes.size() != 0);
576  if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) {
577  myNodeCont.insert(exp.node);
579  // split the edge
580  std::string idBefore = exp.idBefore == "" ? e->getID() : exp.idBefore;
581  std::string idAfter = exp.idAfter == "" ? exp.nameID : exp.idAfter;
582  if (firstID == "") {
583  firstID = idBefore;
584  }
585  const bool ok = myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, exp.node,
586  idBefore, idAfter, e->getNumLanes(), (int) exp.lanes.size(), exp.speed);
587  if (!ok) {
588  WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "').");
589  }
590  seen = exp.pos;
591  std::vector<int> newLanes = exp.lanes;
592  NBEdge* pe = myEdgeCont.retrieve(idBefore);
593  NBEdge* ne = myEdgeCont.retrieve(idAfter);
594  // reconnect lanes
595  pe->invalidateConnections(true);
596  // new on right
597  int rightMostP = currLanes[0];
598  int rightMostN = newLanes[0];
599  for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) {
600  pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
601  }
602  // new on left
603  int leftMostP = currLanes.back();
604  int leftMostN = newLanes.back();
605  for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) {
606  pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true);
607  }
608  // all other connected
609  for (int l = 0; l < noLanesMax; ++l) {
610  if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
611  continue;
612  }
613  if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
614  continue;
615  }
616  pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true);
617  }
618  // move to next
619  e = ne;
620  currLanes = newLanes;
621  } else if (exp.pos == 0) {
622  const int laneCountDiff = e->getNumLanes() - (int)exp.lanes.size();
623  if (laneCountDiff < 0) {
624  e->incLaneNo(-laneCountDiff);
625  } else {
626  e->decLaneNo(laneCountDiff);
627  }
628  currLanes = exp.lanes;
629  // invalidate traffic light definition loaded from a SUMO network
630  // XXX it would be preferable to reconstruct the phase definitions heuristically
631  e->getFromNode()->invalidateTLS(myTLLogicCont, true, true);
632  } else {
633  WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "').");
634  }
635  }
636  // patch lane offsets
637  e = myEdgeCont.retrieve(firstID);
638  if (mySplits.front().pos != 0) {
639  // add a dummy split at the beginning to ensure correct offset
640  Split start;
641  start.pos = 0;
642  for (int lane = 0; lane < (int)e->getNumLanes(); ++lane) {
643  start.lanes.push_back(lane);
644  }
645  mySplits.insert(mySplits.begin(), start);
646  }
647  i = mySplits.begin();
648  for (; i != mySplits.end(); ++i) {
649  int maxLeft = (*i).lanes.back();
650  double offset = 0;
651  if (maxLeft < noLanesMax) {
653  offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft);
654  } else {
655  offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft);
656  }
657  }
658  int maxRight = (*i).lanes.front();
659  if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) {
660  offset -= SUMO_const_halfLaneAndOffset * maxRight;
661  }
662  if (offset != 0) {
663  PositionVector g = e->getGeometry();
664  g.move2side(offset);
665  e->setGeometry(g);
666  }
667  if (e->getToNode()->getOutgoingEdges().size() != 0) {
668  e = e->getToNode()->getOutgoingEdges()[0];
669  }
670  }
671  }
672  myCurrentEdge = 0;
673  } else if (element == SUMO_TAG_LANE) {
674  myLastParameterised.pop_back();
675  }
676 }
677 
678 
679 void
681  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
682  std::vector<std::string> edgeIDs = attrs.getStringVector(SUMO_ATTR_EDGES);
683  EdgeSet roundabout;
684  for (std::vector<std::string>::iterator it = edgeIDs.begin(); it != edgeIDs.end(); ++it) {
685  NBEdge* edge = myEdgeCont.retrieve(*it);
686  if (edge == 0) {
687  if (!myEdgeCont.wasIgnored(*it)) {
688  WRITE_ERROR("Unknown edge '" + (*it) + "' in roundabout");
689  }
690  } else {
691  roundabout.insert(edge);
692  }
693  }
694  myEdgeCont.addRoundabout(roundabout);
695  } else {
696  WRITE_ERROR("Empty edges in roundabout.");
697  }
698 }
699 
700 
701 
702 /****************************************************************************/
703 
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:684
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1268
The information about how to spread the lanes from the given position.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
double getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
Definition: NBTypeCont.cpp:180
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:269
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
Definition: NBEdge.cpp:1146
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:2950
std::string myCurrentID
The current edge&#39;s id.
static NBNode * 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)
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
void markAsSplit(const NBNode *node)
mark a node as being created form a split
Definition: NBNodeCont.h:291
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:2966
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.
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:419
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:982
const double SUMO_const_halfLaneAndOffset
Definition: StdDefs.h:54
double myCurrentSpeed
The current edge&#39;s maximum speed.
The representation of a single edge during network building.
Definition: NBEdge.h:70
const double SUMO_const_laneWidthAndOffset
Definition: StdDefs.h:53
int getPriority(const std::string &type) const
Returns the priority for the given type.
Definition: NBTypeCont.cpp:186
NBNode * myFromNode
The nodes the edge starts and ends at.
A container for districts.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:257
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:1201
NIXMLEdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, OptionsCont &options)
Constructor.
T MAX2(T a, T b)
Definition: StdDefs.h:73
bool myHaveReportedAboutOverwriting
Information whether at least one edge&#39;s attributes were overwritten.
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:499
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:2997
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:3040
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:415
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
int getNumLanes(const std::string &type) const
Returns the number of lanes for the given type.
Definition: NBTypeCont.cpp:174
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
Definition: Named.h:74
NBDistrictCont & myDistrictCont
The districts container (needed if an edge must be split)
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:1177
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:3152
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:532
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:254
std::vector< Parameterised * > myLastParameterised
element to receive parameters
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
The connection was computed and validated.
Definition: NBEdge.h:114
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:2989
double getWidth(const std::string &type) const
Returns the lane width for the given type [m].
Definition: NBTypeCont.cpp:216
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:2981
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
const bool myKeepEdgeShape
Whether the edge shape shall be kept generally.
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:254
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:260
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
Definition: NBNode.cpp:347
void incLaneNo(int by)
increment lane
Definition: NBEdge.cpp:2827
static void parseStringVector(const std::string &def, std::vector< std::string > &into)
Splits the given string.
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:74
double getBikeLaneWidth(const std::string &type) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:228
std::vector< Split > mySplits
The list of this edge&#39;s splits.
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
the edges of a route
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:157
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
double getSidewalkWidth(const std::string &type) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:222
bool myHaveWarnedAboutDeprecatedLaneId
void decLaneNo(int by)
decrement lane
Definition: NBEdge.cpp:2853
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
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:391
void deleteEdge(const SUMOSAXAttributes &attrs)
parses delete tag and deletes the specified edge or lane
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:412
parameter associated to a certain key
void deleteLane(int index, bool recompute=true)
delete lane
Definition: NBEdge.cpp:2838
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
T get(const std::string &str) const
std::string myCurrentType
The current edge&#39;s type.
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:508
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.
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:535
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) ...
Sorts splits by their position (increasing)
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:333
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
begin/end of the description of an edge
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:506
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:602
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:155
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.
SVCPermissions myPermissions
Information about lane permissions.
std::string idAfter
The id for the edge after the split.
double length() const
Returns the length.
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.
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)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:921
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:40
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:250
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:3011
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
void myEndElement(int element)
Called when a closing tag occurs.
A storage for options typed value containers)
Definition: OptionsCont.h:98
NBEdge * myCurrentEdge
The currently processed edge.
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:384
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:3164
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...
double speed
The speed after this change.
NBTypeCont & myTypeCont
The types container (for retrieval of type defaults)
const Position & getPosition() const
Definition: NBNode.h:241
Represents a single node (junction) during network building.
Definition: NBNode.h:74
bool myHaveReportedAboutTypeOverride
Information whether at least one edge&#39;s type was changed.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:426
NBEdgeCont & myEdgeCont
The edges container (for insertion of build edges)
int myCurrentLaneNo
The current edge&#39;s number of lanes.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:474
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:66
std::string myCurrentStreetName
The current edge&#39;s street name.
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
delete certain element
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:489
double mySidewalkWidth
The width of the sidewalk that shall be added to the current edge.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:200
std::string idBefore
The id for the edge before the split.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and modifies myCurrentEdge according to the given attribures.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:433
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:2911
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Definition: NBTypeCont.cpp:210
A storage for available types of edges.
Definition: NBTypeCont.h:61
PositionVector tryGetShape(const SUMOSAXAttributes &attrs)
Tries to parse the shape definition.