Eclipse SUMO - Simulation of Urban MObility
NIImporter_SUMO.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 /****************************************************************************/
21 // Importer for networks stored in SUMO format
22 /****************************************************************************/
23 #include <config.h>
24 #include <string>
30 #include <utils/common/ToString.h>
34 #include <utils/xml/XMLSubSys.h>
38 #include <netbuild/NBEdge.h>
39 #include <netbuild/NBEdgeCont.h>
40 #include <netbuild/NBNode.h>
41 #include <netbuild/NBNodeCont.h>
43 #include <netbuild/NBNetBuilder.h>
44 #include "NILoader.h"
45 #include "NIXMLTypesHandler.h"
46 #include "NIImporter_SUMO.h"
47 
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 // ---------------------------------------------------------------------------
53 // static methods (interface in this case)
54 // ---------------------------------------------------------------------------
55 void
57  NIImporter_SUMO importer(nb);
58  importer._loadNetwork(oc);
59 }
60 
61 
62 // ---------------------------------------------------------------------------
63 // loader methods
64 // ---------------------------------------------------------------------------
66  : SUMOSAXHandler("sumo-network"),
67  myNetBuilder(nb),
68  myNodeCont(nb.getNodeCont()),
69  myTLLCont(nb.getTLLogicCont()),
70  myTypesHandler(nb.getTypeCont()),
71  myCurrentEdge(nullptr),
72  myCurrentLane(nullptr),
73  myCurrentTL(nullptr),
74  myLocation(nullptr),
75  myNetworkVersion(0),
76  myHaveSeenInternalEdge(false),
77  myAmLefthand(false),
78  myChangeLefthand(false),
79  myCornerDetail(0),
80  myLinkDetail(-1),
81  myRectLaneCut(false),
82  myWalkingAreas(false),
83  myLimitTurnSpeed(-1),
84  myCheckLaneFoesAll(false),
85  myCheckLaneFoesRoundabout(true),
86  myTlsIgnoreInternalJunctionJam(false),
87  myDefaultSpreadType(toString(LaneSpreadFunction::RIGHT)),
88  myGeomAvoidOverlap(true),
89  myJunctionsHigherSpeed(false),
90  myInternalJunctionsVehicleWidth(OptionsCont::getOptions().getFloat("internal-junctions.vehicle-width")) {
91 }
92 
93 
95  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
96  EdgeAttrs* ed = (*i).second;
97  for (std::vector<LaneAttrs*>::const_iterator j = ed->lanes.begin(); j != ed->lanes.end(); ++j) {
98  delete *j;
99  }
100  delete ed;
101  }
102  delete myLocation;
103 }
104 
105 
106 void
108  // check whether the option is set (properly)
109  if (!oc.isUsableFileList("sumo-net-file")) {
110  return;
111  }
112  const std::vector<std::string> discardableParams = oc.getStringVector("discard-params");
113  myDiscardableParams.insert(discardableParams.begin(), discardableParams.end());
114  // parse file(s)
115  const std::vector<std::string> files = oc.getStringVector("sumo-net-file");
116  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
117  if (!FileHelpers::isReadable(*file)) {
118  WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
119  return;
120  }
121  setFileName(*file);
122  PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'");
123  XMLSubSys::runParser(*this, *file, true);
125  }
126  // build edges
127  const double maxSegmentLength = oc.getFloat("geometry.max-segment-length");
128  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
129  EdgeAttrs* ed = (*i).second;
130  // skip internal edges
132  continue;
133  }
134  // get and check the nodes
135  NBNode* from = myNodeCont.retrieve(ed->fromNode);
136  NBNode* to = myNodeCont.retrieve(ed->toNode);
137  if (from == nullptr) {
138  WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
139  continue;
140  }
141  if (to == nullptr) {
142  WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
143  continue;
144  }
145  if (from == to) {
146  WRITE_ERROR("Edge's '" + ed->id + "' from-node and to-node '" + ed->toNode + "' are identical.");
147  continue;
148  }
149  if (ed->shape.size() == 0 && maxSegmentLength > 0) {
150  ed->shape.push_back(from->getPosition());
151  ed->shape.push_back(to->getPosition());
152  // shape is already cartesian but we must use a copy because the original will be modified
153  NBNetBuilder::addGeometrySegments(ed->shape, PositionVector(ed->shape), maxSegmentLength);
154  }
155  // build and insert the edge
156  NBEdge* e = new NBEdge(ed->id, from, to,
157  ed->type, ed->maxSpeed,
158  (int) ed->lanes.size(),
160  ed->shape, ed->lsf, ed->streetName, "", true); // always use tryIgnoreNodePositions to keep original shape
161  e->setLoadedLength(ed->length);
163  e->setDistance(ed->distance);
164  if (!myNetBuilder.getEdgeCont().insert(e)) {
165  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
166  delete e;
167  continue;
168  }
170  if (ed->builtEdge != nullptr) {
172  }
173  }
174  // assign further lane attributes (edges are built)
175  EdgeVector toRemove;
176  const bool dismissVclasses = oc.getBool("dismiss-vclasses");
177  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
178  EdgeAttrs* ed = (*i).second;
179  NBEdge* nbe = ed->builtEdge;
180  if (nbe == nullptr) { // inner edge or removed by explicit list, vclass, ...
181  continue;
182  }
183  const SumoXMLNodeType toType = nbe->getToNode()->getType();
184  for (int fromLaneIndex = 0; fromLaneIndex < (int) ed->lanes.size(); ++fromLaneIndex) {
185  LaneAttrs* lane = ed->lanes[fromLaneIndex];
186  // connections
187  const std::vector<Connection>& connections = lane->connections;
188  for (const Connection& c : connections) {
189  if (myEdges.count(c.toEdgeID) == 0) {
190  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
191  continue;
192  }
193  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
194  if (toEdge == nullptr) { // removed by explicit list, vclass, ...
195  continue;
196  }
197  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
198  // do not warn if this is a duplicate connection when merging networks
199  if (!nbe->hasConnectionTo(toEdge, c.toLaneIdx, fromLaneIndex)) {
200  WRITE_WARNINGF("Target lane '%' has multiple connections from '%'.", toEdge->getLaneID(c.toLaneIdx), nbe->getID());
201  }
202  }
203  // patch attribute uncontrolled for legacy networks where it is not set explicitly
204  bool uncontrolled = c.uncontrolled;
205 
206  if ((NBNode::isTrafficLight(toType) || toType == SumoXMLNodeType::RAIL_SIGNAL)
207  && c.tlLinkIndex == NBConnection::InvalidTlIndex) {
208  uncontrolled = true;
209  }
211  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::Lane2LaneInfoType::VALIDATED,
212  true, c.mayDefinitelyPass, c.keepClear ? KEEPCLEAR_TRUE : KEEPCLEAR_FALSE,
213  c.contPos, c.visibility, c.speed, c.customLength, c.customShape, uncontrolled, c.permissions, c.indirectLeft, c.edgeType, c.changeLeft, c.changeRight);
214  if (c.getParametersMap().size() > 0) {
215  nbe->getConnectionRef(fromLaneIndex, toEdge, c.toLaneIdx).updateParameters(c.getParametersMap());
216  }
217  // maybe we have a tls-controlled connection
218  if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) {
219  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
220  if (programs.size() > 0) {
221  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
222  for (it = programs.begin(); it != programs.end(); it++) {
223  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
224  if (tlDef) {
225  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkIndex, c.tlLinkIndex2, false);
226  } else {
227  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
228  }
229  }
230  } else {
231  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
232  }
233  }
234  }
235  // allow/disallow XXX preferred
236  if (!dismissVclasses) {
237  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow, myNetworkVersion), fromLaneIndex);
238  }
239  nbe->setPermittedChanging(fromLaneIndex, parseVehicleClasses(lane->changeLeft, ""), parseVehicleClasses(lane->changeRight, ""));
240  // width, offset
241  nbe->setLaneWidth(fromLaneIndex, lane->width);
242  nbe->setEndOffset(fromLaneIndex, lane->endOffset);
243  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
244  nbe->setAcceleration(fromLaneIndex, lane->accelRamp);
245  nbe->getLaneStruct(fromLaneIndex).oppositeID = lane->oppositeID;
246  nbe->getLaneStruct(fromLaneIndex).type = lane->type;
247  nbe->getLaneStruct(fromLaneIndex).updateParameters(lane->getParametersMap());
248  if (lane->customShape) {
249  nbe->setLaneShape(fromLaneIndex, lane->shape);
250  }
251  // stop offset for lane
252  bool stopOffsetSet = false;
253  if (lane->laneStopOffset.isDefined() || nbe->getEdgeStopOffset().isDefined()) {
254  // apply lane-specific stopOffset (might be none as well)
255  stopOffsetSet = nbe->setEdgeStopOffset(fromLaneIndex, lane->laneStopOffset);
256  }
257  if (!stopOffsetSet) {
258  // apply default stop offset to lane
259  nbe->setEdgeStopOffset(fromLaneIndex, nbe->getEdgeStopOffset());
260  }
261  }
263  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
264  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
265  }
267  nbe->setEndOffset(-1, nbe->getEndOffset(0));
268  }
269  if (!nbe->hasLaneSpecificStopOffsets() && nbe->getEdgeStopOffset().isDefined()) {
270  nbe->setEdgeStopOffset(-1, nbe->getEdgeStopOffset());
271  }
272  // check again after permissions are set
275  toRemove.push_back(nbe);
276  }
277  }
278  for (EdgeVector::iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
280  }
281  // insert loaded prohibitions
282  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
283  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
284  NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge;
285  NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge;
286  NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge;
287  if (prohibitedFrom == nullptr) {
288  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitedFrom);
289  } else if (prohibitedTo == nullptr) {
290  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitedTo);
291  } else if (prohibitorFrom == nullptr) {
292  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitorFrom);
293  } else if (prohibitorTo == nullptr) {
294  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitorTo);
295  } else {
296  NBNode* n = prohibitedFrom->getToNode();
298  NBConnection(prohibitorFrom, prohibitorTo),
299  NBConnection(prohibitedFrom, prohibitedTo));
300  }
301  }
302  if (!myHaveSeenInternalEdge && oc.isDefault("no-internal-links")) {
303  oc.set("no-internal-links", "true");
304  }
305  if (oc.isDefault("lefthand")) {
306  oc.set("lefthand", toString(myAmLefthand));
307  }
308  if (oc.isDefault("junctions.corner-detail")) {
309  oc.set("junctions.corner-detail", toString(myCornerDetail));
310  }
311  if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) {
312  oc.set("junctions.internal-link-detail", toString(myLinkDetail));
313  }
314  if (oc.isDefault("rectangular-lane-cut")) {
315  oc.set("rectangular-lane-cut", toString(myRectLaneCut));
316  }
317  if (oc.isDefault("walkingareas")) {
318  oc.set("walkingareas", toString(myWalkingAreas));
319  }
320  if (oc.isDefault("junctions.limit-turn-speed")) {
321  oc.set("junctions.limit-turn-speed", toString(myLimitTurnSpeed));
322  }
323  if (oc.isDefault("check-lane-foes.all") && oc.getBool("check-lane-foes.all") != myCheckLaneFoesAll) {
324  oc.set("check-lane-foes.all", toString(myCheckLaneFoesAll));
325  }
326  if (oc.isDefault("check-lane-foes.roundabout") && oc.getBool("check-lane-foes.roundabout") != myCheckLaneFoesRoundabout) {
327  oc.set("check-lane-foes.roundabout", toString(myCheckLaneFoesRoundabout));
328  }
329  if (oc.isDefault("tls.ignore-internal-junction-jam") && oc.getBool("tls.ignore-internal-junction-jam") != myTlsIgnoreInternalJunctionJam) {
330  oc.set("tls.ignore-internal-junction-jam", toString(myTlsIgnoreInternalJunctionJam));
331  }
332  if (oc.isDefault("default.spreadtype") && oc.getString("default.spreadtype") != myDefaultSpreadType) {
333  oc.set("default.spreadtype", myDefaultSpreadType);
334  }
335  if (oc.isDefault("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap") != myGeomAvoidOverlap) {
336  oc.set("geometry.avoid-overlap", toString(myGeomAvoidOverlap));
337  }
338  if (oc.isDefault("junctions.higher-speed") && oc.getBool("junctions.higher-speed") != myJunctionsHigherSpeed) {
339  oc.set("junctions.higher-speed", toString(myJunctionsHigherSpeed));
340  }
341  if (oc.isDefault("internal-junctions.vehicle-width") && oc.getFloat("internal-junctions.vehicle-width") != myInternalJunctionsVehicleWidth) {
342  oc.set("internal-junctions.vehicle-width", toString(myInternalJunctionsVehicleWidth));
343  }
344  if (!deprecatedVehicleClassesSeen.empty()) {
345  WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
347  }
348  if (!oc.getBool("no-internal-links")) {
349  // add loaded crossings
350  for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
351  NBNode* node = myNodeCont.retrieve((*it).first);
352  for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
353  const Crossing& crossing = (*it_c);
354  EdgeVector edges;
355  for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
356  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
357  // edge might have been removed due to options
358  if (edge != nullptr) {
359  edges.push_back(edge);
360  }
361  }
362  if (edges.size() > 0) {
363  node->addCrossing(edges, crossing.width, crossing.priority, crossing.customTLIndex, crossing.customTLIndex2, crossing.customShape, true);
364  }
365  }
366  }
367  // add walking area custom shapes
368  for (auto item : myWACustomShapes) {
369  std::string nodeID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(item.first);
370  NBNode* node = myNodeCont.retrieve(nodeID);
371  std::vector<std::string> edgeIDs;
372  if (item.second.fromEdges.size() + item.second.toEdges.size() == 0) {
373  // must be a split crossing
374  assert(item.second.fromCrossed.size() > 0);
375  assert(item.second.toCrossed.size() > 0);
376  edgeIDs = item.second.fromCrossed;
377  edgeIDs.insert(edgeIDs.end(), item.second.toCrossed.begin(), item.second.toCrossed.end());
378  } else if (item.second.fromEdges.size() > 0) {
379  edgeIDs = item.second.fromEdges;
380  } else {
381  edgeIDs = item.second.toEdges;
382  }
383  EdgeVector edges;
384  for (std::string edgeID : edgeIDs) {
385  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeID);
386  // edge might have been removed due to options
387  if (edge != nullptr) {
388  edges.push_back(edge);
389  }
390  }
391  if (edges.size() > 0) {
392  node->addWalkingAreaShape(edges, item.second.shape, item.second.width);
393  }
394  }
395  }
396  // add roundabouts
397  for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
398  EdgeSet roundabout;
399  for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
400  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
401  if (edge == nullptr) {
402  if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
403  WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
404  }
405  } else {
406  roundabout.insert(edge);
407  }
408  }
409  myNetBuilder.getEdgeCont().addRoundabout(roundabout);
410  }
411 }
412 
413 
414 
415 void
417  const SUMOSAXAttributes& attrs) {
418  /* our goal is to reproduce the input net faithfully
419  * there are different types of objects in the netfile:
420  * 1) those which must be loaded into NBNetBuilder-Containers for processing
421  * 2) those which can be ignored because they are recomputed based on group 1
422  * 3) those which are of no concern to NBNetBuilder but should be exposed to
423  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
424  * and hand them over to NETEDIT
425  * alternative idea: those shouldn't really be contained within the
426  * network but rather in separate files. teach NETEDIT how to open those
427  * (POI?)
428  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
429  * must be copied over - need to patch NBNetBuilder for this.
430  * copy unknown by default
431  */
432  switch (element) {
433  case SUMO_TAG_NET: {
434  bool ok;
435  myNetworkVersion = attrs.getOpt<double>(SUMO_ATTR_VERSION, nullptr, ok, 0);
436  myAmLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
437  myCornerDetail = attrs.getOpt<int>(SUMO_ATTR_CORNERDETAIL, nullptr, ok, 0);
438  myLinkDetail = attrs.getOpt<int>(SUMO_ATTR_LINKDETAIL, nullptr, ok, -1);
439  myRectLaneCut = attrs.getOpt<bool>(SUMO_ATTR_RECTANGULAR_LANE_CUT, nullptr, ok, false);
440  myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
441  myLimitTurnSpeed = attrs.getOpt<double>(SUMO_ATTR_LIMIT_TURN_SPEED, nullptr, ok, -1);
442  myCheckLaneFoesAll = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ALL, nullptr, ok, false);
443  myCheckLaneFoesRoundabout = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ROUNDABOUT, nullptr, ok, true);
445  myDefaultSpreadType = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, nullptr, ok, myDefaultSpreadType);
449  // derived
450  const OptionsCont& oc = OptionsCont::getOptions();
451  myChangeLefthand = !oc.isDefault("lefthand") && (oc.getBool("lefthand") != myAmLefthand);
452 
453  break;
454  }
455  case SUMO_TAG_EDGE:
456  addEdge(attrs);
457  break;
458  case SUMO_TAG_LANE:
459  addLane(attrs);
460  break;
461  case SUMO_TAG_STOPOFFSET: {
462  bool ok = true;
463  addStopOffsets(attrs, ok);
464  }
465  break;
466  case SUMO_TAG_NEIGH:
468  break;
469  case SUMO_TAG_JUNCTION:
470  addJunction(attrs);
471  break;
472  case SUMO_TAG_REQUEST:
473  addRequest(attrs);
474  break;
475  case SUMO_TAG_CONNECTION:
476  addConnection(attrs);
477  break;
478  case SUMO_TAG_TLLOGIC:
480  if (myCurrentTL) {
481  myLastParameterised.push_back(myCurrentTL);
482  }
483  break;
484  case SUMO_TAG_PHASE:
485  addPhase(attrs, myCurrentTL);
486  break;
487  case SUMO_TAG_LOCATION:
488  delete myLocation;
489  myLocation = loadLocation(attrs);
490  break;
492  addProhibition(attrs);
493  break;
494  case SUMO_TAG_ROUNDABOUT:
495  addRoundabout(attrs);
496  break;
497  case SUMO_TAG_PARAM:
498  if (myLastParameterised.size() != 0) {
499  bool ok = true;
500  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
501  if (myDiscardableParams.count(key) == 0) {
502  // circumventing empty string test
503  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
504  myLastParameterised.back()->setParameter(key, val);
505  }
506  }
507  break;
508  default:
509  myTypesHandler.myStartElement(element, attrs);
510  break;
511  }
512 }
513 
514 
515 void
517  switch (element) {
518  case SUMO_TAG_EDGE:
519  if (myCurrentEdge != nullptr) {
520  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
521  WRITE_WARNINGF("Edge '%' occurred at least twice in the input.", myCurrentEdge->id);
522  } else {
524  }
525  myCurrentEdge = nullptr;
526  myLastParameterised.pop_back();
527  }
528  break;
529  case SUMO_TAG_LANE:
530  if (myCurrentEdge != nullptr && myCurrentLane != nullptr) {
532  myCurrentEdge->lanes.push_back(myCurrentLane);
533  myLastParameterised.pop_back();
534  }
535  myCurrentLane = nullptr;
536  break;
537  case SUMO_TAG_TLLOGIC:
538  if (!myCurrentTL) {
539  WRITE_ERROR("Unmatched closing tag for tl-logic.");
540  } else {
541  if (!myTLLCont.insert(myCurrentTL)) {
542  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
543  delete myCurrentTL;
544  }
545  myCurrentTL = nullptr;
546  myLastParameterised.pop_back();
547  }
548  break;
549  case SUMO_TAG_JUNCTION:
550  if (myCurrentJunction.node != nullptr) {
551  myLastParameterised.pop_back();
552  }
553  break;
554  case SUMO_TAG_CONNECTION:
555  // !!! this just avoids a crash but is not a real check that it was a connection
556  if (!myLastParameterised.empty()) {
557  myLastParameterised.pop_back();
558  }
559  break;
560  default:
561  break;
562  }
563 }
564 
565 
566 void
568  // get the id, report an error if not given or empty...
569  bool ok = true;
570  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
571  if (!ok) {
572  return;
573  }
574  myCurrentEdge = new EdgeAttrs();
576  myCurrentEdge->builtEdge = nullptr;
577  myCurrentEdge->id = id;
578  // get the function
579  myCurrentEdge->func = attrs.getEdgeFunc(ok);
581  // add the crossing but don't do anything else
582  Crossing c(id);
583  c.crossingEdges = attrs.get<std::vector<std::string> >(SUMO_ATTR_CROSSING_EDGES, nullptr, ok);
585  return;
587  myHaveSeenInternalEdge = true;
588  return; // skip internal edges
589  }
590  // get the type
591  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
592  // get the origin and the destination node
593  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
594  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
595  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
596  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
600  myCurrentEdge->maxSpeed = 0;
601  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
602  myCurrentEdge->distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
603  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
604  OptionsCont::getOptions().set("output.street-names", "true");
605  }
606 
607  std::string lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, myDefaultSpreadType);
608  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
610  } else {
611  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
612  }
613 }
614 
615 
616 void
618  bool ok = true;
619  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
620  if (!ok) {
621  return;
622  }
623  if (!myCurrentEdge) {
624  WRITE_ERROR("Found lane '" + id + "' not within edge element.");
625  return;
626  }
627  const std::string expectedID = myCurrentEdge->id + "_" + toString(myCurrentEdge->lanes.size());
628  if (id != expectedID) {
629  WRITE_WARNING("Renaming lane '" + id + "' to '" + expectedID + "'.");
630  }
631  myCurrentLane = new LaneAttrs();
633  myCurrentLane->customShape = attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false);
634  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
635  myCurrentLane->width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_WIDTH);
636  myCurrentLane->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
638  // save the width and the lane id of the crossing but don't do anything else
640  assert(crossings.size() > 0);
641  crossings.back().width = attrs.get<double>(SUMO_ATTR_WIDTH, id.c_str(), ok);
642  if (myCurrentLane->customShape) {
643  crossings.back().customShape = myCurrentLane->shape;
644  NBNetBuilder::transformCoordinates(crossings.back().customShape, true, myLocation);
645  }
647  // save custom shape if needed but don't do anything else
648  if (myCurrentLane->customShape) {
650  wacs.shape = myCurrentLane->shape;
651  wacs.width = myCurrentLane->width;
654  }
655  return;
657  return; // skip internal edges
658  }
659  if (attrs.hasAttribute("maxspeed")) {
660  // !!! deprecated
661  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
662  } else {
663  myCurrentLane->maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
664  }
665  try {
666  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
667  } catch (EmptyData&) {
668  // !!! deprecated
669  myCurrentLane->allow = "";
670  }
671  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
672  myCurrentLane->endOffset = attrs.getOpt<double>(SUMO_ATTR_ENDOFFSET, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_OFFSET);
673  myCurrentLane->accelRamp = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
674  myCurrentLane->changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
675  myCurrentLane->changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
676  if (myChangeLefthand) {
678  }
679 
680  // lane coordinates are derived (via lane spread) do not include them in convex boundary
682 }
683 
684 
685 void
687  const StopOffset offset(attrs, ok);
688  if (!ok) {
689  return;
690  }
691  // Admissibility of value will be checked in _loadNetwork(), when lengths are known
692  if (myCurrentLane == nullptr) {
694  WRITE_WARNING("Duplicate definition of stopOffset for edge " + myCurrentEdge->id + ".\nIgnoring duplicate specification.");
695  } else {
696  myCurrentEdge->edgeStopOffset = offset;
697  }
698  } else {
700  WRITE_WARNING("Duplicate definition of lane's stopOffset on edge " + myCurrentEdge->id + ".\nIgnoring duplicate specifications.");
701  } else {
702  myCurrentLane->laneStopOffset = offset;
703  }
704  }
705 }
706 
707 
708 void
710  // get the id, report an error if not given or empty...
711  myCurrentJunction.node = nullptr;
712  myCurrentJunction.intLanes.clear();
713  myCurrentJunction.response.clear();
714  bool ok = true;
715  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
716  if (!ok) {
717  return;
718  }
719  if (id[0] == ':') { // internal node
720  return;
721  }
722  SumoXMLNodeType type = attrs.getNodeType(ok);
723  if (ok) {
725  // dead end is a computed status. Reset this to unknown so it will
726  // be corrected if additional connections are loaded
728  }
729  } else {
730  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
731  }
732  Position pos = readPosition(attrs, id, ok);
734  NBNode* node = new NBNode(id, pos, type);
735  myLastParameterised.push_back(node);
736  if (!myNodeCont.insert(node)) {
737  WRITE_WARNINGF("Junction '%' occurred at least twice in the input.", id);
738  delete node;
739  return;
740  }
741  myCurrentJunction.node = node;
742  myCurrentJunction.intLanes = attrs.get<std::vector<std::string> >(SUMO_ATTR_INTLANES, nullptr, ok, false);
743  // set optional radius
744  if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
745  node->setRadius(attrs.get<double>(SUMO_ATTR_RADIUS, id.c_str(), ok));
746  }
747  // handle custom shape
748  if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false)) {
749  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
751  node->setCustomShape(shape);
752  }
754  // both types of nodes come without a tlLogic
755  myRailSignals.insert(id);
756  }
758  node->setRightOfWay(attrs.getRightOfWay(ok));
759  }
760  if (attrs.hasAttribute(SUMO_ATTR_FRINGE)) {
761  node->setFringeType(attrs.getFringeType(ok));
762  }
763  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
764  node->setName(attrs.get<std::string>(SUMO_ATTR_NAME, id.c_str(), ok));
765  }
766 }
767 
768 
769 void
771  if (myCurrentJunction.node != nullptr) {
772  bool ok = true;
773  myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok));
774  }
775 }
776 
777 
778 void
780  bool ok = true;
781  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
782  if (myEdges.count(fromID) == 0) {
783  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
784  return;
785  }
786  EdgeAttrs* from = myEdges[fromID];
787  Connection conn;
788  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
789  int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
790  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
791  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
792  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, nullptr, ok, false);
793  conn.keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
794  conn.indirectLeft = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
795  conn.edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, nullptr, ok, "");
796  conn.contPos = attrs.getOpt<double>(SUMO_ATTR_CONTPOS, nullptr, ok, NBEdge::UNSPECIFIED_CONTPOS);
798  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "", false);
799  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "", false);
800  if (allow == "" && disallow == "") {
802  } else {
803  conn.permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
804  }
805  if (attrs.hasAttribute(SUMO_ATTR_CHANGE_LEFT)) {
806  conn.changeLeft = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok), "");
807  } else {
809  }
811  conn.changeRight = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok), "");
812  } else {
814  }
815  if (myChangeLefthand) {
816  std::swap(conn.changeLeft, conn.changeRight);
817  }
818  conn.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, NBEdge::UNSPECIFIED_SPEED);
819  conn.customLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, nullptr, ok, NBEdge::UNSPECIFIED_LOADED_LENGTH);
823  if (conn.tlID != "") {
824  conn.tlLinkIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
825  conn.tlLinkIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX2, nullptr, ok, -1);
826  } else {
828  }
829  if ((int)from->lanes.size() <= fromLaneIdx) {
830  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
831  return;
832  }
833  from->lanes[fromLaneIdx]->connections.push_back(conn);
834  myLastParameterised.push_back(&from->lanes[fromLaneIdx]->connections.back());
835 
836  // determine crossing priority and tlIndex
837  if (myPedestrianCrossings.size() > 0) {
839  // connection from walkingArea to crossing
840  std::vector<Crossing>& crossings = myPedestrianCrossings[SUMOXMLDefinitions::getJunctionIDFromInternalEdge(fromID)];
841  for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
842  if (conn.toEdgeID == (*it).edgeID) {
843  if (conn.tlID != "") {
844  (*it).priority = true;
845  (*it).customTLIndex = conn.tlLinkIndex;
846  } else {
847  LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
848  (*it).priority = state == LINKSTATE_MAJOR;
849  }
850  }
851  }
852  } else if (from->func == SumoXMLEdgeFunc::CROSSING && myEdges[conn.toEdgeID]->func == SumoXMLEdgeFunc::WALKINGAREA) {
853  // connection from crossing to walkingArea (set optional linkIndex2)
855  if (fromID == c.edgeID) {
856  c.customTLIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok, -1);
857  }
858  }
859  }
860  }
861  // determine walking area reference edges
862  if (myWACustomShapes.size() > 0) {
863  EdgeAttrs* to = myEdges[conn.toEdgeID];
864  if (from->func == SumoXMLEdgeFunc::WALKINGAREA) {
865  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(fromID);
866  if (it != myWACustomShapes.end()) {
867  if (to->func == SumoXMLEdgeFunc::NORMAL) {
868  // add target sidewalk as reference
869  it->second.toEdges.push_back(conn.toEdgeID);
870  } else if (to->func == SumoXMLEdgeFunc::CROSSING) {
871  // add target crossing edges as reference
873  if (conn.toEdgeID == crossing.edgeID) {
874  it->second.toCrossed.insert(it->second.toCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
875  }
876  }
877  }
878  }
879  } else if (to->func == SumoXMLEdgeFunc::WALKINGAREA) {
880  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(conn.toEdgeID);
881  if (it != myWACustomShapes.end()) {
882  if (from->func == SumoXMLEdgeFunc::NORMAL) {
883  // add origin sidewalk as reference
884  it->second.fromEdges.push_back(fromID);
885  } else if (from->func == SumoXMLEdgeFunc::CROSSING) {
886  // add origin crossing edges as reference
888  if (fromID == crossing.edgeID) {
889  it->second.fromCrossed.insert(it->second.fromCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
890  }
891  }
892  }
893  }
894  }
895  }
896 }
897 
898 
899 void
901  bool ok = true;
902  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, nullptr, ok, "");
903  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, nullptr, ok, "");
904  if (!ok) {
905  return;
906  }
907  Prohibition p;
910  if (!ok) {
911  return;
912  }
913  myProhibitions.push_back(p);
914 }
915 
916 
919  if (currentTL) {
920  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
921  return nullptr;
922  }
923  bool ok = true;
924  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
925  SUMOTime offset = TIME2STEPS(attrs.get<double>(SUMO_ATTR_OFFSET, id.c_str(), ok));
926  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
927  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, nullptr, ok);
928  TrafficLightType type;
929  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
931  } else {
932  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
933  return nullptr;
934  }
935  if (ok) {
936  return new NBLoadedSUMOTLDef(id, programID, offset, type);
937  } else {
938  return nullptr;
939  }
940 }
941 
942 
943 void
945  if (!currentTL) {
946  WRITE_ERROR("found phase without tl-logic");
947  return;
948  }
949  const std::string& id = currentTL->getID();
950  bool ok = true;
951  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
952  SUMOTime duration = TIME2STEPS(attrs.get<double>(SUMO_ATTR_DURATION, id.c_str(), ok));
953  if (duration < 0) {
954  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
955  return;
956  }
957  // if the traffic light is an actuated traffic light, try to get
958  // the minimum and maximum durations
961  std::vector<int> nextPhases = attrs.getOptIntVector(SUMO_ATTR_NEXT, nullptr, ok);
962  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, nullptr, ok, "");
963  if (ok) {
964  currentTL->addPhase(duration, state, minDuration, maxDuration, nextPhases, name);
965  }
966 }
967 
968 
971  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
972  bool ok = true;
973  GeoConvHelper* result = nullptr;
974  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
975  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
976  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
977  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
978  if (ok) {
979  Position networkOffset = s[0];
980  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
981  GeoConvHelper::setLoaded(*result);
982  }
983  return result;
984 }
985 
986 
987 Position
988 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
989  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
990  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
991  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
992  return Position(x, y, z);
993 }
994 
995 
996 void
997 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
998  // split from/to
999  const std::string::size_type div = attr.find("->");
1000  if (div == std::string::npos) {
1001  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
1002  ok = false;
1003  }
1004  from = attr.substr(0, div);
1005  to = attr.substr(div + 2);
1006  // check whether the definition includes a lane information and discard it
1007  if (from.find('_') != std::string::npos) {
1008  from = from.substr(0, from.find('_'));
1009  }
1010  if (to.find('_') != std::string::npos) {
1011  to = to.substr(0, to.find('_'));
1012  }
1013  // check whether the edges are known
1014  if (myEdges.count(from) == 0) {
1015  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
1016  ok = false;
1017  }
1018  if (myEdges.count(to) == 0) {
1019  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
1020  ok = false;
1021  }
1022 }
1023 
1024 
1025 void
1027  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
1028  myRoundabouts.push_back(attrs.getStringVector(SUMO_ATTR_EDGES));
1029  } else {
1030  WRITE_ERROR("Empty edges in roundabout.");
1031  }
1032 }
1033 
1034 
1035 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:281
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:284
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:283
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
@ KEEPCLEAR_FALSE
Definition: NBCont.h:59
@ KEEPCLEAR_TRUE
Definition: NBCont.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
std::set< std::string > deprecatedVehicleClassesSeen
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...
@ RIGHT
At the rightmost side of the lane.
TrafficLightType
@ SUMO_TAG_PHASE
a single phase description
@ SUMO_TAG_NET
root element of a network file
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_REQUEST
description of a logic request within the junction
@ SUMO_TAG_PROHIBITION
prohibition of circulation between two edges
@ SUMO_TAG_LOCATION
@ SUMO_TAG_CONNECTION
connectio between two lanes
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_TAG_JUNCTION
begin/end of the description of a 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_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...
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_MAJOR
This is an uncontrolled, major link, may pass.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_CONV_BOUNDARY
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_NET_OFFSET
@ SUMO_ATTR_ORIG_BOUNDARY
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_LINKDETAIL
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_CORNERDETAIL
@ SUMO_ATTR_RADIUS
The turning radius at an intersection in m.
@ SUMO_ATTR_INDIRECT
Whether this connection is an indirect (left) turn.
@ SUMO_ATTR_RECTANGULAR_LANE_CUT
@ SUMO_ATTR_Y
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_Z
@ SUMO_ATTR_RESPONSE
@ SUMO_ATTR_LIMIT_TURN_SPEED
@ SUMO_ATTR_CHECKLANEFOES_ROUNDABOUT
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_X
@ SUMO_ATTR_AVOID_OVERLAP
@ SUMO_ATTR_CUSTOMSHAPE
whether a given shape is user-defined
@ SUMO_ATTR_INTLANES
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_FRINGE
Fringe type of node.
@ SUMO_ATTR_PROHIBITED
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LEFTHAND
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_NAME
@ SUMO_ATTR_ORIG_PROJ
@ SUMO_ATTR_CHECKLANEFOES_ALL
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
@ SUMO_ATTR_PASS
@ SUMO_ATTR_ENDOFFSET
@ SUMO_ATTR_HIGHER_SPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_UNCONTROLLED
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_VERSION
@ SUMO_ATTR_ID
@ SUMO_ATTR_MAXDURATION
maximum duration of a phase
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_PROHIBITOR
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_CONTPOS
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_CROSSING_EDGES
the edges crossed by a pedestrian crossing
@ SUMO_ATTR_TLS_IGNORE_INTERNAL_JUNCTION_JAM
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_MINDURATION
@ SUMO_ATTR_KEY
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_INTERNAL_JUNCTIONS_VEHICLE_WIDTH
@ SUMO_ATTR_STATE
The state of a link.
@ SUMO_ATTR_WALKINGAREAS
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:49
void setFileName(const std::string &name)
Sets the current file name.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
static const int InvalidTlIndex
Definition: NBConnection.h:123
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
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 ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:199
void ignore(std::string id)
mark the given edge id as ignored
Definition: NBEdgeCont.h:507
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 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
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
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3953
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:630
Connection & getConnectionRef(int fromLane, const NBEdge *to, int toLane)
Returns reference to the specified connection This method goes through "myConnections" and returns th...
Definition: NBEdge.cpp:1234
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
Definition: NBEdge.h:376
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
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
Definition: NBEdge.cpp:2369
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
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
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 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:1060
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:358
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:361
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2336
std::string getLaneID(int lane) const
get lane ID
Definition: NBEdge.cpp:3693
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:355
@ VALIDATED
The connection was computed and validated.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2358
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:3977
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:349
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1249
void declareConnectionsAsLoaded(EdgeBuildingStep step=EdgeBuildingStep::LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1382
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:660
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
A loaded (complete) traffic light logic.
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct=true)
Adds a connection and immediately informs the edges.
void addPhase(SUMOTime duration, const std::string &state, SUMOTime minDur, SUMOTime maxDur, const std::vector< int > &next, const std::string &name)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases.
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:168
static int addGeometrySegments(PositionVector &from, const PositionVector &cartesian, const double maxLength)
insertion geometry points to ensure maximum segment length between points
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:148
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
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape, double width)
add custom shape for walkingArea
Definition: NBNode.cpp:3333
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:273
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:543
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:2424
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3555
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false)
add a pedestrian crossing to this node
Definition: NBNode.cpp:3395
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1774
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:533
void setName(const std::string &name)
set intersection name
Definition: NBNode.h:553
const Position & getPosition() const
Definition: NBNode.h:248
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition: NBNode.h:548
const std::string & getProgramID() const
Returns the ProgramID.
static const SUMOTime UNSPECIFIED_DURATION
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A connection description.
PositionVector customShape
custom shape connection
std::string tlID
The id of the traffic light that controls this connection.
double speed
custom speed for connection
std::string edgeType
optional edge type
std::string toEdgeID
The id of the target edge.
double customLength
custom length for connection
double contPos
custom position for internal junction on this connection
int toLaneIdx
The index of the target lane.
int tlLinkIndex
The index of this connection within the controlling traffic light.
bool indirectLeft
Whether this connection is an indirect left turn.
double visibility
custom foe visibility for connection
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
SVCPermissions changeLeft
custom lane changing permissions for connection
SVCPermissions changeRight
custom lane changing permissions for connection
bool uncontrolled
if set to true, This connection will not be TLS-controlled despite its node being controlled.
SVCPermissions permissions
custom permissions for connection
Describes the values found in an edge's definition and this edge's lanes.
LaneSpreadFunction lsf
The lane spread function.
std::vector< LaneAttrs * > lanes
This edge's lanes.
StopOffset edgeStopOffset
This edge's vehicle specific stop offsets (used for lanes, that do not have a specified stopOffset)
PositionVector shape
This edges's shape.
int priority
This edge's priority.
std::string toNode
The node this edge ends at.
std::string type
This edge's type.
double maxSpeed
The maximum velocity allowed on this edge (!!!)
NBEdge * builtEdge
The built edge.
SumoXMLEdgeFunc func
This edge's function.
std::string streetName
This edge's street name.
std::string fromNode
The node this edge starts at.
double length
The length of the edge if set explicitly.
std::string id
This edge's id.
double distance
The position at the start of this edge (kilometrage/mileage)
Describes the values found in a lane's definition.
double maxSpeed
The maximum velocity allowed on this lane.
std::string changeRight
This lane's vehicle classes allowed to change right.
double endOffset
This lane's offset from the intersection.
bool accelRamp
Whether this lane is an acceleration lane.
std::string oppositeID
This lane's opposite lane.
std::string type
the type of this lane
std::vector< Connection > connections
This lane's connections.
bool customShape
Whether this lane has a custom shape.
StopOffset laneStopOffset
This lane's vehicle specific stop offsets.
PositionVector shape
This lane's shape (may be custom)
std::string changeLeft
This lane's vehicle classes allowed to change left.
double width
The width of this lane.
std::string disallow
This lane's disallowed vehicle classes.
std::string allow
This lane's allowed vehicle classes.
Importer for networks stored in SUMO format.
GeoConvHelper * myLocation
The coordinate transformation which was used to build the loaded network.
static NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
begins the reading of a traffic lights logic
void parseProhibitionConnection(const std::string &attr, std::string &from, std::string &to, bool &ok)
parses connection string of a prohibition (very old school)
~NIImporter_SUMO()
Destructor.
NIXMLTypesHandler myTypesHandler
The handler for parsing edge types and restrictions.
int myCornerDetail
the level of corner detail in the loaded network
bool myCheckLaneFoesAll
whether foe-relationships where checked at lane-level
double myLimitTurnSpeed
whether turning speed was limited in the network
std::set< std::string > myRailSignals
list of node id with rail signals (no NBTrafficLightDefinition exists)
bool myGeomAvoidOverlap
overlap option for loaded network
std::map< std::string, std::vector< Crossing > > myPedestrianCrossings
The pedestrian crossings found in the network.
bool myCheckLaneFoesRoundabout
JunctionAttrs myCurrentJunction
The currently parsed junction definition to help in reconstructing crossings.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
bool myAmLefthand
whether the loaded network was built for lefthand traffic
bool myRectLaneCut
whether all lanes of an edge should have the same stop line
std::vector< Parameterised * > myLastParameterised
element to receive parameters
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myInternalJunctionsVehicleWidth
custom settings for internal junction computation
std::string myDefaultSpreadType
default spreadType defined in the network
bool myJunctionsHigherSpeed
higherSpeed option for loaded network
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
static void loadNetwork(OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
std::vector< std::vector< std::string > > myRoundabouts
loaded roundabout edges
bool myChangeLefthand
whether the the written network should have a different "handedness" (LHT/RHT) than the loaded networ...
void addConnection(const SUMOSAXAttributes &attrs)
Parses a connection and saves it into the lane's definition stored in "myCurrentLane".
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
LaneAttrs * myCurrentLane
The currently parsed lanes's definition (to add the shape to)
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and stores the values in "myCurrentLane".
NBNodeCont & myNodeCont
The node container to fill.
EdgeAttrs * myCurrentEdge
The currently parsed edge's definition (to add loaded lanes to)
NBNetBuilder & myNetBuilder
The network builder to fill.
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
std::vector< Prohibition > myProhibitions
Loaded prohibitions.
double myNetworkVersion
the loaded network version
void _loadNetwork(OptionsCont &oc)
load the network
void myEndElement(int element)
Called when a closing tag occurs.
bool myTlsIgnoreInternalJunctionJam
whether some right-of-way checks at traffic light junctions should be disabled
void addStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
parses stop offsets for the current lane or edge
static Position readPosition(const SUMOSAXAttributes &attrs, const std::string &id, bool &ok)
read position from the given attributes, attribute errors to id
static void addPhase(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
adds a phase to the traffic lights logic currently build
int myLinkDetail
the level of geometry detail for internal lanes in the loaded network
std::map< std::string, WalkingAreaParsedCustomShape > myWACustomShapes
Map from walkingArea edge IDs to custom shapes.
bool myWalkingAreas
whether walkingareas must be built
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
NIImporter_SUMO(NBNetBuilder &nb)
Constructor.
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and saves it.
void addRequest(const SUMOSAXAttributes &attrs)
Parses a reques and saves selected attributes in myCurrentJunction.
std::set< std::string > myDiscardableParams
list of parameter keys to discard
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
std::map< std::string, EdgeAttrs * > myEdges
Loaded edge definitions.
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag; Parses edge type information.
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)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
void updateParameters(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
static const PositionVector EMPTY
empty Vector
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 > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
virtual FringeType getFringeType(bool &ok) const =0
returns fringe type
virtual RightOfWay getRightOfWay(bool &ok) const =0
Returns the right-of-way method.
virtual double getFloat(int id) const =0
Returns the double-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.
const std::vector< int > getOptIntVector(int attr, const char *objectid, bool &ok, bool report=true) const
convenience function to avoid the default argument and the template stuff at getOpt<>
virtual SumoXMLNodeType getNodeType(bool &ok) const =0
Returns the value of the named attribute.
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.
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
SAX-handler base for SUMO-files.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< LinkState > LinkStates
link states
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea
stop offset
bool isDefined() const
check if stopOffset was defined
T get(const std::string &str) const
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:149
std::string type
the type of this lane
Definition: NBEdge.h:188
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:175
Describes a pedestrian crossing.
std::vector< std::string > crossingEdges
std::vector< std::string > response
std::vector< std::string > intLanes
Describes the values found in a prohibition.
Describes custom shape for a walking area during parsing.