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.dev/sumo
3 // Copyright (C) 2001-2024 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>
32 #include <netbuild/NBNodeCont.h>
33 #include <netbuild/NBTypeCont.h>
34 #include <netbuild/NBNetBuilder.h>
40 #include <utils/common/ToString.h>
43 #include "NIXMLNodesHandler.h"
44 #include "NIXMLEdgesHandler.h"
45 #include "NIImporter_SUMO.h"
46 
47 
48 // ===========================================================================
49 // method definitions
50 // ===========================================================================
52  NBEdgeCont& ec,
53  NBTypeCont& tc,
54  NBDistrictCont& dc,
56  OptionsCont& options) :
57  SUMOSAXHandler("xml-edges - file"),
58  myOptions(options),
59  myNodeCont(nc),
60  myEdgeCont(ec),
61  myTypeCont(tc),
62  myDistrictCont(dc),
63  myTLLogicCont(tlc),
64  myCurrentEdge(nullptr),
65  myCurrentLaneIndex(-1),
66  myHaveReportedAboutOverwriting(false),
67  myHaveReportedAboutTypeOverride(false),
68  myHaveWarnedAboutDeprecatedLaneId(false),
69  myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
70 }
71 
72 
74  delete myLocation;
75 }
76 
77 
78 void
80  const SUMOSAXAttributes& attrs) {
81  switch (element) {
83  // infer location for legacy networks that don't have location information
85  break;
86  case SUMO_TAG_LOCATION:
87  delete myLocation;
89  break;
90  case SUMO_TAG_EDGE:
91  addEdge(attrs);
92  break;
93  case SUMO_TAG_LANE:
94  addLane(attrs);
95  break;
96  case SUMO_TAG_NEIGH:
98  break;
99  case SUMO_TAG_SPLIT:
100  addSplit(attrs);
101  break;
102  case SUMO_TAG_DEL:
103  deleteEdge(attrs);
104  break;
105  case SUMO_TAG_ROUNDABOUT:
106  addRoundabout(attrs);
107  break;
108  case SUMO_TAG_PARAM:
109  if (myLastParameterised.size() != 0 && myCurrentEdge != nullptr) {
110  bool ok = true;
111  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
112  // circumventing empty string test
113  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
114  myLastParameterised.back()->setParameter(key, val);
115  }
116  break;
117  case SUMO_TAG_STOPOFFSET: {
118  bool ok = true;
119  const StopOffset stopOffset(attrs, ok);
120  if (!ok) {
121  std::stringstream ss;
122  ss << "(Error encountered at lane " << myCurrentLaneIndex << " of edge '" << myCurrentID << "' while parsing stopOffsets.)";
123  WRITE_ERROR(ss.str());
124  } else {
126  std::stringstream ss;
127  ss << "Duplicate definition of stopOffset for ";
128  if (myCurrentLaneIndex != -1) {
129  ss << "lane " << myCurrentLaneIndex << " on ";
130  }
131  ss << "edge " << myCurrentEdge->getID() << ". Ignoring duplicate specification.";
132  WRITE_WARNING(ss.str());
133  } else if ((stopOffset.getOffset() > myCurrentEdge->getLength()) || (stopOffset.getOffset() < 0)) {
134  std::stringstream ss;
135  ss << "Ignoring invalid stopOffset for ";
136  if (myCurrentLaneIndex != -1) {
137  ss << "lane " << myCurrentLaneIndex << " on ";
138  }
139  ss << "edge " << myCurrentEdge->getID();
140  if (stopOffset.getOffset() > myCurrentEdge->getLength()) {
141  ss << " (offset larger than the edge length).";
142  } else {
143  ss << " (negative offset).";
144  }
145  WRITE_WARNING(ss.str());
146  } else {
148  }
149  }
150  }
151  break;
152  default:
153  break;
154  }
155 }
156 
157 
158 void
160  myIsUpdate = false;
161  bool ok = true;
162  // initialise the edge
163  myCurrentEdge = nullptr;
164  mySplits.clear();
165  // get the id, report an error if not given or empty...
166  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
167  if (!ok) {
168  return;
169  }
171  // check deprecated (unused) attributes
172  // use default values, first
173  myCurrentType = myOptions.getString("default.type");
177  if (myCurrentEdge != nullptr) {
178  // update existing edge. only update lane-specific settings when explicitly requested
179  myIsUpdate = true;
186  } else {
187  // this is a completely new edge. get the type specific defaults
193  }
196  myCurrentStreetName = "";
197  myReinitKeepEdgeShape = false;
200  // check whether a type's values shall be used
201  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
202  myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
203  if (!ok) {
204  return;
205  }
206  if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
207  WRITE_ERRORF("Type '%' used by edge '%' was not defined (ignore with option --ignore-errors.edge-type).", myCurrentType, myCurrentID);
208  return;
209  }
218  }
219  // use values from the edge to overwrite if existing, then
220  if (myIsUpdate) {
222  WRITE_MESSAGEF(TL("Duplicate edge id occurred ('%'); assuming overwriting is wished."), myCurrentID);
224  }
227  WRITE_MESSAGEF(TL("Edge '%' changed its type; assuming type override is wished."), myCurrentID);
229  }
230  }
231  if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
233  myCurrentEdge = nullptr;
234  return;
235  }
240  myReinitKeepEdgeShape = true;
241  }
245  }
247  }
248  // speed, priority and the number of lanes have now default values;
249  // try to read the real values from the file
250  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
251  myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
252  }
253  if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
254  myCurrentSpeed = myCurrentSpeed / (double) 3.6;
255  }
256  // try to read the friction value from file
257  if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
258  myCurrentFriction = attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok);
259  }
260  // try to get the number of lanes
261  if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
262  myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
263  }
264  // try to get the priority
265  if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
266  myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
267  }
268  // try to get the width
269  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
270  myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
271  }
272  // try to get the offset of the stop line from the intersection
273  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
274  myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
275  }
276  // try to get the street name
277  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
278  myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
279  if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
280  myOptions.set("output.street-names", "true");
281  }
282  }
283 
284  // try to get the allowed/disallowed classes
286  std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
287  std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
288  // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
289  myPermissions = parseVehicleClasses(allowS, disallowS);
290  }
291  // try to set the nodes
292  if (!setNodes(attrs)) {
293  // return if this failed
294  myCurrentEdge = nullptr;
295  return;
296  }
297  // try to get the shape
298  myShape = tryGetShape(attrs);
299  // try to get the spread type
301  // try to get the length
302  myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
303  // try to get the sidewalkWidth
305  // try to get the bikeLaneWidth
307  // insert the parsed edge into the edges map
308  if (!ok) {
309  myCurrentEdge = nullptr;
310  return;
311  }
312  if (myFromNode == myToNode) {
313  // this might as well be an error. We make this a warning mostly for
314  // backward compatibility
315  WRITE_WARNINGF(TL("Ignoring self-looped edge '%' at junction '%'"), myCurrentID, myFromNode->getID());
316  myCurrentEdge = nullptr;
317  return;
318  }
319  // check whether a previously defined edge shall be overwritten
320  const bool applyLaneType = myCurrentEdge == nullptr;
321  if (myCurrentEdge != nullptr) {
327  } else {
328  // the edge must be allocated in dependence to whether a shape is given
329  if (myShape.size() == 0) {
333  } else {
338  }
339  }
343  }
344  // apply laneType if given
345  if (applyLaneType && myCurrentType != "" && myTypeCont.knows(myCurrentType)) {
347  if (eType->needsLaneType()) {
348  int lane = 0;
349  for (const NBTypeCont::LaneTypeDefinition& laneType : eType->laneTypeDefinitions) {
350  if (lane >= myCurrentLaneNo) {
351  break;
352  }
353  if (laneType.attrs.count(SUMO_ATTR_SPEED) > 0) {
354  myCurrentEdge->setSpeed(lane, laneType.speed);
355  }
356  if (laneType.attrs.count(SUMO_ATTR_FRICTION) > 0) {
357  myCurrentEdge->setFriction(lane, laneType.friction);
358  }
359  if (laneType.attrs.count(SUMO_ATTR_DISALLOW) > 0 || laneType.attrs.count(SUMO_ATTR_ALLOW) > 0) {
360  myCurrentEdge->setPermissions(laneType.permissions, lane);
361  }
362  if (laneType.attrs.count(SUMO_ATTR_WIDTH) > 0) {
363  myCurrentEdge->setLaneWidth(lane, laneType.width);
364  }
365  lane++;
366  }
367  }
368  }
369  // try to get the kilometrage/mileage
371  // preserve bidi edge (only as boo, the actual edge will be recomputed)
372  const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, myCurrentID.c_str(), ok, "");
373  myCurrentEdge->setBidi(myCurrentEdge->getBidiEdge() != nullptr || bidi != "");
374 
376 }
377 
378 
379 void
381  if (myCurrentEdge == nullptr) {
382  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
383  WRITE_ERRORF("Additional lane information could not be set - the edge with id '%s' is not known.", myCurrentID);
384  }
385  return;
386  }
387  bool ok = true;
388  int lane;
389  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
390  lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
393  WRITE_WARNINGF(TL("'%' is deprecated, please use '%' instead."), toString(SUMO_ATTR_ID), toString(SUMO_ATTR_INDEX));
394  }
395  } else {
396  lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
397  }
398  if (!ok) {
399  return;
400  }
401  // check whether this lane exists
402  if (lane >= myCurrentEdge->getNumLanes()) {
403  WRITE_ERRORF(TL("Lane index is larger than number of lanes (edge '%')."), myCurrentID);
404  return;
405  }
406  myCurrentLaneIndex = lane;
407  // set information about allowed / disallowed vehicle classes (if specified)
409  const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
410  const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
411  myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
412  }
413  if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
414  const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, nullptr, ok);
416  }
418  const std::string changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok, "");
419  const std::string changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok, "");
420  myCurrentEdge->setPermittedChanging(lane, parseVehicleClasses(changeLeft, ""), parseVehicleClasses(changeRight, ""));
421  }
422  // try to get the width
423  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
424  myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
425  }
426  // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
427  if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) {
428  myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
429  }
430  // try to get lane specific speed (should not occur for german networks)
431  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
432  myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
433  }
434  // try to get lane specific friction
435  if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
436  myCurrentEdge->setFriction(lane, attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok));
437  }
438  // check whether this is an acceleration lane
440  myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
441  }
442  // check whether this lane has a custom shape
443  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
444  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
445  if (!NBNetBuilder::transformCoordinates(shape, true, myLocation)) {
446  const std::string laneID = myCurrentID + "_" + toString(lane);
447  WRITE_ERRORF(TL("Unable to project coordinates for lane '%'."), laneID);
448  }
449  if (shape.size() == 1) {
450  // lane shape of length 1 is not permitted
452  shape.push_back(myCurrentEdge->getToNode()->getPosition());
453  }
454  shape.removeDoublePoints();
455  if (shape.size() < 2) {
456  // ignore lane shape for very short lanes
457  shape.clear();
458  }
459  myCurrentEdge->setLaneShape(lane, shape);
460  }
461  // set custom lane type
462  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
463  myCurrentEdge->setLaneType(lane, attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok));
464  }
466 }
467 
468 
470  if (myCurrentEdge == nullptr) {
471  if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
472  WRITE_WARNING(TL("Ignoring 'split' because it cannot be assigned to an edge"));
473  }
474  return;
475  }
476  bool ok = true;
478  e.pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
479  if (ok) {
480  if (fabs(e.pos) > myCurrentEdge->getLoadedLength()) {
481  WRITE_ERRORF(TL("Edge '%' has a split at invalid position %."), myCurrentID, toString(e.pos));
482  return;
483  }
484  std::vector<NBEdgeCont::Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
485  if (i != mySplits.end()) {
486  WRITE_ERRORF(TL("Edge '%' has already a split at position %."), myCurrentID, toString(e.pos));
487  return;
488  }
489  // XXX rounding to int may duplicate the id of another split
490  e.nameID = myCurrentID + "." + toString((int)e.pos);
491  if (e.pos < 0) {
493  }
494  for (const std::string& id : attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LANES, myCurrentID.c_str(), ok)) {
495  try {
496  int lane = StringUtils::toInt(id);
497  e.lanes.push_back(lane);
498  } catch (NumberFormatException&) {
499  WRITE_ERRORF(TL("Error on parsing a split (edge '%')."), myCurrentID);
500  } catch (EmptyData&) {
501  WRITE_ERRORF(TL("Error on parsing a split (edge '%')."), myCurrentID);
502  }
503  }
504  if (e.lanes.empty()) {
505  for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
506  e.lanes.push_back(l);
507  }
508  }
509  e.speed = attrs.getOpt(SUMO_ATTR_SPEED, nullptr, ok, myCurrentEdge->getSpeed());
510  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
511  e.speed /= 3.6;
512  }
513  e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, nullptr, ok, std::string(""));
514  e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, nullptr, ok, std::string(""));
515  if (!ok) {
516  return;
517  }
518  const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, nullptr, ok, e.nameID);
519  if (nodeID == myCurrentEdge->getFromNode()->getID() || nodeID == myCurrentEdge->getToNode()->getID()) {
520  WRITE_ERRORF(TL("Invalid split node id for edge '%' (from- and to-node are forbidden)"), myCurrentEdge->getID());
521  return;
522  }
523  e.node = myNodeCont.retrieve(nodeID);
524  e.offsetFactor = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
525  if (e.node == nullptr) {
526  double geomPos = e.pos;
529  }
530  e.node = new NBNode(nodeID, myCurrentEdge->getGeometry().positionAtOffset(geomPos));
532  }
535  mySplits.push_back(e);
536  }
537 }
538 
539 
540 bool
542  // the names and the coordinates of the beginning and the end node
543  // may be found, try
544  bool ok = true;
545  if (myIsUpdate) {
548  }
549  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
550  const std::string begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
551  if (begNodeID != "") {
552  myFromNode = myNodeCont.retrieve(begNodeID);
553  if (myFromNode == nullptr) {
554  WRITE_ERRORF(TL("Edge's '%' from-node '%' is not known."), myCurrentID, begNodeID);
555  }
556  }
557  } else if (!myIsUpdate) {
558  WRITE_ERRORF(TL("The from-node is not given for edge '%'."), myCurrentID);
559  ok = false;
560  }
561  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
562  const std::string endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
563  if (endNodeID != "") {
564  myToNode = myNodeCont.retrieve(endNodeID);
565  if (myToNode == nullptr) {
566  WRITE_ERRORF(TL("Edge's '%' to-node '%' is not known."), myCurrentID, endNodeID);
567  }
568  }
569  } else if (!myIsUpdate) {
570  WRITE_ERRORF(TL("The to-node is not given for edge '%'."), myCurrentID);
571  ok = false;
572  }
573  return ok && myFromNode != nullptr && myToNode != nullptr;
574 }
575 
576 
579  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE) && myShape.size() > 0) {
580  return myShape;
581  }
582  // try to build shape
583  bool ok = true;
584  if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
585  const double maxSegmentLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
586  if (maxSegmentLength > 0) {
587  PositionVector shape;
588  shape.push_back(myFromNode->getPosition());
589  shape.push_back(myToNode->getPosition());
590  // shape is already cartesian but we must use a copy because the original will be modified
591  NBNetBuilder::addGeometrySegments(shape, PositionVector(shape), maxSegmentLength);
592  return shape;
593  } else {
594  myReinitKeepEdgeShape = false;
595  return PositionVector();
596  }
597  }
598  PositionVector shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector());
599  if (!NBNetBuilder::transformCoordinates(shape, true, myLocation)) {
600  WRITE_ERRORF(TL("Unable to project coordinates for edge '%'."), myCurrentID);
601  }
603  return shape;
604 }
605 
606 
609  bool ok = true;
611  std::string lsfS = toString(result);
612  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
613  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
615  } else {
616  WRITE_WARNINGF(TL("Ignoring unknown spreadType '%' for edge '%'."), lsfS, myCurrentID);
617  }
618  return result;
619 }
620 
621 
622 void
624  bool ok = true;
625  myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
626  if (!ok) {
627  return;
628  }
630  if (edge == nullptr) {
631  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DEL) + "' for unknown edge '" +
632  myCurrentID + "'");
633  return;
634  }
635  const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
636  if (lane < 0) {
637  myEdgeCont.extract(myDistrictCont, edge, true);
638  } else {
639  edge->deleteLane(lane, false, true);
640  }
641 }
642 
643 
644 void
646  if (element == SUMO_TAG_VIEWSETTINGS_EDGES) {
647  delete myLocation;
648  myLocation = nullptr;
649  return;
650  }
651  if (myCurrentEdge == nullptr) {
652  return;
653  }
654  if (element == SUMO_TAG_EDGE) {
655  myLastParameterised.pop_back();
656  // add bike lane, wait until lanes are loaded to avoid building if it already exists
659  }
660  // add sidewalk, wait until lanes are loaded to avoid building if it already exists
663  }
664  // apply default stopOffsets of edge to all lanes without specified stopOffset.
665  const StopOffset stopOffsets = myCurrentEdge->getEdgeStopOffset();
666  if (stopOffsets.isDefined()) {
667  for (int i = 0; i < (int)myCurrentEdge->getLanes().size(); i++) {
668  myCurrentEdge->setEdgeStopOffset(i, stopOffsets, false);
669  }
670  }
671  if (!myIsUpdate) {
672  try {
674  WRITE_ERRORF(TL("Duplicate edge '%' occurred."), myCurrentID);
675  delete myCurrentEdge;
676  myCurrentEdge = nullptr;
677  return;
678  }
679  } catch (InvalidArgument& e) {
680  WRITE_ERROR(e.what());
681  throw;
682  } catch (...) {
683  WRITE_ERRORF(TL("An important information is missing in edge '%'."), myCurrentID);
684  }
685  }
687  myCurrentEdge = nullptr;
688  } else if (element == SUMO_TAG_LANE && myCurrentLaneIndex != -1) {
689  myLastParameterised.pop_back();
690  myCurrentLaneIndex = -1;
691  }
692 }
693 
694 
695 void
697  bool ok = true;
698  const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
699  if (ok) {
700  EdgeSet roundabout;
701  for (const std::string& eID : edgeIDs) {
702  NBEdge* edge = myEdgeCont.retrieve(eID);
703  if (edge == nullptr) {
704  if (!myEdgeCont.wasIgnored(eID)) {
705  WRITE_ERRORF(TL("Unknown edge '%' in roundabout."), eID);
706  }
707  } else {
708  roundabout.insert(edge);
709  }
710  }
711  myEdgeCont.addRoundabout(roundabout);
712  }
713 }
714 
715 
716 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
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_LOCATION
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_VIEWSETTINGS_EDGES
@ 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_BIDI
@ 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_FRICTION
@ SUMO_ATTR_ID_BEFORE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
const std::string & getFileName() const
returns the current file name
static GeoConvHelper * getLoadedPlain(const std::string &edgFile)
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:418
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
process splits
Definition: NBEdgeCont.cpp:458
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:411
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:281
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:481
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:182
The representation of a single edge during network building.
Definition: NBEdge.h:92
void reinit(NBNode *from, NBNode *to, const std::string &type, double speed, double friction, 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:379
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:4285
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:4299
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:589
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:4271
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:598
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:4514
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4223
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition: NBEdge.h:351
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:665
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.cpp:979
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:608
void setDistance(double distance)
set kilometrage at start of edge (negative value implies couting down along the edge)
Definition: NBEdge.h:1407
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:4193
const std::string & getID() const
Definition: NBEdge.h:1522
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:726
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
void setLaneType(int lane, const std::string &type)
set lane specific type (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4109
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:615
double getDistance() const
get distance
Definition: NBEdge.h:675
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:360
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4094
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:4255
const StopOffset & getEdgeStopOffset() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.cpp:4161
void setBidi(bool isBidi)
mark this edge as a bidi edge
Definition: NBEdge.h:1412
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:4502
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:516
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:779
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4239
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition: NBEdge.cpp:4015
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:348
const NBEdge * getBidiEdge() const
Definition: NBEdge.h:1508
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:4263
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:589
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:523
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:342
const StopOffset & getLaneStopOffset(int lane) const
Returns the stop offset to the specified lane's end.
Definition: NBEdge.cpp:4167
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1175
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4177
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:345
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1422
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:4323
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:535
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
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:57
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:87
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:116
Represents a single node (junction) during network building.
Definition: NBNode.h:66
const Position & getPosition() const
Definition: NBNode.h:260
A container for traffic light definitions and built programs.
A storage for available edgeTypes of edges.
Definition: NBTypeCont.h:52
double getEdgeTypeFriction(const std::string &edgeType) const
Returns the default friction for the given edgeType [-].
Definition: NBTypeCont.cpp:508
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
Definition: NBTypeCont.cpp:503
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
Definition: NBTypeCont.cpp:514
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
Definition: NBTypeCont.cpp:497
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
Definition: NBTypeCont.cpp:564
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
Definition: NBTypeCont.cpp:552
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
Definition: NBTypeCont.cpp:303
double getEdgeTypeSidewalkWidth(const std::string &edgeType) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:570
LaneSpreadFunction getEdgeTypeSpreadType(const std::string &edgeType) const
Returns spreadType for the given edgeType.
Definition: NBTypeCont.cpp:558
double getEdgeTypeBikeLaneWidth(const std::string &edgeType) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:576
const EdgeTypeDefinition * getEdgeType(const std::string &name) const
Retrieve the name or the default edgeType.
Definition: NBTypeCont.cpp:582
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs, bool setLoaded=true)
Parses network location description and registers it with GeoConveHelper::setLoaded.
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.
GeoConvHelper * myLocation
The coordinate transformation which was used compute the node coordinates.
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.
double myCurrentFriction
The current edge's friction.
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)
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 set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
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:60
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.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
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.
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:179
A structure which describes changes of lane number or speed along the road.
Definition: NBEdgeCont.h:189
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
Definition: NBEdgeCont.h:209
double speed
The speed after this change.
Definition: NBEdgeCont.h:195
std::string nameID
the default node id
Definition: NBEdgeCont.h:205
std::string idBefore
The id for the edge before the split.
Definition: NBEdgeCont.h:201
double pos
The position of this change.
Definition: NBEdgeCont.h:193
std::vector< int > lanes
The lanes after this change.
Definition: NBEdgeCont.h:191
std::string idAfter
The id for the edge after the split.
Definition: NBEdgeCont.h:203
NBNode * node
The new node that is created for this split.
Definition: NBEdgeCont.h:199
edgeType definition
Definition: NBTypeCont.h:93
bool needsLaneType() const
whether any lane attributes deviate from the edge attributes
Definition: NBTypeCont.cpp:137
std::vector< LaneTypeDefinition > laneTypeDefinitions
vector with LaneTypeDefinitions
Definition: NBTypeCont.h:158
laneType definition
Definition: NBTypeCont.h:59
double speed
The maximal velocity on a lane in m/s.
Definition: NBTypeCont.h:74
double friction
The default friction on a lane.
Definition: NBTypeCont.h:77
SVCPermissions permissions
List of vehicle edgeTypes that are allowed on this lane.
Definition: NBTypeCont.h:80
std::set< SumoXMLAttr > attrs
The attributes which have been set.
Definition: NBTypeCont.h:89
double width
lane width [m]
Definition: NBTypeCont.h:83