Eclipse SUMO - Simulation of Urban MObility
NIXMLConnectionsHandler.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 /****************************************************************************/
21 // Importer for edge connections stored in XML
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <string>
26 #include <iostream>
27 #include <netbuild/NBEdge.h>
28 #include <netbuild/NBEdgeCont.h>
29 #include <netbuild/NBNodeCont.h>
31 #include <netbuild/NBNode.h>
32 #include <netbuild/NBNetBuilder.h>
37 #include <utils/common/ToString.h>
42 #include "NIImporter_SUMO.h"
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
50  SUMOSAXHandler("xml-connection-description"),
51  myEdgeCont(ec),
52  myNodeCont(nc),
53  myTLLogicCont(tlc),
54  myHaveWarnedAboutDeprecatedLanes(false),
55  myErrorMsgHandler(OptionsCont::getOptions().getBool("ignore-errors.connections") ?
56  MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
57  myLocation(nullptr),
58  myLastParameterised(nullptr) {
59 }
60 
61 
63  delete myLocation;
64 }
65 
66 
67 void
69  const SUMOSAXAttributes& attrs) {
70  switch (element) {
72  // infer location for legacy networks that don't have location information
74  break;
75  case SUMO_TAG_LOCATION:
76  delete myLocation;
78  break;
79  case SUMO_TAG_DEL:
80  delConnection(attrs);
81  break;
83  parseConnection(attrs);
84  break;
86  addProhibition(attrs);
87  break;
88  case SUMO_TAG_CROSSING:
89  addCrossing(attrs);
90  break;
92  addWalkingArea(attrs);
93  break;
94  case SUMO_TAG_PARAM:
95  if (myLastParameterised != nullptr) {
96  bool ok = true;
97  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
98  // circumventing empty string test
99  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
101  }
102  break;
103  default:
104  break;
105  }
106 }
107 
108 
109 void
111  switch (element) {
112  case SUMO_TAG_CONNECTION:
113  case SUMO_TAG_CROSSING:
114  myLastParameterised = nullptr;
115  break;
116  default:
117  break;
118  }
119 }
120 
121 
122 
124 NIXMLConnectionsHandler::parseConnectionDef(const std::string& defRole, const std::string& def) {
125  // split from/to
126  const std::string::size_type div = def.find("->");
127  if (div == std::string::npos) {
128  myErrorMsgHandler->inform("Missing connection divider in " + defRole + " '" + def + "'");
130  }
131  std::string fromDef = def.substr(0, div);
132  std::string toDef = def.substr(div + 2);
133 
134  // retrieve them now
135  NBEdge* fromE = myEdgeCont.retrieve(fromDef);
136  NBEdge* toE = myEdgeCont.retrieve(toDef);
137  // check
138  if (fromE == nullptr) {
139  myErrorMsgHandler->inform("Could not find edge '" + fromDef + "' in " + defRole + " '" + def + "'");
141  }
142  if (toE == nullptr) {
143  myErrorMsgHandler->inform("Could not find edge '" + toDef + "' in " + defRole + " '" + def + "'");
145  }
146  return NBConnection(fromE, toE);
147 }
148 
149 
150 void
152  if (to == nullptr) {
153  // do nothing if it's a dead end
154  return;
155  }
156  bool ok = true;
157  // get the begin and the end lane
158  int fromLane;
159  int toLane;
160  try {
161  if (!parseLaneInfo(attrs, from, to, &fromLane, &toLane)) {
162  return;
163  }
164  if (fromLane < 0) {
165  myErrorMsgHandler->informf("Invalid value '%' for " + toString(SUMO_ATTR_FROM_LANE) +
166  " in connection from '%' to '%'.", fromLane, from->getID(), to->getID());
167  return;
168  }
169  if (toLane < 0) {
170  myErrorMsgHandler->informf("Invalid value '%' for " + toString(SUMO_ATTR_TO_LANE) +
171  " in connection from '%' to '%'.", toLane, from->getID(), to->getID());
172  return;
173  }
174 
175  NBEdge::Connection defaultCon(fromLane, to, toLane);
177  // maybe we are patching an existing connection
178  std::vector<NBEdge::Connection> existing = from->getConnectionsFromLane(fromLane, to, toLane);
179  if (existing.size() > 0) {
180  assert(existing.size() == 1);
181  defaultCon = existing.front();
182  // remove the original so we can insert the replacement
183  from->removeFromConnections(defaultCon);
184  } else {
185  from->getToNode()->invalidateTLS(myTLLogicCont, true, false);
186  }
187  }
188  if (OptionsCont::getOptions().isSet("default.connection.cont-pos")) {
189  defaultCon.contPos = OptionsCont::getOptions().getFloat("default.connection.cont-pos");
190  }
191  const bool mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, nullptr, ok, defaultCon.mayDefinitelyPass);
192  KeepClear keepClear = defaultCon.keepClear;
193  if (attrs.hasAttribute(SUMO_ATTR_KEEP_CLEAR)) {
194  keepClear = attrs.get<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok) ? KEEPCLEAR_TRUE : KEEPCLEAR_FALSE;
195  }
196  const double contPos = attrs.getOpt<double>(SUMO_ATTR_CONTPOS, nullptr, ok, defaultCon.contPos);
197  const double visibility = attrs.getOpt<double>(SUMO_ATTR_VISIBILITY_DISTANCE, nullptr, ok, defaultCon.visibility);
198  const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, defaultCon.speed);
199  const double friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, nullptr, ok, defaultCon.friction);
200  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, nullptr, ok, defaultCon.customLength);
201  const bool uncontrolled = attrs.getOpt<bool>(SUMO_ATTR_UNCONTROLLED, nullptr, ok, defaultCon.uncontrolled);
202  const bool indirectLeft = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
203  const std::string edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, nullptr, ok, "");
204  PositionVector customShape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, defaultCon.customShape);
205  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
206  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
207  SVCPermissions permissions;
208  if (allow == "" && disallow == "") {
209  permissions = SVC_UNSPECIFIED;
210  } else {
211  permissions = parseVehicleClasses(attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, ""), attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, ""));
212  }
213  SVCPermissions changeLeft = SVC_UNSPECIFIED;
214  SVCPermissions changeRight = SVC_UNSPECIFIED;
215  if (attrs.hasAttribute(SUMO_ATTR_CHANGE_LEFT)) {
216  changeLeft = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok), "");
217  }
219  changeRight = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok), "");
220  }
221  if (attrs.hasAttribute(SUMO_ATTR_SHAPE) && !NBNetBuilder::transformCoordinates(customShape, true, myLocation)) {
222  WRITE_ERRORF(TL("Unable to project shape for connection from edge '%' to edge '%'."), from->getID(), to->getID());
223  }
224  if (!ok) {
225  return;
226  }
227  if (!from->addLane2LaneConnection(fromLane, to, toLane, NBEdge::Lane2LaneInfoType::USER, true, mayDefinitelyPass,
228  keepClear, contPos, visibility, speed, friction, length, customShape, uncontrolled, permissions, indirectLeft, edgeType, changeLeft, changeRight)) {
229  if (OptionsCont::getOptions().getBool("show-errors.connections-first-try")) {
230  WRITE_WARNINGF(TL("Could not set loaded connection from lane '%' to lane '%'."), from->getLaneID(fromLane), to->getLaneID(toLane));
231  }
232  // set as to be re-applied after network processing
233  myEdgeCont.addPostProcessConnection(from->getID(), fromLane, to->getID(), toLane, mayDefinitelyPass, keepClear, contPos, visibility,
234  speed, friction, length, customShape, uncontrolled, false, permissions, indirectLeft, edgeType, changeLeft, changeRight);
235  }
236  } catch (NumberFormatException&) {
237  myErrorMsgHandler->inform("At least one of the defined lanes was not numeric");
238  }
239 }
240 
241 bool
243  int* fromLane, int* toLane) {
244  if (attributes.hasAttribute(SUMO_ATTR_LANE)) {
245  return parseDeprecatedLaneDefinition(attributes, fromEdge, toEdge, fromLane, toLane);
246  } else {
247  return parseLaneDefinition(attributes, fromLane, toLane);
248  }
249 }
250 
251 
252 inline bool
254  NBEdge* from, NBEdge* to,
255  int* fromLane, int* toLane) {
256  bool ok = true;
259  WRITE_WARNING("'" + toString(SUMO_ATTR_LANE) + "' is deprecated, please use '" +
261  "' instead.");
262  }
263 
264  std::string laneConn = attributes.get<std::string>(SUMO_ATTR_LANE, nullptr, ok);
265  StringTokenizer st(laneConn, ':');
266  if (!ok || st.size() != 2) {
267  myErrorMsgHandler->inform("Invalid lane to lane connection from '" +
268  from->getID() + "' to '" + to->getID() + "'.");
269  return false; // There was an error.
270  }
271 
272  *fromLane = StringUtils::toIntSecure(st.next(), -1);
273  *toLane = StringUtils::toIntSecure(st.next(), -1);
274 
275  return true; // We succeeded.
276 }
277 
278 
279 inline bool
281  int* fromLane,
282  int* toLane) {
283  bool ok = true;
284  *fromLane = attributes.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
285  *toLane = attributes.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
286  return ok;
287 }
288 
289 void
291  bool ok = true;
292  std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
293  std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
294  if (!ok) {
295  return;
296  }
297  // these connections were removed when the edge was deleted
298  if (myEdgeCont.wasRemoved(from) || myEdgeCont.wasRemoved(to)) {
299  return;
300  }
301  NBEdge* fromEdge = myEdgeCont.retrieve(from);
302  NBEdge* toEdge = myEdgeCont.retrieve(to);
303  if (fromEdge == nullptr) {
304  myErrorMsgHandler->informf("The connection-source edge '%' to reset is not known.", from);
305  return;
306  }
307  if (toEdge == nullptr) {
308  myErrorMsgHandler->informf("The connection-destination edge '%' to reset is not known.", to);
309  return;
310  }
311  if (!fromEdge->isConnectedTo(toEdge) && fromEdge->getStep() >= NBEdge::EdgeBuildingStep::EDGE2EDGES) {
312  WRITE_WARNINGF(TL("Target edge '%' is not connected with '%'; the connection cannot be reset."), toEdge->getID(), fromEdge->getID());
313  return;
314  }
315  int fromLane = -1; // Assume all lanes are to be reset.
316  int toLane = -1;
317  if (attrs.hasAttribute(SUMO_ATTR_LANE)
319  || attrs.hasAttribute(SUMO_ATTR_TO_LANE)) {
320  if (!parseLaneInfo(attrs, fromEdge, toEdge, &fromLane, &toLane)) {
321  return;
322  }
323  // we could be trying to reset a connection loaded from a sumo net and which has become obsolete.
324  // In this case it's ok to encounter invalid lance indices
325  if (!fromEdge->hasConnectionTo(toEdge, toLane) && fromEdge->getStep() >= NBEdge::EdgeBuildingStep::LANES2EDGES) {
326  WRITE_WARNINGF(TL("Edge '%' has no connection to lane '%'; the connection cannot be reset."), fromEdge->getID(), toEdge->getLaneID(toLane));
327  }
328  }
329  fromEdge->removeFromConnections(toEdge, fromLane, toLane, true);
330 }
331 
332 void
334  bool ok = true;
335  std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "connection", ok);
336  std::string to = attrs.getOpt<std::string>(SUMO_ATTR_TO, "connection", ok, "");
337  if (!ok || myEdgeCont.wasIgnored(from) || myEdgeCont.wasIgnored(to)) {
338  return;
339  }
340  // extract edges
341  NBEdge* fromEdge = myEdgeCont.retrieve(from);
342  NBEdge* toEdge = to.length() != 0 ? myEdgeCont.retrieve(to) : nullptr;
343  // check whether they are valid
344  if (fromEdge == nullptr) {
345  myErrorMsgHandler->inform("The connection-source edge '" + from + "' is not known.");
346  return;
347  }
348  if (toEdge == nullptr && to.length() != 0) {
349  myErrorMsgHandler->inform("The connection-destination edge '" + to + "' is not known.");
350  return;
351  }
352  // parse optional lane information
354  parseLaneBound(attrs, fromEdge, toEdge);
355  } else {
356  fromEdge->addEdge2EdgeConnection(toEdge);
357  fromEdge->getToNode()->invalidateTLS(myTLLogicCont, true, false);
358  if (attrs.hasAttribute(SUMO_ATTR_PASS)
362  || attrs.hasAttribute(SUMO_ATTR_SPEED)
365  || attrs.hasAttribute(SUMO_ATTR_SHAPE)
366  || attrs.hasAttribute(SUMO_ATTR_ALLOW)
367  || attrs.hasAttribute(SUMO_ATTR_DISALLOW)) {
368  WRITE_ERROR("No additional connection attributes are permitted in connection from edge '" + fromEdge->getID() + "' unless '"
369  + toString(SUMO_ATTR_FROM_LANE) + "' and '" + toString(SUMO_ATTR_TO_LANE) + "' are set.");
370  }
371  }
372 }
373 
374 void
376  bool ok = true;
377  EdgeVector edges;
378  const std::string nodeID = attrs.get<std::string>(SUMO_ATTR_NODE, nullptr, ok);
379  double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, nodeID.c_str(), ok, NBEdge::UNSPECIFIED_WIDTH, true);
380  const bool discard = attrs.getOpt<bool>(SUMO_ATTR_DISCARD, nodeID.c_str(), ok, false, true);
381  int tlIndex = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok, -1);
382  int tlIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX2, nullptr, ok, -1);
383  NBNode* node = myNodeCont.retrieve(nodeID);
384  if (node == nullptr) {
385  if (!discard && myNodeCont.wasRemoved(nodeID)) {
386  WRITE_ERRORF(TL("Node '%' in crossing is not known."), nodeID);
387  }
388  return;
389  }
390  if (!attrs.hasAttribute(SUMO_ATTR_EDGES)) {
391  if (discard) {
392  node->discardAllCrossings(true);
393  return;
394  } else {
395  WRITE_ERRORF(TL("No edges specified for crossing at node '%'."), nodeID);
396  return;
397  }
398  }
399  for (const std::string& id : attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nodeID.c_str(), ok)) {
400  NBEdge* edge = myEdgeCont.retrieve(id);
401  if (edge == nullptr) {
402  if (!(discard && myEdgeCont.wasRemoved(id))) {
403  WRITE_ERRORF(TL("Edge '%' for crossing at node '%' is not known."), id, nodeID);
404  return;
405  } else {
406  edge = myEdgeCont.retrieve(id, true);
407  }
408  } else {
409  if (edge->getToNode() != node && edge->getFromNode() != node) {
410  if (!discard) {
411  WRITE_ERRORF(TL("Edge '%' does not touch node '%'."), id, nodeID);
412  return;
413  }
414  }
415  }
416  edges.push_back(edge);
417  }
418  if (!ok) {
419  return;
420  }
421  bool priority = attrs.getOpt<bool>(SUMO_ATTR_PRIORITY, nodeID.c_str(), ok, node->isTLControlled(), true);
422  if (node->isTLControlled() && !priority) {
423  // traffic_light nodes should always have priority crossings
424  WRITE_WARNINGF(TL("Crossing at controlled node '%' must be prioritized"), nodeID);
425  priority = true;
426  }
427  PositionVector customShape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector::EMPTY);
428  if (!NBNetBuilder::transformCoordinates(customShape, true, myLocation)) {
429  WRITE_ERRORF(TL("Unable to project shape for crossing at node '%'."), node->getID());
430  }
431  if (discard) {
432  node->removeCrossing(edges);
433  } else {
434  if (node->checkCrossingDuplicated(edges)) {
435  // possibly a diff
436  NBNode::Crossing* existing = node->getCrossing(edges);
437  if (!(
438  (attrs.hasAttribute(SUMO_ATTR_WIDTH) && width != existing->width)
439  || (attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX) && tlIndex != existing->customTLIndex)
440  || (attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX2) && tlIndex2 != existing->customTLIndex2)
441  || (attrs.hasAttribute(SUMO_ATTR_PRIORITY) && priority != existing->priority))) {
442  WRITE_ERRORF(TL("Crossing with edges '%' already exists at node '%'."), toString(edges), node->getID());
443  return;
444  } else {
445  // replace existing, keep old attributes
446  if (!attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
447  width = existing->width;
448  }
449  if (!attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)) {
450  tlIndex = existing->customTLIndex;
451  }
452  if (!attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX2)) {
453  tlIndex2 = existing->customTLIndex2;
454  }
455  if (!attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
456  priority = existing->priority;
457  }
458  node->removeCrossing(edges);
459  }
460  }
461  NBNode::Crossing* c = node->addCrossing(edges, width, priority, tlIndex, tlIndex2, customShape);
463  }
464 }
465 
466 
467 void
469  bool ok = true;
470  NBNode* node = nullptr;
471  EdgeVector edges;
472  const std::string nodeID = attrs.get<std::string>(SUMO_ATTR_NODE, nullptr, ok);
473  std::vector<std::string> edgeIDs;
474  if (!attrs.hasAttribute(SUMO_ATTR_EDGES)) {
475  WRITE_ERRORF(TL("No edges specified for walkingArea at node '%'."), nodeID);
476  return;
477  }
478  for (const std::string& id : attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nodeID.c_str(), ok)) {
479  NBEdge* edge = myEdgeCont.retrieve(id);
480  if (edge == nullptr) {
481  WRITE_ERRORF(TL("Edge '%' for walkingArea at node '%' is not known."), id, nodeID);
482  return;
483  }
484  if (node == nullptr) {
485  if (edge->getToNode()->getID() == nodeID) {
486  node = edge->getToNode();
487  } else if (edge->getFromNode()->getID() == nodeID) {
488  node = edge->getFromNode();
489  } else {
490  WRITE_ERRORF(TL("Edge '%' does not touch node '%'."), id, nodeID);
491  return;
492  }
493  } else {
494  if (edge->getToNode() != node && edge->getFromNode() != node) {
495  WRITE_ERRORF(TL("Edge '%' does not touch node '%'."), id, nodeID);
496  return;
497  }
498  }
499  edges.push_back(edge);
500  }
501  if (!ok) {
502  return;
503  }
504  PositionVector customShape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector::EMPTY);
505  double customWidth = attrs.getOpt<double>(SUMO_ATTR_WIDTH, nullptr, ok, NBEdge::UNSPECIFIED_WIDTH);
506  if (!NBNetBuilder::transformCoordinates(customShape, true, myLocation)) {
507  WRITE_ERRORF(TL("Unable to project shape for walkingArea at node '%'."), node->getID());
508  }
509  node->addWalkingAreaShape(edges, customShape, customWidth);
510 }
511 
512 void
514  bool ok = true;
515  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, nullptr, ok, "");
516  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, nullptr, ok, "");
517  if (!ok) {
518  return;
519  }
520  NBConnection prohibitorC = parseConnectionDef("prohibitor", prohibitor);
521  NBConnection prohibitedC = parseConnectionDef("prohibited", prohibited);
522  if (prohibitorC == NBConnection::InvalidConnection || prohibitedC == NBConnection::InvalidConnection) {
523  // something failed
524  return;
525  }
526  NBNode* n = prohibitorC.getFrom()->getToNode();
527  n->addSortedLinkFoes(prohibitorC, prohibitedC);
528 }
529 
530 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#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::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
KeepClear
keepClear status of connections
Definition: NBCont.h:58
@ KEEPCLEAR_FALSE
Definition: NBCont.h:59
@ KEEPCLEAR_TRUE
Definition: NBCont.h:60
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...
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SUMO_TAG_CONNECTIONS
root element of connections file
@ SUMO_TAG_PROHIBITION
prohibition of circulation between two edges
@ SUMO_TAG_LOCATION
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_WALKINGAREA
walking area for pedestrians
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_DEL
delete certain element (note: DELETE is a macro)
@ SUMO_ATTR_NODE
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_INDIRECT
Whether this connection is an indirect (left) turn.
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_PROHIBITED
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_PASS
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_UNCONTROLLED
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_DISCARD
@ SUMO_ATTR_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_PROHIBITOR
@ SUMO_ATTR_CONTPOS
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_KEY
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_FRICTION
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 &plainFile, const std::string &suffix=".edg.xml")
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:154
void informf(const std::string &format, T value, Targs... Fargs)
adds a new formatted message
Definition: MsgHandler.h:122
NBEdge * getFrom() const
returns the from-edge (start of the connection)
static const NBConnection InvalidConnection
Definition: NBConnection.h:124
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:281
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass, KeepClear keepClear, double contPos, double visibility, double speed, double friction, double length, const PositionVector &customShape, bool uncontrolled, bool warnOnly, SVCPermissions permissions=SVC_UNSPECIFIED, bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED)
Adds a connection which could not be set during loading.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:481
bool wasRemoved(std::string id) const
Returns whether the edge with the id was deleted explicitly.
Definition: NBEdgeCont.h:491
The representation of a single edge during network building.
Definition: NBEdge.h:92
EdgeBuildingStep getStep() const
The building step of this edge.
Definition: NBEdge.h:631
bool addEdge2EdgeConnection(NBEdge *dest, bool overrideRemoval=false, SVCPermissions permission=SVC_UNSPECIFIED)
Adds a connection to another edge.
Definition: NBEdge.cpp:1091
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double friction=UNSPECIFIED_FRICTION, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED, const bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
Definition: NBEdge.cpp:1126
const std::string & getID() const
Definition: NBEdge.h:1524
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
@ EDGE2EDGES
The relationships between edges are computed/loaded.
@ LANES2EDGES
Lanes to edges - relationships are computed/loaded.
@ LANES2LANES_USER
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1280
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1441
bool isConnectedTo(const NBEdge *e, const bool ignoreTurnaround=false) const
Returns the information whethe a connection to the given edge has been added (or computed)
Definition: NBEdge.cpp:1324
std::string getLaneID(int lane) const
get lane ID
Definition: NBEdge.cpp:4006
@ USER
The connection was given by the user.
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:342
bool hasConnectionTo(const NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1318
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)
A definition of a pedestrian crossing.
Definition: NBNode.h:135
int customTLIndex
the custom traffic light index of this crossing (if controlled)
Definition: NBNode.h:165
int customTLIndex2
Definition: NBNode.h:166
bool priority
whether the pedestrians have priority
Definition: NBNode.h:158
double width
This crossing's width.
Definition: NBNode.h:150
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:57
bool wasRemoved(std::string id) const
Returns whether the node with the id was deleted explicitly.
Definition: NBNodeCont.h:287
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
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape, double width)
add custom shape for walkingArea
Definition: NBNode.cpp:3771
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
Definition: NBNode.cpp:426
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1886
A container for traffic light definitions and built programs.
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs, bool setLoaded=true)
Parses network location description and registers it with GeoConveHelper::setLoaded.
void delConnection(const SUMOSAXAttributes &attrs)
Parses a delete element that specifies a connection to delete.
MsgHandler *const myErrorMsgHandler
the handler for loading errors
void parseConnection(const SUMOSAXAttributes &attrs)
Parses a connection and adds it to the referenced edge.
bool parseLaneInfo(const SUMOSAXAttributes &attributes, NBEdge *fromEdge, NBEdge *toEdge, int *fromLane, int *toLane)
Parses information about lane-2-lane connection when it describes a lane-2-lane relationship.
bool parseLaneDefinition(const SUMOSAXAttributes &attributes, int *fromLane, int *toLane)
Parses information about lane-2-lane connection.
bool myHaveWarnedAboutDeprecatedLanes
Information whether we have a deprecated attribute.
NIXMLConnectionsHandler(NBEdgeCont &ec, NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Constructor.
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to (when invalidating tls)
bool parseDeprecatedLaneDefinition(const SUMOSAXAttributes &attributes, NBEdge *fromEdge, NBEdge *toEdge, int *fromLane, int *toLane)
Parses information about lane-2-lane connection in deprecated format.
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and updates the referenced node.
NBEdgeCont & myEdgeCont
The edge container to fill.
void myEndElement(int element)
Called when a closing tag occurs.
void addWalkingArea(const SUMOSAXAttributes &attrs)
Parses a walkingArea and updates the referenced node.
Parameterised * myLastParameterised
last item the could receive parameters
NBConnection parseConnectionDef(const std::string &defRole, const std::string &def)
Returns the connection described by def.
NBNodeCont & myNodeCont
The edge container to fill.
GeoConvHelper * myLocation
The coordinate transformation which was used compute the custom shape coordinates for connections and...
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void parseLaneBound(const SUMOSAXAttributes &attrs, NBEdge *from, NBEdge *to)
Parses a connection when it describes a lane-2-lane relationship.
void addCrossing(const SUMOSAXAttributes &attrs)
Parses a crossing and updates the referenced node.
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)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
A list of positions.
static const PositionVector EMPTY
empty Vector
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.
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 int toIntSecure(const std::string &sData, int def)
converts a string into the integer value described by it
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:201
double speed
custom speed for connection
Definition: NBEdge.h:240
KeepClear keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:231
double customLength
custom length for connection
Definition: NBEdge.h:246
bool uncontrolled
check if Connection is uncontrolled
Definition: NBEdge.h:297
PositionVector customShape
custom shape for connection
Definition: NBEdge.h:249
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:228
double contPos
custom position for internal junction on this connection
Definition: NBEdge.h:234
double visibility
custom foe visiblity for connection
Definition: NBEdge.h:237
double friction
Definition: NBEdge.h:243