Eclipse 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-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
23 // Importer for network edges stored in XML
24 /****************************************************************************/
25 #include <config.h>
26 
27 #include <string>
28 #include <iostream>
29 #include <map>
30 #include <cmath>
31 #include <xercesc/sax/HandlerBase.hpp>
32 #include <xercesc/sax/AttributeList.hpp>
33 #include <xercesc/sax/SAXParseException.hpp>
34 #include <xercesc/sax/SAXException.hpp>
36 #include <netbuild/NBNodeCont.h>
37 #include <netbuild/NBTypeCont.h>
38 #include <netbuild/NBNetBuilder.h>
44 #include <utils/common/ToString.h>
47 #include "NIXMLNodesHandler.h"
48 #include "NIXMLEdgesHandler.h"
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
55  NBEdgeCont& ec,
56  NBTypeCont& tc,
57  NBDistrictCont& dc,
59  OptionsCont& options) :
60  SUMOSAXHandler("xml-edges - file"),
61  myOptions(options),
62  myNodeCont(nc),
63  myEdgeCont(ec),
64  myTypeCont(tc),
65  myDistrictCont(dc),
66  myTLLogicCont(tlc),
67  myCurrentEdge(nullptr),
68  myCurrentLaneIndex(-1),
69  myHaveReportedAboutOverwriting(false),
70  myHaveReportedAboutTypeOverride(false),
71  myHaveWarnedAboutDeprecatedLaneId(false),
72  myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
73 }
74 
75 
77 
78 
79 void
81  const SUMOSAXAttributes& attrs) {
82  switch (element) {
83  case SUMO_TAG_EDGE:
84  addEdge(attrs);
85  break;
86  case SUMO_TAG_LANE:
87  addLane(attrs);
88  break;
89  case SUMO_TAG_NEIGH:
91  break;
92  case SUMO_TAG_SPLIT:
93  addSplit(attrs);
94  break;
95  case SUMO_TAG_DEL:
96  deleteEdge(attrs);
97  break;
99  addRoundabout(attrs);
100  break;
101  case SUMO_TAG_PARAM:
102  if (myLastParameterised.size() != 0 && myCurrentEdge != nullptr) {
103  bool ok = true;
104  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
105  // circumventing empty string test
106  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
107  myLastParameterised.back()->setParameter(key, val);
108  }
109  break;
110  case SUMO_TAG_STOPOFFSET: {
111  bool ok = true;
112  const StopOffset stopOffset(attrs, ok);
113  if (!ok) {
114  std::stringstream ss;
115  ss << "(Error encountered at lane " << myCurrentLaneIndex << " of edge '" << myCurrentID << "' while parsing stopOffsets.)";
116  WRITE_ERROR(ss.str());
117  } else {
119  std::stringstream ss;
120  ss << "Duplicate definition of stopOffset for ";
121  if (myCurrentLaneIndex != -1) {
122  ss << "lane " << myCurrentLaneIndex << " on ";
123  }
124  ss << "edge " << myCurrentEdge->getID() << ". Ignoring duplicate specification.";
125  WRITE_WARNING(ss.str());
126  } else if ((stopOffset.getOffset() > myCurrentEdge->getLength()) || (stopOffset.getOffset() < 0)) {
127  std::stringstream ss;
128  ss << "Ignoring invalid stopOffset for ";
129  if (myCurrentLaneIndex != -1) {
130  ss << "lane " << myCurrentLaneIndex << " on ";
131  }
132  ss << "edge " << myCurrentEdge->getID();
133  if (stopOffset.getOffset() > myCurrentEdge->getLength()) {
134  ss << " (offset larger than the edge length).";
135  } else {
136  ss << " (negative offset).";
137  }
138  WRITE_WARNING(ss.str());
139  } else {
141  }
142  }
143  }
144  break;
145  default:
146  break;
147  }
148 }
149 
150 
151 void
153  myIsUpdate = false;
154  bool ok = true;
155  // initialise the edge
156  myCurrentEdge = nullptr;
157  mySplits.clear();
158  // get the id, report an error if not given or empty...
159  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
160  if (!ok) {
161  return;
162  }
164  // check deprecated (unused) attributes
165  // use default values, first
166  myCurrentType = myOptions.getString("default.type");
170  if (myCurrentEdge != nullptr) {
171  // update existing edge. only update lane-specific settings when explicitly requested
172  myIsUpdate = true;
178  } else {
179  // this is a completely new edge. get the type specific defaults
184  }
187  myCurrentStreetName = "";
188  myReinitKeepEdgeShape = false;
191  // check whether a type's values shall be used
192  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
193  myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
194  if (!ok) {
195  return;
196  }
197  if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
198  WRITE_ERRORF("Type '%' used by edge '%' was not defined (ignore with option --ignore-errors.edge-type).", myCurrentType, myCurrentID);
199  return;
200  }
209  }
210  // use values from the edge to overwrite if existing, then
211  if (myIsUpdate) {
213  WRITE_MESSAGE("Duplicate edge id occurred ('" + myCurrentID + "'); assuming overwriting is wished.");
215  }
218  WRITE_MESSAGE("Edge '" + myCurrentID + "' changed it's type; assuming type override is wished.");
220  }
221  }
222  if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
224  myCurrentEdge = nullptr;
225  return;
226  }
231  myReinitKeepEdgeShape = true;
232  }
236  }
238  }
239  // speed, priority and the number of lanes have now default values;
240  // try to read the real values from the file
241  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
242  myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
243  }
244  if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
245  myCurrentSpeed = myCurrentSpeed / (double) 3.6;
246  }
247  // try to get the number of lanes
248  if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
249  myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
250  }
251  // try to get the priority
252  if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
253  myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
254  }
255  // try to get the width
256  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
257  myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
258  }
259  // try to get the offset of the stop line from the intersection
260  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
261  myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
262  }
263  // try to get the street name
264  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
265  myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
266  if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
267  myOptions.set("output.street-names", "true");
268  }
269  }
270 
271  // try to get the allowed/disallowed classes
273  std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
274  std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
275  // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
276  myPermissions = parseVehicleClasses(allowS, disallowS);
277  }
278  // try to set the nodes
279  if (!setNodes(attrs)) {
280  // return if this failed
281  myCurrentEdge = nullptr;
282  return;
283  }
284  // try to get the shape
285  myShape = tryGetShape(attrs);
286  // try to get the spread type
288  // try to get the length
289  myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
290  // try to get the sidewalkWidth
292  // try to get the bikeLaneWidth
294  // insert the parsed edge into the edges map
295  if (!ok) {
296  myCurrentEdge = nullptr;
297  return;
298  }
299  // check whether a previously defined edge shall be overwritten
300  const bool applyLaneType = myCurrentEdge == nullptr;
301  if (myCurrentEdge != nullptr) {
307  } else {
308  // the edge must be allocated in dependence to whether a shape is given
309  if (myShape.size() == 0) {
313  } else {
318  }
319  }
323  }
324  // apply laneType if given
325  if (applyLaneType && myCurrentType != "" && myTypeCont.knows(myCurrentType)) {
327  if (eType->needsLaneType()) {
328  int lane = 0;
329  for (const NBTypeCont::LaneTypeDefinition& laneType : eType->laneTypeDefinitions) {
330  if (lane >= myCurrentLaneNo) {
331  break;
332  }
333  if (laneType.attrs.count(SUMO_ATTR_SPEED) > 0) {
334  myCurrentEdge->setSpeed(lane, laneType.speed);
335  }
336  if (laneType.attrs.count(SUMO_ATTR_DISALLOW) > 0 || laneType.attrs.count(SUMO_ATTR_ALLOW) > 0) {
337  myCurrentEdge->setPermissions(laneType.permissions, lane);
338  }
339  if (laneType.attrs.count(SUMO_ATTR_WIDTH) > 0) {
340  myCurrentEdge->setLaneWidth(lane, laneType.width);
341  }
342  lane++;
343  }
344  }
345  }
346  // try to get the kilometrage/mileage
348 
350 }
351 
352 
353 void
355  if (myCurrentEdge == nullptr) {
356  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
357  WRITE_ERRORF("Additional lane information could not be set - the edge with id '%s' is not known.", myCurrentID);
358  }
359  return;
360  }
361  bool ok = true;
362  int lane;
363  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
364  lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
367  WRITE_WARNING("'" + toString(SUMO_ATTR_ID) + "' is deprecated, please use '" + toString(SUMO_ATTR_INDEX) + "' instead.");
368  }
369  } else {
370  lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
371  }
372  if (!ok) {
373  return;
374  }
375  // check whether this lane exists
376  if (lane >= myCurrentEdge->getNumLanes()) {
377  WRITE_ERROR("Lane index is larger than number of lanes (edge '" + myCurrentID + "').");
378  return;
379  }
380  myCurrentLaneIndex = lane;
381  // set information about allowed / disallowed vehicle classes (if specified)
383  const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
384  const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
385  myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
386  }
387  if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
388  const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, nullptr, ok);
390  }
392  const std::string changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok, "");
393  const std::string changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok, "");
394  myCurrentEdge->setPermittedChanging(lane, parseVehicleClasses(changeLeft, ""), parseVehicleClasses(changeRight, ""));
395  }
396  // try to get the width
397  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
398  myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
399  }
400  // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
401  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
402  myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
403  }
404  // try to get lane specific speed (should not occur for german networks)
405  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
406  myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
407  }
408  // check whether this is an acceleration lane
410  myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
411  }
412  // check whether this lane has a custom shape
413  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
414  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
416  const std::string laneID = myCurrentID + "_" + toString(lane);
417  WRITE_ERROR("Unable to project coordinates for lane '" + laneID + "'.");
418  }
419  if (shape.size() == 1) {
420  // lane shape of length 1 is not permitted
422  shape.push_back(myCurrentEdge->getToNode()->getPosition());
423  }
424  shape.removeDoublePoints();
425  if (shape.size() < 2) {
426  // ignore lane shape for very short lanes
427  shape.clear();
428  }
429  myCurrentEdge->setLaneShape(lane, shape);
430  }
431  // set custom lane type
432  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
433  myCurrentEdge->setLaneType(lane, attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok));
434  }
436 }
437 
438 
440  if (myCurrentEdge == nullptr) {
441  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
442  WRITE_WARNING("Ignoring 'split' because it cannot be assigned to an edge");
443  }
444  return;
445  }
446  bool ok = true;
448  e.pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
449  if (ok) {
450  if (fabs(e.pos) > myCurrentEdge->getGeometry().length()) {
451  WRITE_ERROR("Edge '" + myCurrentID + "' has a split at invalid position " + toString(e.pos) + ".");
452  return;
453  }
454  std::vector<NBEdgeCont::Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
455  if (i != mySplits.end()) {
456  WRITE_ERROR("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + ".");
457  return;
458  }
459  // XXX rounding to int may duplicate the id of another split
460  e.nameID = myCurrentID + "." + toString((int)e.pos);
461  if (e.pos < 0) {
463  }
464  for (const std::string& id : attrs.getOptStringVector(SUMO_ATTR_LANES, myCurrentID.c_str(), ok)) {
465  try {
466  int lane = StringUtils::toInt(id);
467  e.lanes.push_back(lane);
468  } catch (NumberFormatException&) {
469  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
470  } catch (EmptyData&) {
471  WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
472  }
473  }
474  if (e.lanes.empty()) {
475  for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
476  e.lanes.push_back(l);
477  }
478  }
479  e.speed = attrs.getOpt(SUMO_ATTR_SPEED, nullptr, ok, myCurrentEdge->getSpeed());
480  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
481  e.speed /= 3.6;
482  }
483  e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, nullptr, ok, std::string(""));
484  e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, nullptr, ok, std::string(""));
485  if (!ok) {
486  return;
487  }
488  const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, nullptr, ok, e.nameID);
489  if (nodeID == myCurrentEdge->getFromNode()->getID() || nodeID == myCurrentEdge->getToNode()->getID()) {
490  WRITE_ERROR("Invalid split node id for edge '" + myCurrentEdge->getID() + "' (from- and to-node are forbidden)");
491  return;
492  }
493  e.node = myNodeCont.retrieve(nodeID);
494  e.offsetFactor = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
495  if (e.node == nullptr) {
496  e.node = new NBNode(nodeID, myCurrentEdge->getGeometry().positionAtOffset(e.pos));
498  }
501  mySplits.push_back(e);
502  }
503 }
504 
505 
506 bool
508  // the names and the coordinates of the beginning and the end node
509  // may be found, try
510  bool ok = true;
511  if (myIsUpdate) {
514  }
515  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
516  const std::string begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
517  if (begNodeID != "") {
518  myFromNode = myNodeCont.retrieve(begNodeID);
519  if (myFromNode == nullptr) {
520  WRITE_ERROR("Edge's '" + myCurrentID + "' from-node '" + begNodeID + "' is not known.");
521  }
522  }
523  } else if (!myIsUpdate) {
524  WRITE_ERROR("The from-node is not given for edge '" + myCurrentID + "'.");
525  ok = false;
526  }
527  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
528  const std::string endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
529  if (endNodeID != "") {
530  myToNode = myNodeCont.retrieve(endNodeID);
531  if (myToNode == nullptr) {
532  WRITE_ERROR("Edge's '" + myCurrentID + "' to-node '" + endNodeID + "' is not known.");
533  }
534  }
535  } else if (!myIsUpdate) {
536  WRITE_ERROR("The to-node is not given for edge '" + myCurrentID + "'.");
537  ok = false;
538  }
539  return ok && myFromNode != nullptr && myToNode != nullptr;
540 }
541 
542 
545  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE) && myShape.size() > 0) {
546  return myShape;
547  }
548  // try to build shape
549  bool ok = true;
550  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
551  const double maxSegmentLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
552  if (maxSegmentLength > 0) {
553  PositionVector shape;
554  shape.push_back(myFromNode->getPosition());
555  shape.push_back(myToNode->getPosition());
556  // shape is already cartesian but we must use a copy because the original will be modified
557  NBNetBuilder::addGeometrySegments(shape, PositionVector(shape), maxSegmentLength);
558  return shape;
559  } else {
560  myReinitKeepEdgeShape = false;
561  return PositionVector();
562  }
563  }
564  PositionVector shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector());
566  WRITE_ERROR("Unable to project coordinates for edge '" + myCurrentID + "'.");
567  }
569  return shape;
570 }
571 
572 
575  bool ok = true;
577  std::string lsfS = toString(result);
578  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
579  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
581  } else {
582  WRITE_WARNING("Ignoring unknown spreadType '" + lsfS + "' for edge '" + myCurrentID + "'.");
583  }
584  return result;
585 }
586 
587 
588 void
590  bool ok = true;
591  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
592  if (!ok) {
593  return;
594  }
596  if (edge == nullptr) {
597  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DEL) + "' for unknown edge '" +
598  myCurrentID + "'");
599  return;
600  }
601  const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
602  if (lane < 0) {
603  myEdgeCont.extract(myDistrictCont, edge, true);
604  } else {
605  edge->deleteLane(lane, false, true);
606  }
607 }
608 
609 
610 void
612  if (myCurrentEdge == nullptr) {
613  return;
614  }
615  if (element == SUMO_TAG_EDGE) {
616  myLastParameterised.pop_back();
617  // add bike lane, wait until lanes are loaded to avoid building if it already exists
620  }
621  // add sidewalk, wait until lanes are loaded to avoid building if it already exists
624  }
625  // apply default stopOffsets of edge to all lanes without specified stopOffset.
626  const StopOffset stopOffsets = myCurrentEdge->getEdgeStopOffset();
627  if (stopOffsets.isDefined()) {
628  for (int i = 0; i < (int)myCurrentEdge->getLanes().size(); i++) {
629  myCurrentEdge->setEdgeStopOffset(i, stopOffsets, false);
630  }
631  }
632  if (!myIsUpdate) {
633  try {
635  WRITE_ERROR("Duplicate edge occurred. ID='" + myCurrentID + "'");
636  delete myCurrentEdge;
637  }
638  } catch (InvalidArgument& e) {
639  WRITE_ERROR(e.what());
640  throw;
641  } catch (...) {
642  WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'.");
643  }
644  }
646  myCurrentEdge = nullptr;
647  } else if (element == SUMO_TAG_LANE && myCurrentLaneIndex != -1) {
648  myLastParameterised.pop_back();
649  myCurrentLaneIndex = -1;
650  }
651 }
652 
653 
654 void
656  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
657  std::vector<std::string> edgeIDs = attrs.getStringVector(SUMO_ATTR_EDGES);
658  EdgeSet roundabout;
659  for (std::vector<std::string>::iterator it = edgeIDs.begin(); it != edgeIDs.end(); ++it) {
660  NBEdge* edge = myEdgeCont.retrieve(*it);
661  if (edge == nullptr) {
662  if (!myEdgeCont.wasIgnored(*it)) {
663  WRITE_ERROR("Unknown edge '" + (*it) + "' in roundabout");
664  }
665  } else {
666  roundabout.insert(edge);
667  }
668  }
669  myEdgeCont.addRoundabout(roundabout);
670  } else {
671  WRITE_ERROR("Empty edges in roundabout.");
672  }
673 }
674 
675 
676 /****************************************************************************/
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:289
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:282
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_NEIGH
begin/end of the description of a neighboring lane
@ SUMO_TAG_SPLIT
split something
@ SUMO_TAG_DEL
delete certain element (note: DELETE is a macro)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
@ SUMO_ATTR_PREFER
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_REMOVE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_NUMLANES
@ SUMO_ATTR_LANES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_NAME
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
@ SUMO_ATTR_ENDOFFSET
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_BIKELANEWIDTH
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_ID_AFTER
@ SUMO_ATTR_SIDEWALKWIDTH
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_KEY
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_ID_BEFORE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A container for districts.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
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:412
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
Definition: NBEdgeCont.cpp:444
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:405
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:275
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:502
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:178
The representation of a single edge during network building.
Definition: NBEdge.h:91
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:3999
void setPermittedChanging(int lane, SVCPermissions changeLeft, SVCPermissions changeRight)
set allowed classes for changing to the left and right from the given lane
Definition: NBEdge.cpp:4013
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:588
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:3985
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:597
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:4227
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3953
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:643
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.cpp:942
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:607
void setDistance(double distance)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.h:1363
bool setEdgeStopOffset(int lane, const StopOffset &offset, bool overwrite=false)
set lane and vehicle class specific stopOffset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3923
const std::string & getID() const
Definition: NBEdge.h:1465
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:701
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:541
void setLaneType(int lane, const std::string &type)
set lane specific type (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3854
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:614
double getDistance() const
get distance
Definition: NBEdge.h:653
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:364
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3839
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:3969
const StopOffset & getEdgeStopOffset() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.cpp:3891
void reinit(NBNode *from, NBNode *to, const std::string &type, double speed, int nolanes, int priority, PositionVector geom, double width, double endOffset, const std::string &streetName, LaneSpreadFunction spread, bool tryIgnoreNodePositions=false)
Resets initial values.
Definition: NBEdge.cpp:406
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:4215
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:515
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:752
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition: NBEdge.cpp:3761
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:355
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:3977
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:604
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:522
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:349
const StopOffset & getLaneStopOffset(int lane) const
Returns the stop offset to the specified lane's end.
Definition: NBEdge.cpp:3897
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1146
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3907
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:352
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1368
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:4037
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:534
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
static int addGeometrySegments(PositionVector &from, const PositionVector &cartesian, const double maxLength)
insertion geometry points to ensure maximum segment length between points
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:58
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:90
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:119
Represents a single node (junction) during network building.
Definition: NBNode.h:66
const Position & getPosition() const
Definition: NBNode.h:248
A container for traffic light definitions and built programs.
A storage for available edgeTypes of edges.
Definition: NBTypeCont.h:52
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
Definition: NBTypeCont.cpp:476
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
Definition: NBTypeCont.cpp:482
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
Definition: NBTypeCont.cpp:470
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
Definition: NBTypeCont.cpp:532
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
Definition: NBTypeCont.cpp:520
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
Definition: NBTypeCont.cpp:291
double getEdgeTypeSidewalkWidth(const std::string &edgeType) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:538
LaneSpreadFunction getEdgeTypeSpreadType(const std::string &edgeType) const
Returns spreadType for the given edgeType.
Definition: NBTypeCont.cpp:526
double getEdgeTypeBikeLaneWidth(const std::string &edgeType) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:544
const EdgeTypeDefinition * getEdgeType(const std::string &name) const
Retrieve the name or the default edgeType.
Definition: NBTypeCont.cpp:550
Finds a split at the given position.
std::string myCurrentID
The current edge's id.
SVCPermissions myPermissions
Information about lane permissions.
bool setNodes(const SUMOSAXAttributes &attrs)
Sets from/to node information of the currently parsed edge.
PositionVector myShape
The shape of the edge.
std::string myCurrentStreetName
The current edge's street name.
LaneSpreadFunction tryGetLaneSpread(const SUMOSAXAttributes &attrs)
Tries to parse the spread type.
double myCurrentSpeed
The current edge's maximum speed.
double myBikeLaneWidth
The width of the bike lane that shall be added to the current edge.
~NIXMLEdgesHandler()
Destructor.
int myCurrentLaneNo
The current edge's number of lanes.
OptionsCont & myOptions
A reference to the program's options.
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
double myCurrentWidth
The current edge's lane width.
NIXMLEdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, OptionsCont &options)
Constructor.
NBTypeCont & myTypeCont
The types container (for retrieval of type defaults)
double myCurrentEndOffset
The current edge's offset till the destination node.
double myLength
The current edge's length.
int myCurrentPriority
The current edge's priority.
NBNodeCont & myNodeCont
The nodes container (for retrieval of referenced nodes)
PositionVector tryGetShape(const SUMOSAXAttributes &attrs)
Tries to parse the shape definition.
bool myIsUpdate
Whether this edge definition is an update of a previously inserted edge.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
LaneSpreadFunction myLanesSpread
Information about how to spread the lanes.
NBDistrictCont & myDistrictCont
The districts container (needed if an edge must be split)
std::vector< Parameterised * > myLastParameterised
element to receive parameters
NBEdgeCont & myEdgeCont
The edges container (for insertion of build edges)
double mySidewalkWidth
The width of the sidewalk that shall be added to the current edge.
bool myHaveWarnedAboutDeprecatedLaneId
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 myCurrentType
The current edge's type.
NBEdge * myCurrentEdge
The currently processed edge.
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to (when invalidating tls because of splits)
std::vector< NBEdgeCont::Split > mySplits
The list of this edge's splits.
int myCurrentLaneIndex
The currently processed lane index.
bool myHaveReportedAboutTypeOverride
Information whether at least one edge's type was changed.
NBNode * myFromNode
The nodes the edge starts and ends at.
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and modifies myCurrentEdge according to the given attribures.
void myEndElement(int element)
Called when a closing tag occurs.
const bool myKeepEdgeShape
Whether the edge shape shall be kept generally.
bool myHaveReportedAboutOverwriting
Information whether at least one edge's attributes were overwritten.
void deleteEdge(const SUMOSAXAttributes &attrs)
parses delete tag and deletes the specified edge or lane
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".
static NBNode * processNodeType(const SUMOSAXAttributes &attrs, NBNode *node, const std::string &nodeID, const Position &position, bool updateEdgeGeometries, NBNodeCont &nc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
parses node attributes (not related to positioning)
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
A list of positions.
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void push_front(const Position &p)
insert in front a Position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false, int beginOffset=0, int endOffset=0, bool resample=false)
Removes positions if too near.
Encapsulated SAX-Attributes.
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.
const std::vector< std::string > getOptStringVector(int attr, const char *objectid, bool &ok, bool report=true) const
convenience function to avoid the default argument and the template stuff at getOpt<>
const std::vector< std::string > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
SAX-handler base for SUMO-files.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
stop offset
bool isDefined() const
check if stopOffset was defined
double getOffset() const
get offset
T get(const std::string &str) const
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:175
A structure which describes changes of lane number or speed along the road.
Definition: NBEdgeCont.h:204
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
Definition: NBEdgeCont.h:222
double speed
The speed after this change.
Definition: NBEdgeCont.h:210
std::string nameID
the default node id
Definition: NBEdgeCont.h:218
std::string idBefore
The id for the edge before the split.
Definition: NBEdgeCont.h:214
double pos
The position of this change.
Definition: NBEdgeCont.h:208
std::vector< int > lanes
The lanes after this change.
Definition: NBEdgeCont.h:206
std::string idAfter
The id for the edge after the split.
Definition: NBEdgeCont.h:216
NBNode * node
The new node that is created for this split.
Definition: NBEdgeCont.h:212
edgeType definition
Definition: NBTypeCont.h:90
bool needsLaneType() const
whether any lane attributes deviate from the edge attributes
Definition: NBTypeCont.cpp:132
std::vector< LaneTypeDefinition > laneTypeDefinitions
vector with LaneTypeDefinitions
Definition: NBTypeCont.h:152
laneType definition
Definition: NBTypeCont.h:59
double speed
The maximal velocity on a lane in m/s.
Definition: NBTypeCont.h:74
SVCPermissions permissions
List of vehicle edgeTypes that are allowed on this lane.
Definition: NBTypeCont.h:77
std::set< SumoXMLAttr > attrs
The attributes which have been set.
Definition: NBTypeCont.h:86
double width
lane width [m]
Definition: NBTypeCont.h:80