SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIImporter_SUMO.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Importer for networks stored in SUMO format
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 #include <string>
38 #include <utils/common/ToString.h>
42 #include <utils/xml/XMLSubSys.h>
46 #include <netbuild/NBEdge.h>
47 #include <netbuild/NBEdgeCont.h>
48 #include <netbuild/NBNode.h>
49 #include <netbuild/NBNodeCont.h>
51 #include <netbuild/NBNetBuilder.h>
52 #include "NILoader.h"
53 #include "NIXMLEdgesHandler.h"
54 #include "NIImporter_SUMO.h"
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 
61 // ===========================================================================
62 // method definitions
63 // ===========================================================================
64 // ---------------------------------------------------------------------------
65 // static methods (interface in this case)
66 // ---------------------------------------------------------------------------
67 void
69  NIImporter_SUMO importer(nb);
70  importer._loadNetwork(oc);
71 }
72 
73 
74 // ---------------------------------------------------------------------------
75 // loader methods
76 // ---------------------------------------------------------------------------
78  : SUMOSAXHandler("sumo-network"),
79  myNetBuilder(nb),
80  myNodeCont(nb.getNodeCont()),
81  myTLLCont(nb.getTLLogicCont()),
82  myCurrentEdge(0),
83  myCurrentLane(0),
84  myCurrentTL(0),
85  myLocation(0),
86  myHaveSeenInternalEdge(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 void
104  // check whether the option is set (properly)
105  if (!oc.isUsableFileList("sumo-net-file")) {
106  return;
107  }
108  // parse file(s)
109  std::vector<std::string> files = oc.getStringVector("sumo-net-file");
110  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
111  if (!FileHelpers::isReadable(*file)) {
112  WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
113  return;
114  }
115  setFileName(*file);
116  PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'");
117  XMLSubSys::runParser(*this, *file, true);
119  }
120  // build edges
121  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
122  EdgeAttrs* ed = (*i).second;
123  // skip internal edges
124  if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) {
125  continue;
126  }
127  // get and check the nodes
128  NBNode* from = myNodeCont.retrieve(ed->fromNode);
129  NBNode* to = myNodeCont.retrieve(ed->toNode);
130  if (from == 0) {
131  WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
132  continue;
133  }
134  if (to == 0) {
135  WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
136  continue;
137  }
138  // edge shape
139  PositionVector geom;
140  if (ed->shape.size() > 0) {
141  geom = ed->shape;
142  } else {
143  // either the edge has default shape consisting only of the two node
144  // positions or we have a legacy network
145  geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition());
146  }
147  // build and insert the edge
148  NBEdge* e = new NBEdge(ed->id, from, to,
149  ed->type, ed->maxSpeed,
150  (unsigned int) ed->lanes.size(),
152  geom, ed->streetName, ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape
153  e->setLoadedLength(ed->length);
154  if (!myNetBuilder.getEdgeCont().insert(e)) {
155  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
156  delete e;
157  continue;
158  }
160  }
161  // assign further lane attributes (edges are built)
162  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
163  EdgeAttrs* ed = (*i).second;
164  NBEdge* nbe = ed->builtEdge;
165  if (nbe == 0) { // inner edge or removed by explicit list, vclass, ...
166  continue;
167  }
168  for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) {
169  LaneAttrs* lane = ed->lanes[fromLaneIndex];
170  // connections
171  const std::vector<Connection>& connections = lane->connections;
172  for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) {
173  const Connection& c = *c_it;
174  if (myEdges.count(c.toEdgeID) == 0) {
175  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
176  continue;
177  }
178  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
179  if (toEdge == 0) { // removed by explicit list, vclass, ...
180  continue;
181  }
182  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
183  WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'.");
184  }
186  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED,
187  true, c.mayDefinitelyPass);
188 
189  // maybe we have a tls-controlled connection
190  if (c.tlID != "") {
191  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
192  if (programs.size() > 0) {
193  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
194  for (it = programs.begin(); it != programs.end(); it++) {
195  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
196  if (tlDef) {
197  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo);
198  } else {
199  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
200  }
201  }
202  } else {
203  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
204  }
205  }
206  }
207  // allow/disallow XXX preferred
208  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex);
209  // width, offset
210  nbe->setLaneWidth(fromLaneIndex, lane->width);
211  nbe->setEndOffset(fromLaneIndex, lane->endOffset);
212  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
213  }
215  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
216  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
217  }
219  nbe->setEndOffset(-1, nbe->getEndOffset(0));
220  }
221  }
222  // insert loaded prohibitions
223  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
224  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
225  if (prohibitedFrom == 0) {
226  WRITE_ERROR("Edge '" + it->prohibitedFrom + "' in prohibition was not built");
227  } else {
228  NBNode* n = prohibitedFrom->getToNode();
230  NBConnection(myEdges[it->prohibitorFrom]->builtEdge, myEdges[it->prohibitorTo]->builtEdge),
231  NBConnection(prohibitedFrom, myEdges[it->prohibitedTo]->builtEdge));
232  }
233  }
234  if (!myHaveSeenInternalEdge && oc.isDefault("no-internal-links")) {
235  oc.set("no-internal-links", "true");
236  }
237  if (!deprecatedVehicleClassesSeen.empty()) {
238  WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
240  }
241  // add loaded crossings
242  for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
243  NBNode* node = myNodeCont.retrieve((*it).first);
244  for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
245  const Crossing& crossing = (*it_c);
246  EdgeVector edges;
247  for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
248  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
249  assert(edge != 0);
250  edges.push_back(edge);
251  }
252  node->addCrossing(edges, crossing.width, crossing.priority);
253  }
254  }
255  // add roundabouts
256  for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
257  EdgeSet roundabout;
258  for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
259  NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
260  if (edge == 0) {
261  if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
262  WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
263  }
264  } else {
265  roundabout.insert(edge);
266  }
267  }
268  myNetBuilder.getEdgeCont().addRoundabout(roundabout);
269  }
270 }
271 
272 
273 
274 void
276  const SUMOSAXAttributes& attrs) {
277  /* our goal is to reproduce the input net faithfully
278  * there are different types of objects in the netfile:
279  * 1) those which must be loaded into NBNetBuilder-Containers for processing
280  * 2) those which can be ignored because they are recomputed based on group 1
281  * 3) those which are of no concern to NBNetBuilder but should be exposed to
282  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
283  * and hand them over to NETEDIT
284  * alternative idea: those shouldn't really be contained within the
285  * network but rather in separate files. teach NETEDIT how to open those
286  * (POI?)
287  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
288  * must be copied over - need to patch NBNetBuilder for this.
289  * copy unknown by default
290  */
291  switch (element) {
292  case SUMO_TAG_EDGE:
293  addEdge(attrs);
294  break;
295  case SUMO_TAG_LANE:
296  addLane(attrs);
297  break;
298  case SUMO_TAG_JUNCTION:
299  addJunction(attrs);
300  break;
301  case SUMO_TAG_REQUEST:
302  addRequest(attrs);
303  break;
304  case SUMO_TAG_CONNECTION:
305  addConnection(attrs);
306  break;
307  case SUMO_TAG_TLLOGIC:
309  break;
310  case SUMO_TAG_PHASE:
311  addPhase(attrs, myCurrentTL);
312  break;
313  case SUMO_TAG_LOCATION:
314  myLocation = loadLocation(attrs);
315  break;
317  addProhibition(attrs);
318  break;
319  case SUMO_TAG_ROUNDABOUT:
320  addRoundabout(attrs);
321  break;
322  default:
323  break;
324  }
325 }
326 
327 
328 void
330  switch (element) {
331  case SUMO_TAG_EDGE:
332  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
333  WRITE_ERROR("Edge '" + myCurrentEdge->id + "' occured at least twice in the input.");
334  } else {
336  }
337  myCurrentEdge = 0;
338  break;
339  case SUMO_TAG_LANE:
340  if (myCurrentEdge != 0) {
342  myCurrentEdge->lanes.push_back(myCurrentLane);
343  }
344  myCurrentLane = 0;
345  break;
346  case SUMO_TAG_TLLOGIC:
347  if (!myCurrentTL) {
348  WRITE_ERROR("Unmatched closing tag for tl-logic.");
349  } else {
350  if (!myTLLCont.insert(myCurrentTL)) {
351  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
352  delete myCurrentTL;
353  }
354  myCurrentTL = 0;
355  }
356  break;
357  case SUMO_TAG_JUNCTION:
358  // in a network without internal lanes, we do not need to check for crossings
359  if (myCurrentJunction.node != 0 && myCurrentJunction.intLanes.size() > 0) {
360  assert(myCurrentJunction.intLanes.size() == myCurrentJunction.response.size());
361  std::vector<Crossing>& crossings = myPedestrianCrossings[myCurrentJunction.node->getID()];
362  for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
363  for (int i = 0; i < (int)myCurrentJunction.intLanes.size(); ++i) {
364  if (myCurrentJunction.intLanes[i] == (*it).laneID) {
365  (*it).priority = myCurrentJunction.response[i].find("1") == std::string::npos;
366  }
367  }
368  }
369  }
370  default:
371  break;
372  }
373 }
374 
375 
376 void
378  // get the id, report an error if not given or empty...
379  bool ok = true;
380  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
381  if (!ok) {
382  return;
383  }
384  myCurrentEdge = new EdgeAttrs();
386  myCurrentEdge->id = id;
387  // get the function
388  myCurrentEdge->func = attrs.getEdgeFunc(ok);
390  // add the crossing crossing but don't do anything else
391  Crossing c;
394  return;
396  return; // skip internal edges
397  }
398  // get the type
399  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
400  // get the origin and the destination node
401  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
402  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
403  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
404  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
408  myCurrentEdge->maxSpeed = 0;
409  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
410  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
411  OptionsCont::getOptions().set("output.street-names", "true");
412  }
413 
414  std::string lsfS = toString(LANESPREAD_RIGHT);
415  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, lsfS);
416  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
418  } else {
419  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
420  }
421 }
422 
423 
424 void
426  bool ok = true;
427  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
428  if (!ok) {
429  return;
430  }
431  if (!myCurrentEdge) {
432  WRITE_ERROR("Found lane '" + id + "' not within edge element");
433  return;
434  }
435  myCurrentLane = new LaneAttrs;
437  // save the width and the lane id of the crossing but don't do anything else
439  assert(crossings.size() > 0);
440  crossings.back().laneID = id;
441  crossings.back().width = attrs.get<SUMOReal>(SUMO_ATTR_WIDTH, id.c_str(), ok);
442  return;
444  myHaveSeenInternalEdge = true;
445  return; // skip internal lanes
446  }
447  if (attrs.hasAttribute("maxspeed")) {
448  // !!! deprecated
449  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
450  } else {
451  myCurrentLane->maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_SPEED, id.c_str(), ok);
452  }
453  try {
454  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
455  } catch (EmptyData e) {
456  // !!! deprecated
457  myCurrentLane->allow = "";
458  }
459  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
462  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
463  // lane coordinates are derived (via lane spread) do not include them in convex boundary
465 }
466 
467 
468 void
470  // get the id, report an error if not given or empty...
472  bool ok = true;
473  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
474  if (!ok) {
475  return;
476  }
477  if (id[0] == ':') { // internal node
478  return;
479  }
480  SumoXMLNodeType type = attrs.getNodeType(ok);
481  if (ok) {
482  if (type == NODETYPE_DEAD_END_DEPRECATED || type == NODETYPE_DEAD_END) {
483  // dead end is a computed status. Reset this to unknown so it will
484  // be corrected if additional connections are loaded
485  type = NODETYPE_UNKNOWN;
486  }
487  } else {
488  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
489  }
490  Position pos = readPosition(attrs, id, ok);
492  NBNode* node = new NBNode(id, pos, type);
493  if (!myNodeCont.insert(node)) {
494  WRITE_ERROR("Problems on adding junction '" + id + "'.");
495  delete node;
496  return;
497  }
498  myCurrentJunction.node = node;
500 }
501 
502 
503 void
505  if (myCurrentJunction.node != 0) {
506  bool ok = true;
507  myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, 0, ok));
508  }
509 }
510 
511 
512 void
514  bool ok = true;
515  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
516  if (myEdges.count(fromID) == 0) {
517  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
518  return;
519  }
520  EdgeAttrs* from = myEdges[fromID];
521  Connection conn;
522  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
523  unsigned int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
524  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
525  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
526  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, 0, ok, false);
527  if (conn.tlID != "") {
528  conn.tlLinkNo = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
529  }
530  if (from->lanes.size() <= (size_t) fromLaneIdx) {
531  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
532  return;
533  }
534  from->lanes[fromLaneIdx]->connections.push_back(conn);
535 }
536 
537 
538 void
540  bool ok = true;
541  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, 0, ok, "");
542  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, 0, ok, "");
543  if (!ok) {
544  return;
545  }
546  Prohibition p;
549  if (!ok) {
550  return;
551  }
552  myProhibitions.push_back(p);
553 }
554 
555 
557 NIImporter_SUMO::getLaneAttrsFromID(EdgeAttrs* edge, std::string lane_id) {
558  std::string edge_id;
559  unsigned int index;
560  interpretLaneID(lane_id, edge_id, index);
561  assert(edge->id == edge_id);
562  if (edge->lanes.size() <= (size_t) index) {
563  WRITE_ERROR("Unknown lane '" + lane_id + "' given in succedge.");
564  return 0;
565  } else {
566  return edge->lanes[index];
567  }
568 }
569 
570 
571 void
572 NIImporter_SUMO::interpretLaneID(const std::string& lane_id, std::string& edge_id, unsigned int& index) {
573  // assume lane_id = edge_id + '_' + index
574  size_t sep_index = lane_id.rfind('_');
575  if (sep_index == std::string::npos) {
576  WRITE_ERROR("Invalid lane id '" + lane_id + "' (missing '_').");
577  }
578  edge_id = lane_id.substr(0, sep_index);
579  std::string index_string = lane_id.substr(sep_index + 1);
580  try {
581  index = (unsigned int)TplConvert::_2int(index_string.c_str());
582  } catch (NumberFormatException) {
583  WRITE_ERROR("Invalid lane index '" + index_string + "' for lane '" + lane_id + "'.");
584  }
585 }
586 
587 
590  if (currentTL) {
591  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
592  return 0;
593  }
594  bool ok = true;
595  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
596  SUMOTime offset = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_OFFSET, id.c_str(), ok));
597  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
598  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
599  TrafficLightType type;
600  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
602  } else {
603  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
604  return 0;
605  }
606  if (ok) {
607  return new NBLoadedSUMOTLDef(id, programID, offset, type);
608  } else {
609  return 0;
610  }
611 }
612 
613 
614 void
616  if (!currentTL) {
617  WRITE_ERROR("found phase without tl-logic");
618  return;
619  }
620  const std::string& id = currentTL->getID();
621  bool ok = true;
622  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
623  SUMOTime duration = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_DURATION, id.c_str(), ok));
624  if (duration < 0) {
625  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
626  return;
627  }
628  // if the traffic light is an actuated traffic light, try to get
629  // the minimum and maximum durations
630  //SUMOTime minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, -1);
631  //SUMOTime maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, -1);
632  if (ok) {
633  currentTL->addPhase(duration, state);
634  }
635 }
636 
637 
639 NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) {
640  const PositionVector& firstLane = edge->lanes[0]->shape;
641  PositionVector result;
642  result.push_back(from);
643 
644  // reverse logic of NBEdge::computeLaneShape
645  // !!! this will only work for old-style constant width lanes
646  const size_t noLanes = edge->lanes.size();
647  SUMOReal offset;
648  if (edge->lsf == LANESPREAD_RIGHT) {
649  offset = (SUMO_const_laneWidth + SUMO_const_laneOffset) / 2.; // @todo: why is the lane offset counted in here?
650  } else {
651  offset = (SUMO_const_laneWidth) / 2. - (SUMO_const_laneWidth * (SUMOReal)noLanes - 1) / 2.;
652  }
653  for (unsigned int i = 1; i < firstLane.size() - 1; i++) {
654  Position from = firstLane[i - 1];
655  Position me = firstLane[i];
656  Position to = firstLane[i + 1];
657  std::pair<SUMOReal, SUMOReal> offsets = NBEdge::laneOffset(from, me, offset, false);
658  std::pair<SUMOReal, SUMOReal> offsets2 = NBEdge::laneOffset(me, to, offset, false);
659 
660  Line l1(
661  Position(from.x() + offsets.first, from.y() + offsets.second),
662  Position(me.x() + offsets.first, me.y() + offsets.second));
663  l1.extrapolateBy(100);
664  Line l2(
665  Position(me.x() + offsets2.first, me.y() + offsets2.second),
666  Position(to.x() + offsets2.first, to.y() + offsets2.second));
667  l2.extrapolateBy(100);
668  if (l1.intersects(l2)) {
669  result.push_back(l1.intersectsAt(l2));
670  } else {
671  WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'.");
672  }
673  }
674 
675  result.push_back(to);
676  return result;
677 }
678 
679 
682  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
683  bool ok = true;
684  GeoConvHelper* result = 0;
686  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, 0, ok);
687  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, 0, ok);
688  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, 0, ok);
689  if (ok) {
690  Position networkOffset = s[0];
691  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
692  GeoConvHelper::setLoaded(*result);
693  }
694  return result;
695 }
696 
697 
698 Position
699 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
700  SUMOReal x = attrs.get<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok);
701  SUMOReal y = attrs.get<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok);
702  SUMOReal z = 0;
703  if (attrs.hasAttribute(SUMO_ATTR_Z)) {
704  z = attrs.get<SUMOReal>(SUMO_ATTR_Z, id.c_str(), ok);
705  }
706  return Position(x, y, z);
707 }
708 
709 
710 void
711 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
712  // split from/to
713  size_t div = attr.find("->");
714  if (div == std::string::npos) {
715  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
716  ok = false;
717  }
718  from = attr.substr(0, div);
719  to = attr.substr(div + 2);
720  // check whether the definition includes a lane information and discard it
721  if (from.find('_') != std::string::npos) {
722  from = from.substr(0, from.find('_'));
723  }
724  if (to.find('_') != std::string::npos) {
725  to = to.substr(0, to.find('_'));
726  }
727  // check whether the edges are known
728  if (myEdges.count(from) == 0) {
729  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
730  ok = false;
731  }
732  if (myEdges.count(to) == 0) {
733  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
734  ok = false;
735  }
736 }
737 
738 
739 void
741  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
743  } else {
744  WRITE_ERROR("Empty edges in roundabout.");
745  }
746 }
747 
748 
749 /****************************************************************************/
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.
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:738
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) ...
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
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
std::set< std::string > deprecatedVehicleClassesSeen
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:46
static bool transformCoordinates(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:58
NBNodeCont & myNodeCont
The node container to fill.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in &quot;myCurrentEdge&quot;.
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
SUMOReal maxSpeed
The maximum velocity allowed on this lane.
A loaded (complete) traffic light logic.
std::vector< LaneAttrs * > lanes
This edge&#39;s lanes.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1392
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2066
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2112
Describes a pedestrian crossing.
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:503
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea ...
const std::string & getProgramID() const
Returns the ProgramID.
The representation of a single edge during network building.
Definition: NBEdge.h:71
void declareConnectionsAsLoaded()
Definition: NBEdge.h:1033
A connection description.
std::vector< std::string > response
void addCrossing(EdgeVector edges, SUMOReal width, bool priority)
add a pedestrian crossing to this node
Definition: NBNode.cpp:2013
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
static std::pair< SUMOReal, SUMOReal > laneOffset(const Position &from, const Position &to, SUMOReal laneCenterOffset, bool leftHand)
Computes the offset from the edge shape on the current segment.
Definition: NBEdge.cpp:1293
bool addLane2LaneConnection(unsigned int fromLane, NBEdge *dest, unsigned int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:628
T MAX2(T a, T b)
Definition: StdDefs.h:74
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:446
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:2128
static NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
begins the reading of a traffic lights logic
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
const SUMOReal SUMO_const_laneOffset
Definition: StdDefs.h:49
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
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:114
NIImporter_SUMO(NBNetBuilder &nb)
Constructor.
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
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:48
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
Describes the values found in a lane&#39;s definition.
The connection was computed and validated.
Definition: NBEdge.h:116
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:67
std::string toEdgeID
The id of the target edge.
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
The state of a link.
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and stores the values in &quot;myCurrentLane&quot;.
NBNetBuilder & myNetBuilder
The network builder to fill.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
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 &quot;myCurrentLane&quot;.
static void parseStringVector(const std::string &def, std::vector< std::string > &into)
Splits the given string.
std::string toNode
The node this edge ends at.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:232
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.
std::set< NBEdge * > EdgeSet
Definition: NBCont.h:51
JunctionAttrs myCurrentJunction
The currently parsed junction definition to help in reconstructing crossings.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:59
the edges of a route
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:158
std::string getLaneID(unsigned int lane) const
Definition: NBEdge.cpp:1958
std::vector< std::string > crossingEdges
std::string allow
This lane&#39;s allowed vehicle classes.
Encapsulated SAX-Attributes.
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
static StringBijection< TrafficLightType > TrafficLightTypes
Describes the values found in a prohibition.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
Importer for networks stored in SUMO format.
std::string tlID
The id of the traffic light that controls this connection.
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
EdgeAttrs * myCurrentEdge
The currently parsed edge&#39;s definition (to add loaded lanes to)
A list of positions.
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
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 parseProhibitionConnection(const std::string &attr, std::string &from, std::string &to, bool &ok)
parses connection string of a prohibition (very old school)
LaneSpreadFunction lsf
The lane spread function.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
Definition: Line.h:51
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:202
std::string disallow
This lane&#39;s disallowed vehicle classes.
unsigned int tlLinkNo
The index of this connection within the controlling traffic light.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2171
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.
void _loadNetwork(OptionsCont &oc)
load the network
SUMOReal width
The width of this lane.
SUMOReal getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:471
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, unsigned int &index)
parses edge-id and index from lane-id
bool intersects(const Line &l) const
Definition: Line.cpp:171
std::vector< std::string > intLanes
SUMOReal 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.
SUMOReal maxSpeed
The maximum velocity allowed on this edge (!!!)
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
void extrapolateBy(SUMOReal length)
Definition: Line.cpp:60
void push_back(const PositionVector &p)
Appends all positions from the given vector.
static int _2int(const E *const data)
Definition: TplConvert.h:114
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:368
std::vector< Connection > connections
This lane&#39;s connections.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
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.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:245
static const SUMOReal UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:207
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
unsigned int toLaneIdx
The index of the target lane.
void addPhase(SUMOTime duration, const std::string &state)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases...
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
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:108
int priority
This edge&#39;s priority.
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.
int SUMOTime
Definition: SUMOTime.h:43
std::string fromNode
The node this edge starts at.
Represents a single node (junction) during network building.
Definition: NBNode.h:75
T get(const std::string &str) const
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)
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1370
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Definition: NBNode.cpp:988
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2096
#define SUMOReal
Definition: config.h:218
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
SUMOReal length
The length of the edge if set explicitly.
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.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:463
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:203
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
Definition: NBEdgeCont.cpp:897
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and saves it.
Position intersectsAt(const Line &l) const
Definition: Line.cpp:165
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex)
Adds a connection and immediately informs the edges.
TrafficLightType