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-2020 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  myCornerDetail(0),
79  myLinkDetail(-1),
80  myRectLaneCut(false),
81  myWalkingAreas(false),
82  myLimitTurnSpeed(-1),
83  myCheckLaneFoesAll(false),
84  myCheckLaneFoesRoundabout(true),
85  myTlsIgnoreInternalJunctionJam(false),
86  myDefaultSpreadType(toString(LaneSpreadFunction::RIGHT)),
87  myGeomAvoidOverlap(true) {
88 }
89 
90 
92  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
93  EdgeAttrs* ed = (*i).second;
94  for (std::vector<LaneAttrs*>::const_iterator j = ed->lanes.begin(); j != ed->lanes.end(); ++j) {
95  delete *j;
96  }
97  delete ed;
98  }
99  delete myLocation;
100 
101 }
102 
103 
104 void
106  // check whether the option is set (properly)
107  if (!oc.isUsableFileList("sumo-net-file")) {
108  return;
109  }
110  const std::vector<std::string> discardableParams = oc.getStringVector("discard-params");
111  myDiscardableParams.insert(discardableParams.begin(), discardableParams.end());
112  // parse file(s)
113  const std::vector<std::string> files = oc.getStringVector("sumo-net-file");
114  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
115  if (!FileHelpers::isReadable(*file)) {
116  WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
117  return;
118  }
119  setFileName(*file);
120  PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'");
121  XMLSubSys::runParser(*this, *file, true);
123  }
124  // build edges
125  const double maxSegmentLength = oc.getFloat("geometry.max-segment-length");
126  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
127  EdgeAttrs* ed = (*i).second;
128  // skip internal edges
130  continue;
131  }
132  // get and check the nodes
133  NBNode* from = myNodeCont.retrieve(ed->fromNode);
134  NBNode* to = myNodeCont.retrieve(ed->toNode);
135  if (from == nullptr) {
136  WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
137  continue;
138  }
139  if (to == nullptr) {
140  WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
141  continue;
142  }
143  if (from == to) {
144  WRITE_ERROR("Edge's '" + ed->id + "' from-node and to-node '" + ed->toNode + "' are identical.");
145  continue;
146  }
147  if (ed->shape.size() == 0 && maxSegmentLength > 0) {
148  ed->shape.push_back(from->getPosition());
149  ed->shape.push_back(to->getPosition());
150  // shape is already cartesian but we must use a copy because the original will be modified
151  NBNetBuilder::addGeometrySegments(ed->shape, PositionVector(ed->shape), maxSegmentLength);
152  }
153  // build and insert the edge
154  NBEdge* e = new NBEdge(ed->id, from, to,
155  ed->type, ed->maxSpeed,
156  (int) ed->lanes.size(),
158  ed->shape, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape
159  e->setLoadedLength(ed->length);
161  e->setDistance(ed->distance);
162  if (!myNetBuilder.getEdgeCont().insert(e)) {
163  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
164  delete e;
165  continue;
166  }
168  if (ed->builtEdge != nullptr) {
169  ed->builtEdge->setStopOffsets(-1, ed->stopOffsets);
170  }
171  }
172  // assign further lane attributes (edges are built)
173  EdgeVector toRemove;
174  const bool dismissVclasses = oc.getBool("dismiss-vclasses");
175  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
176  EdgeAttrs* ed = (*i).second;
177  NBEdge* nbe = ed->builtEdge;
178  if (nbe == nullptr) { // inner edge or removed by explicit list, vclass, ...
179  continue;
180  }
181  const SumoXMLNodeType toType = nbe->getToNode()->getType();
182  for (int fromLaneIndex = 0; fromLaneIndex < (int) ed->lanes.size(); ++fromLaneIndex) {
183  LaneAttrs* lane = ed->lanes[fromLaneIndex];
184  // connections
185  const std::vector<Connection>& connections = lane->connections;
186  for (const Connection& c : connections) {
187  if (myEdges.count(c.toEdgeID) == 0) {
188  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
189  continue;
190  }
191  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
192  if (toEdge == nullptr) { // removed by explicit list, vclass, ...
193  continue;
194  }
195  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
196  WRITE_WARNINGF("Target lane '%' has multiple connections from '%'.", toEdge->getLaneID(c.toLaneIdx), nbe->getID());
197  }
198  // patch attribute uncontrolled for legacy networks where it is not set explicitly
199  bool uncontrolled = c.uncontrolled;
200 
201  if ((NBNode::isTrafficLight(toType) || toType == SumoXMLNodeType::RAIL_SIGNAL)
202  && c.tlLinkIndex == NBConnection::InvalidTlIndex) {
203  uncontrolled = true;
204  }
206  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::Lane2LaneInfoType::VALIDATED,
207  true, c.mayDefinitelyPass, c.keepClear ? KEEPCLEAR_TRUE : KEEPCLEAR_FALSE,
208  c.contPos, c.visibility, c.speed, c.customLength, c.customShape, uncontrolled, c.permissions);
209  if (c.getParametersMap().size() > 0) {
210  nbe->getConnectionRef(fromLaneIndex, toEdge, c.toLaneIdx).updateParameters(c.getParametersMap());
211  }
212  // maybe we have a tls-controlled connection
213  if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) {
214  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
215  if (programs.size() > 0) {
216  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
217  for (it = programs.begin(); it != programs.end(); it++) {
218  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
219  if (tlDef) {
220  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkIndex, c.tlLinkIndex2, false);
221  } else {
222  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
223  }
224  }
225  } else {
226  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
227  }
228  }
229  }
230  // allow/disallow XXX preferred
231  if (!dismissVclasses) {
232  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow, myNetworkVersion), fromLaneIndex);
233  }
234  // width, offset
235  nbe->setLaneWidth(fromLaneIndex, lane->width);
236  nbe->setEndOffset(fromLaneIndex, lane->endOffset);
237  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
238  nbe->setAcceleration(fromLaneIndex, lane->accelRamp);
239  nbe->getLaneStruct(fromLaneIndex).oppositeID = lane->oppositeID;
240  nbe->getLaneStruct(fromLaneIndex).type = lane->type;
241  nbe->getLaneStruct(fromLaneIndex).updateParameters(lane->getParametersMap());
242  if (lane->customShape) {
243  nbe->setLaneShape(fromLaneIndex, lane->shape);
244  }
245  // stop offset for lane
246  bool stopOffsetSet = false;
247  if (lane->stopOffsets.size() != 0 || nbe->getStopOffsets().size() == 0) {
248  // apply lane-specific stopOffset (might be none as well)
249  stopOffsetSet = nbe->setStopOffsets(fromLaneIndex, lane->stopOffsets);
250  }
251  if (!stopOffsetSet) {
252  // apply default stop offset to lane
253  nbe->setStopOffsets(fromLaneIndex, nbe->getStopOffsets());
254  }
255  }
257  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
258  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
259  }
261  nbe->setEndOffset(-1, nbe->getEndOffset(0));
262  }
263  if (!nbe->hasLaneSpecificStopOffsets() && nbe->getStopOffsets().size() != 0) {
264  nbe->setStopOffsets(-1, nbe->getStopOffsets());
265  }
266  // check again after permissions are set
269  toRemove.push_back(nbe);
270  }
271  }
272  for (EdgeVector::iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
274  }
275  // insert loaded prohibitions
276  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
277  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
278  NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge;
279  NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge;
280  NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge;
281  if (prohibitedFrom == nullptr) {
282  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitedFrom);
283  } else if (prohibitedTo == nullptr) {
284  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitedTo);
285  } else if (prohibitorFrom == nullptr) {
286  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitorFrom);
287  } else if (prohibitorTo == nullptr) {
288  WRITE_WARNINGF("Edge '%' in prohibition was not built.", it->prohibitorTo);
289  } else {
290  NBNode* n = prohibitedFrom->getToNode();
292  NBConnection(prohibitorFrom, prohibitorTo),
293  NBConnection(prohibitedFrom, prohibitedTo));
294  }
295  }
296  if (!myHaveSeenInternalEdge && oc.isDefault("no-internal-links")) {
297  oc.set("no-internal-links", "true");
298  }
299  if (oc.isDefault("lefthand")) {
300  oc.set("lefthand", toString(myAmLefthand));
301  }
302  if (oc.isDefault("junctions.corner-detail")) {
303  oc.set("junctions.corner-detail", toString(myCornerDetail));
304  }
305  if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) {
306  oc.set("junctions.internal-link-detail", toString(myLinkDetail));
307  }
308  if (oc.isDefault("rectangular-lane-cut")) {
309  oc.set("rectangular-lane-cut", toString(myRectLaneCut));
310  }
311  if (oc.isDefault("walkingareas")) {
312  oc.set("walkingareas", toString(myWalkingAreas));
313  }
314  if (oc.isDefault("junctions.limit-turn-speed")) {
315  oc.set("junctions.limit-turn-speed", toString(myLimitTurnSpeed));
316  }
317  if (oc.isDefault("check-lane-foes.all") && oc.getBool("check-lane-foes.all") != myCheckLaneFoesAll) {
318  oc.set("check-lane-foes.all", toString(myCheckLaneFoesAll));
319  }
320  if (oc.isDefault("check-lane-foes.roundabout") && oc.getBool("check-lane-foes.roundabout") != myCheckLaneFoesRoundabout) {
321  oc.set("check-lane-foes.roundabout", toString(myCheckLaneFoesRoundabout));
322  }
323  if (oc.isDefault("tls.ignore-internal-junction-jam") && oc.getBool("tls.ignore-internal-junction-jam") != myTlsIgnoreInternalJunctionJam) {
324  oc.set("tls.ignore-internal-junction-jam", toString(myTlsIgnoreInternalJunctionJam));
325  }
326  if (oc.isDefault("default.spreadtype") && oc.getString("default.spreadtype") != myDefaultSpreadType) {
327  oc.set("default.spreadtype", myDefaultSpreadType);
328  }
329  if (oc.isDefault("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap") != myGeomAvoidOverlap) {
330  oc.set("geometry.avoid-overlap", toString(myGeomAvoidOverlap));
331  }
332  if (!deprecatedVehicleClassesSeen.empty()) {
333  WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
335  }
336  if (!oc.getBool("no-internal-links")) {
337  // add loaded crossings
338  for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
339  NBNode* node = myNodeCont.retrieve((*it).first);
340  for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
341  const Crossing& crossing = (*it_c);
342  EdgeVector edges;
343  for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
344  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
345  // edge might have been removed due to options
346  if (edge != nullptr) {
347  edges.push_back(edge);
348  }
349  }
350  if (edges.size() > 0) {
351  node->addCrossing(edges, crossing.width, crossing.priority, crossing.customTLIndex, crossing.customTLIndex2, crossing.customShape, true);
352  }
353  }
354  }
355  // add walking area custom shapes
356  for (auto item : myWACustomShapes) {
357  std::string nodeID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(item.first);
358  NBNode* node = myNodeCont.retrieve(nodeID);
359  std::vector<std::string> edgeIDs;
360  if (item.second.fromEdges.size() + item.second.toEdges.size() == 0) {
361  // must be a split crossing
362  assert(item.second.fromCrossed.size() > 0);
363  assert(item.second.toCrossed.size() > 0);
364  edgeIDs = item.second.fromCrossed;
365  edgeIDs.insert(edgeIDs.end(), item.second.toCrossed.begin(), item.second.toCrossed.end());
366  } else if (item.second.fromEdges.size() > 0) {
367  edgeIDs = item.second.fromEdges;
368  } else {
369  edgeIDs = item.second.toEdges;
370  }
371  EdgeVector edges;
372  for (std::string edgeID : edgeIDs) {
373  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeID);
374  // edge might have been removed due to options
375  if (edge != nullptr) {
376  edges.push_back(edge);
377  }
378  }
379  if (edges.size() > 0) {
380  node->addWalkingAreaShape(edges, item.second.shape);
381  }
382  }
383  }
384  // add roundabouts
385  for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
386  EdgeSet roundabout;
387  for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
388  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
389  if (edge == nullptr) {
390  if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
391  WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
392  }
393  } else {
394  roundabout.insert(edge);
395  }
396  }
397  myNetBuilder.getEdgeCont().addRoundabout(roundabout);
398  }
399 }
400 
401 
402 
403 void
405  const SUMOSAXAttributes& attrs) {
406  /* our goal is to reproduce the input net faithfully
407  * there are different types of objects in the netfile:
408  * 1) those which must be loaded into NBNetBuilder-Containers for processing
409  * 2) those which can be ignored because they are recomputed based on group 1
410  * 3) those which are of no concern to NBNetBuilder but should be exposed to
411  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
412  * and hand them over to NETEDIT
413  * alternative idea: those shouldn't really be contained within the
414  * network but rather in separate files. teach NETEDIT how to open those
415  * (POI?)
416  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
417  * must be copied over - need to patch NBNetBuilder for this.
418  * copy unknown by default
419  */
420  switch (element) {
421  case SUMO_TAG_NET: {
422  bool ok;
423  myNetworkVersion = attrs.getOpt<double>(SUMO_ATTR_VERSION, nullptr, ok, 0);
424  myAmLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
425  myCornerDetail = attrs.getOpt<int>(SUMO_ATTR_CORNERDETAIL, nullptr, ok, 0);
426  myLinkDetail = attrs.getOpt<int>(SUMO_ATTR_LINKDETAIL, nullptr, ok, -1);
427  myRectLaneCut = attrs.getOpt<bool>(SUMO_ATTR_RECTANGULAR_LANE_CUT, nullptr, ok, false);
428  myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
429  myLimitTurnSpeed = attrs.getOpt<double>(SUMO_ATTR_LIMIT_TURN_SPEED, nullptr, ok, -1);
430  myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
431  myCheckLaneFoesAll = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ALL, nullptr, ok, false);
432  myCheckLaneFoesRoundabout = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ROUNDABOUT, nullptr, ok, true);
434  myDefaultSpreadType = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, nullptr, ok, myDefaultSpreadType);
436 
437  break;
438  }
439  case SUMO_TAG_EDGE:
440  addEdge(attrs);
441  break;
442  case SUMO_TAG_LANE:
443  addLane(attrs);
444  break;
445  case SUMO_TAG_STOPOFFSET: {
446  bool ok = true;
447  addStopOffsets(attrs, ok);
448  }
449  break;
450  case SUMO_TAG_NEIGH:
452  break;
453  case SUMO_TAG_JUNCTION:
454  addJunction(attrs);
455  break;
456  case SUMO_TAG_REQUEST:
457  addRequest(attrs);
458  break;
459  case SUMO_TAG_CONNECTION:
460  addConnection(attrs);
461  break;
462  case SUMO_TAG_TLLOGIC:
464  if (myCurrentTL) {
465  myLastParameterised.push_back(myCurrentTL);
466  }
467  break;
468  case SUMO_TAG_PHASE:
469  addPhase(attrs, myCurrentTL);
470  break;
471  case SUMO_TAG_LOCATION:
472  myLocation = loadLocation(attrs);
473  break;
475  addProhibition(attrs);
476  break;
477  case SUMO_TAG_ROUNDABOUT:
478  addRoundabout(attrs);
479  break;
480  case SUMO_TAG_PARAM:
481  if (myLastParameterised.size() != 0) {
482  bool ok = true;
483  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
484  if (myDiscardableParams.count(key) == 0) {
485  // circumventing empty string test
486  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
487  myLastParameterised.back()->setParameter(key, val);
488  }
489  }
490  break;
491  default:
492  myTypesHandler.myStartElement(element, attrs);
493  break;
494  }
495 }
496 
497 
498 void
500  switch (element) {
501  case SUMO_TAG_EDGE:
502  if (myCurrentEdge != nullptr) {
503  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
504  WRITE_ERROR("Edge '" + myCurrentEdge->id + "' occurred at least twice in the input.");
505  } else {
507  }
508  myCurrentEdge = nullptr;
509  myLastParameterised.pop_back();
510  }
511  break;
512  case SUMO_TAG_LANE:
513  if (myCurrentEdge != nullptr && myCurrentLane != nullptr) {
515  myCurrentEdge->lanes.push_back(myCurrentLane);
516  myLastParameterised.pop_back();
517  }
518  myCurrentLane = nullptr;
519  break;
520  case SUMO_TAG_TLLOGIC:
521  if (!myCurrentTL) {
522  WRITE_ERROR("Unmatched closing tag for tl-logic.");
523  } else {
524  if (!myTLLCont.insert(myCurrentTL)) {
525  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
526  delete myCurrentTL;
527  }
528  myCurrentTL = nullptr;
529  myLastParameterised.pop_back();
530  }
531  break;
532  case SUMO_TAG_JUNCTION:
533  if (myCurrentJunction.node != nullptr) {
534  myLastParameterised.pop_back();
535  }
536  break;
537  case SUMO_TAG_CONNECTION:
538  // !!! this just avoids a crash but is not a real check that it was a connection
539  if (!myLastParameterised.empty()) {
540  myLastParameterised.pop_back();
541  }
542  break;
543  default:
544  break;
545  }
546 }
547 
548 
549 void
551  // get the id, report an error if not given or empty...
552  bool ok = true;
553  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
554  if (!ok) {
555  return;
556  }
557  myCurrentEdge = new EdgeAttrs();
559  myCurrentEdge->builtEdge = nullptr;
560  myCurrentEdge->id = id;
561  // get the function
562  myCurrentEdge->func = attrs.getEdgeFunc(ok);
564  // add the crossing but don't do anything else
565  Crossing c(id);
566  c.crossingEdges = attrs.get<std::vector<std::string> >(SUMO_ATTR_CROSSING_EDGES, nullptr, ok);
568  return;
570  myHaveSeenInternalEdge = true;
571  return; // skip internal edges
572  }
573  // get the type
574  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
575  // get the origin and the destination node
576  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
577  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
578  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
579  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
583  myCurrentEdge->maxSpeed = 0;
584  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
585  myCurrentEdge->distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
586  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
587  OptionsCont::getOptions().set("output.street-names", "true");
588  }
589 
590  std::string lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, myDefaultSpreadType);
591  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
593  } else {
594  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
595  }
596 }
597 
598 
599 void
601  bool ok = true;
602  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
603  if (!ok) {
604  return;
605  }
606  if (!myCurrentEdge) {
607  WRITE_ERROR("Found lane '" + id + "' not within edge element.");
608  return;
609  }
610  const std::string expectedID = myCurrentEdge->id + "_" + toString(myCurrentEdge->lanes.size());
611  if (id != expectedID) {
612  WRITE_WARNING("Renaming lane '" + id + "' to '" + expectedID + "'.");
613  }
614  myCurrentLane = new LaneAttrs();
616  myCurrentLane->customShape = attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false);
617  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
618  myCurrentLane->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
620  // save the width and the lane id of the crossing but don't do anything else
622  assert(crossings.size() > 0);
623  crossings.back().width = attrs.get<double>(SUMO_ATTR_WIDTH, id.c_str(), ok);
624  if (myCurrentLane->customShape) {
625  crossings.back().customShape = myCurrentLane->shape;
626  NBNetBuilder::transformCoordinates(crossings.back().customShape, true, myLocation);
627  }
629  // save custom shape if needed but don't do anything else
630  if (myCurrentLane->customShape) {
632  wacs.shape = myCurrentLane->shape;
635  }
636  return;
638  return; // skip internal edges
639  }
640  if (attrs.hasAttribute("maxspeed")) {
641  // !!! deprecated
642  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
643  } else {
644  myCurrentLane->maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
645  }
646  try {
647  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
648  } catch (EmptyData&) {
649  // !!! deprecated
650  myCurrentLane->allow = "";
651  }
652  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
653  myCurrentLane->width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_WIDTH);
654  myCurrentLane->endOffset = attrs.getOpt<double>(SUMO_ATTR_ENDOFFSET, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_OFFSET);
655  myCurrentLane->accelRamp = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
656  // lane coordinates are derived (via lane spread) do not include them in convex boundary
658 }
659 
660 
661 void
663  std::map<SVCPermissions, double> offsets = parseStopOffsets(attrs, ok);
664  if (!ok) {
665  return;
666  }
667  assert(offsets.size() == 1);
668  // Admissibility of value will be checked in _loadNetwork(), when lengths are known
669  if (myCurrentLane == nullptr) {
670  if (myCurrentEdge->stopOffsets.size() != 0) {
671  std::stringstream ss;
672  ss << "Duplicate definition of stopOffset for edge " << myCurrentEdge->id << ".\nIgnoring duplicate specification.";
673  WRITE_WARNING(ss.str());
674  return;
675  } else {
676  myCurrentEdge->stopOffsets = offsets;
677  }
678  } else {
679  if (myCurrentLane->stopOffsets.size() != 0) {
680  std::stringstream ss;
681  ss << "Duplicate definition of lane's stopOffset on edge " << myCurrentEdge->id << ".\nIgnoring duplicate specifications.";
682  WRITE_WARNING(ss.str());
683  return;
684  } else {
685  myCurrentLane->stopOffsets = offsets;
686  }
687  }
688 }
689 
690 
691 void
693  // get the id, report an error if not given or empty...
694  myCurrentJunction.node = nullptr;
695  myCurrentJunction.intLanes.clear();
696  myCurrentJunction.response.clear();
697  bool ok = true;
698  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
699  if (!ok) {
700  return;
701  }
702  if (id[0] == ':') { // internal node
703  return;
704  }
705  SumoXMLNodeType type = attrs.getNodeType(ok);
706  if (ok) {
708  // dead end is a computed status. Reset this to unknown so it will
709  // be corrected if additional connections are loaded
711  }
712  } else {
713  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
714  }
715  Position pos = readPosition(attrs, id, ok);
717  NBNode* node = new NBNode(id, pos, type);
718  myLastParameterised.push_back(node);
719  if (!myNodeCont.insert(node)) {
720  WRITE_ERROR("Problems on adding junction '" + id + "'.");
721  delete node;
722  return;
723  }
724  myCurrentJunction.node = node;
725  myCurrentJunction.intLanes = attrs.get<std::vector<std::string> >(SUMO_ATTR_INTLANES, nullptr, ok, false);
726  // set optional radius
727  if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
728  node->setRadius(attrs.get<double>(SUMO_ATTR_RADIUS, id.c_str(), ok));
729  }
730  // handle custom shape
731  if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false)) {
732  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
734  node->setCustomShape(shape);
735  }
737  // both types of nodes come without a tlLogic
738  myRailSignals.insert(id);
739  }
741  node->setRightOfWay(attrs.getRightOfWay(ok));
742  }
743  if (attrs.hasAttribute(SUMO_ATTR_FRINGE)) {
744  node->setFringeType(attrs.getFringeType(ok));
745  }
746  if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
747  node->setName(attrs.get<std::string>(SUMO_ATTR_NAME, id.c_str(), ok));
748  }
749 }
750 
751 
752 void
754  if (myCurrentJunction.node != nullptr) {
755  bool ok = true;
756  myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok));
757  }
758 }
759 
760 
761 void
763  bool ok = true;
764  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
765  if (myEdges.count(fromID) == 0) {
766  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
767  return;
768  }
769  EdgeAttrs* from = myEdges[fromID];
770  Connection conn;
771  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
772  int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
773  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
774  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
775  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, nullptr, ok, false);
776  conn.keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
777  conn.contPos = attrs.getOpt<double>(SUMO_ATTR_CONTPOS, nullptr, ok, NBEdge::UNSPECIFIED_CONTPOS);
779  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "", false);
780  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "", false);
781  if (allow == "" && disallow == "") {
783  } else {
784  conn.permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
785  }
786  conn.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, NBEdge::UNSPECIFIED_SPEED);
787  conn.customLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, nullptr, ok, NBEdge::UNSPECIFIED_LOADED_LENGTH);
791  if (conn.tlID != "") {
792  conn.tlLinkIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
793  conn.tlLinkIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX2, nullptr, ok, -1);
794  } else {
796  }
797  if ((int)from->lanes.size() <= fromLaneIdx) {
798  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
799  return;
800  }
801  from->lanes[fromLaneIdx]->connections.push_back(conn);
802  myLastParameterised.push_back(&from->lanes[fromLaneIdx]->connections.back());
803 
804  // determine crossing priority and tlIndex
805  if (myPedestrianCrossings.size() > 0) {
807  // connection from walkingArea to crossing
808  std::vector<Crossing>& crossings = myPedestrianCrossings[SUMOXMLDefinitions::getJunctionIDFromInternalEdge(fromID)];
809  for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
810  if (conn.toEdgeID == (*it).edgeID) {
811  if (conn.tlID != "") {
812  (*it).priority = true;
813  (*it).customTLIndex = conn.tlLinkIndex;
814  } else {
815  LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
816  (*it).priority = state == LINKSTATE_MAJOR;
817  }
818  }
819  }
820  } else if (from->func == SumoXMLEdgeFunc::CROSSING && myEdges[conn.toEdgeID]->func == SumoXMLEdgeFunc::WALKINGAREA) {
821  // connection from crossing to walkingArea (set optional linkIndex2)
823  if (fromID == c.edgeID) {
824  c.customTLIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok, -1);
825  }
826  }
827  }
828  }
829  // determine walking area reference edges
830  if (myWACustomShapes.size() > 0) {
831  EdgeAttrs* to = myEdges[conn.toEdgeID];
832  if (from->func == SumoXMLEdgeFunc::WALKINGAREA) {
833  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(fromID);
834  if (it != myWACustomShapes.end()) {
835  if (to->func == SumoXMLEdgeFunc::NORMAL) {
836  // add target sidewalk as reference
837  it->second.toEdges.push_back(conn.toEdgeID);
838  } else if (to->func == SumoXMLEdgeFunc::CROSSING) {
839  // add target crossing edges as reference
841  if (conn.toEdgeID == crossing.edgeID) {
842  it->second.toCrossed.insert(it->second.toCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
843  }
844  }
845  }
846  }
847  } else if (to->func == SumoXMLEdgeFunc::WALKINGAREA) {
848  std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(conn.toEdgeID);
849  if (it != myWACustomShapes.end()) {
850  if (from->func == SumoXMLEdgeFunc::NORMAL) {
851  // add origin sidewalk as reference
852  it->second.fromEdges.push_back(fromID);
853  } else if (from->func == SumoXMLEdgeFunc::CROSSING) {
854  // add origin crossing edges as reference
856  if (fromID == crossing.edgeID) {
857  it->second.fromCrossed.insert(it->second.fromCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
858  }
859  }
860  }
861  }
862  }
863  }
864 }
865 
866 
867 void
869  bool ok = true;
870  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, nullptr, ok, "");
871  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, nullptr, ok, "");
872  if (!ok) {
873  return;
874  }
875  Prohibition p;
878  if (!ok) {
879  return;
880  }
881  myProhibitions.push_back(p);
882 }
883 
884 
886 NIImporter_SUMO::getLaneAttrsFromID(EdgeAttrs* edge, std::string lane_id) {
887  std::string edge_id;
888  int index;
889  NBHelpers::interpretLaneID(lane_id, edge_id, index);
890  assert(edge->id == edge_id);
891  if ((int)edge->lanes.size() <= index) {
892  WRITE_ERROR("Unknown lane '" + lane_id + "' given in succedge.");
893  return nullptr;
894  } else {
895  return edge->lanes[index];
896  }
897 }
898 
899 
902  if (currentTL) {
903  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
904  return nullptr;
905  }
906  bool ok = true;
907  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
908  SUMOTime offset = TIME2STEPS(attrs.get<double>(SUMO_ATTR_OFFSET, id.c_str(), ok));
909  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
910  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, nullptr, ok);
911  TrafficLightType type;
912  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
914  } else {
915  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
916  return nullptr;
917  }
918  if (ok) {
919  return new NBLoadedSUMOTLDef(id, programID, offset, type);
920  } else {
921  return nullptr;
922  }
923 }
924 
925 
926 void
928  if (!currentTL) {
929  WRITE_ERROR("found phase without tl-logic");
930  return;
931  }
932  const std::string& id = currentTL->getID();
933  bool ok = true;
934  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
935  SUMOTime duration = TIME2STEPS(attrs.get<double>(SUMO_ATTR_DURATION, id.c_str(), ok));
936  if (duration < 0) {
937  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
938  return;
939  }
940  // if the traffic light is an actuated traffic light, try to get
941  // the minimum and maximum durations
944  std::vector<int> nextPhases = attrs.getOptIntVector(SUMO_ATTR_NEXT, nullptr, ok);
945  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, nullptr, ok, "");
946  if (ok) {
947  currentTL->addPhase(duration, state, minDuration, maxDuration, nextPhases, name);
948  }
949 }
950 
951 
954  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
955  bool ok = true;
956  GeoConvHelper* result = nullptr;
957  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
958  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
959  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
960  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
961  if (ok) {
962  Position networkOffset = s[0];
963  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
964  GeoConvHelper::setLoaded(*result);
965  }
966  return result;
967 }
968 
969 
970 Position
971 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
972  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
973  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
974  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
975  return Position(x, y, z);
976 }
977 
978 
979 void
980 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
981  // split from/to
982  const std::string::size_type div = attr.find("->");
983  if (div == std::string::npos) {
984  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
985  ok = false;
986  }
987  from = attr.substr(0, div);
988  to = attr.substr(div + 2);
989  // check whether the definition includes a lane information and discard it
990  if (from.find('_') != std::string::npos) {
991  from = from.substr(0, from.find('_'));
992  }
993  if (to.find('_') != std::string::npos) {
994  to = to.substr(0, to.find('_'));
995  }
996  // check whether the edges are known
997  if (myEdges.count(from) == 0) {
998  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
999  ok = false;
1000  }
1001  if (myEdges.count(to) == 0) {
1002  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
1003  ok = false;
1004  }
1005 }
1006 
1007 
1008 void
1010  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
1011  myRoundabouts.push_back(attrs.getStringVector(SUMO_ATTR_EDGES));
1012  } else {
1013  WRITE_ERROR("Empty edges in roundabout.");
1014  }
1015 }
1016 
1017 
1018 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:277
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:280
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:279
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:49
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
@ KEEPCLEAR_FALSE
Definition: NBCont.h:58
@ KEEPCLEAR_TRUE
Definition: NBCont.h:59
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
std::set< std::string > deprecatedVehicleClassesSeen
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
std::map< SVCPermissions, double > parseStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
Extract stopOffsets from attributes of stopOffset element.
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_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_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_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ACCELERATION
@ 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_STATE
The state of a link.
@ SUMO_ATTR_WALKINGAREAS
T MAX2(T a, T b)
Definition: StdDefs.h:79
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
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:48
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:409
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 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:3627
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3597
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:605
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:1180
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
Definition: NBEdge.h:351
void setDistance(double distance)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.h:1318
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
Definition: NBEdge.cpp:2240
const std::string & getID() const
Definition: NBEdge.h:1423
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:677
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:516
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:339
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3491
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:3612
bool setStopOffsets(int lane, std::map< int, double > offsets, bool overwrite=false)
set lane and vehicle class specific stopOffset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3568
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:333
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:336
const std::map< int, double > & getStopOffsets() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.h:641
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2207
std::string getLaneID(int lane) const
get lane ID
Definition: NBEdge.cpp:3345
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:330
@ VALIDATED
The connection was computed and validated.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2229
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:3619
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:324
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:1195
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:1340
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:630
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3552
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:327
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=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
Definition: NBEdge.cpp:1019
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1326
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:3670
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, int &index)
parses edge-id and index from lane-id
Definition: NBHelpers.cpp:119
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
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:271
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:538
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:2291
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3424
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:3244
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1681
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:528
void setName(const std::string &name)
set intersection name
Definition: NBNode.h:548
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape)
add custom shape for walkingArea
Definition: NBNode.cpp:3183
const Position & getPosition() const
Definition: NBNode.h:246
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition: NBNode.h:543
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 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.
double visibility
custom foe visibility for connection
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
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.
std::map< SVCPermissions, double > stopOffsets
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.
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.
PositionVector shape
This lane's shape (may be custom)
double width
The width of this lane.
std::string disallow
This lane's disallowed vehicle classes.
std::map< SVCPermissions, double > stopOffsets
This lane's vehicle specific stop offsets.
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;.
std::string myDefaultSpreadType
default spreadType defined in the 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
LaneAttrs * getLaneAttrsFromID(EdgeAttrs *edge, std::string lane_id)
Parses lane index from lane ID an retrieve lane from EdgeAttrs.
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:73
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:36
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
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:148
std::string type
the type of this lane
Definition: NBEdge.h:182
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:169
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.