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