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-sim.org/
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 "NIImporter_SUMO.h"
54 
55 #ifdef CHECK_MEMORY_LEAKS
56 #include <foreign/nvwa/debug_new.h>
57 #endif // CHECK_MEMORY_LEAKS
58 
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
63 // ---------------------------------------------------------------------------
64 // static methods (interface in this case)
65 // ---------------------------------------------------------------------------
66 void
68  NIImporter_SUMO importer(nb);
69  importer._loadNetwork(oc);
70 }
71 
72 
73 // ---------------------------------------------------------------------------
74 // loader methods
75 // ---------------------------------------------------------------------------
77  : SUMOSAXHandler("sumo-network"),
78  myNetBuilder(nb),
79  myNodeCont(nb.getNodeCont()),
80  myTLLCont(nb.getTLLogicCont()),
81  myCurrentEdge(0),
82  myCurrentLane(0),
83  myCurrentTL(0),
84  myLocation(0),
85  mySuspectKeepShape(false),
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::exists(*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) {
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  mySuspectKeepShape = false; // no problem with reconstruction if edge shape is given explicit
143  } else {
144  // either the edge has default shape consisting only of the two node
145  // positions or we have a legacy network
146  geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition());
147  }
148  // build and insert the edge
149  NBEdge* e = new NBEdge(ed->id, from, to,
150  ed->type, ed->maxSpeed,
151  (unsigned int) ed->lanes.size(),
153  geom, ed->streetName, ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape
154  e->setLoadedLength(ed->length);
155  if (!myNetBuilder.getEdgeCont().insert(e)) {
156  WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
157  delete e;
158  continue;
159  }
161  }
162  // assign further lane attributes (edges are built)
163  for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
164  EdgeAttrs* ed = (*i).second;
165  NBEdge* nbe = ed->builtEdge;
166  if (nbe == 0) { // inner edge or removed by explicit list, vclass, ...
167  continue;
168  }
169  for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) {
170  LaneAttrs* lane = ed->lanes[fromLaneIndex];
171  // connections
172  const std::vector<Connection>& connections = lane->connections;
173  for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) {
174  const Connection& c = *c_it;
175  if (myEdges.count(c.toEdgeID) == 0) {
176  WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
177  continue;
178  }
179  NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
180  if (toEdge == 0) { // removed by explicit list, vclass, ...
181  continue;
182  }
183  if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) {
184  WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'.");
185  }
187  fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED,
188  true, c.mayDefinitelyPass);
189 
190  // maybe we have a tls-controlled connection
191  if (c.tlID != "") {
192  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
193  if (programs.size() > 0) {
194  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
195  for (it = programs.begin(); it != programs.end(); it++) {
196  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
197  if (tlDef) {
198  tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo);
199  } else {
200  throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
201  }
202  }
203  } else {
204  WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
205  }
206  }
207  }
208  // allow/disallow XXX preferred
209  nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex);
210  // width, offset
211  nbe->setLaneWidth(fromLaneIndex, lane->width);
212  nbe->setOffset(fromLaneIndex, lane->offset);
213  nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
214  }
216  if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
217  nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
218  }
219  if (!nbe->hasLaneSpecificOffset() && nbe->getOffset(0) != NBEdge::UNSPECIFIED_OFFSET) {
220  nbe->setOffset(-1, nbe->getOffset(0));
221  }
222  }
223  // insert loaded prohibitions
224  for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
225  NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
226  if (prohibitedFrom == 0) {
227  WRITE_ERROR("Edge '" + it->prohibitedFrom + "' in prohibition was not built");
228  } else {
229  NBNode* n = prohibitedFrom->getToNode();
231  NBConnection(myEdges[it->prohibitorFrom]->builtEdge, myEdges[it->prohibitorTo]->builtEdge),
232  NBConnection(prohibitedFrom, myEdges[it->prohibitedTo]->builtEdge));
233  }
234  }
235  if (!myHaveSeenInternalEdge && oc.isDefault("no-internal-links")) {
236  oc.set("no-internal-links", "true");
237  }
238  // final warning
239  if (mySuspectKeepShape) {
240  WRITE_WARNING("The input network may have been built using option 'xml.keep-shape'.\n... Accuracy of junction positions cannot be guaranteed.");
241  }
242 
243 }
244 
245 
246 
247 void
249  const SUMOSAXAttributes& attrs) {
250  /* our goal is to reproduce the input net faithfully
251  * there are different types of objects in the netfile:
252  * 1) those which must be loaded into NBNetBuilder-Containers for processing
253  * 2) those which can be ignored because they are recomputed based on group 1
254  * 3) those which are of no concern to NBNetBuilder but should be exposed to
255  * NETEDIT. We will probably have to patch NBNetBuilder to contain them
256  * and hand them over to NETEDIT
257  * alternative idea: those shouldn't really be contained within the
258  * network but rather in separate files. teach NETEDIT how to open those
259  * (POI?)
260  * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
261  * must be copied over - need to patch NBNetBuilder for this.
262  * copy unknown by default
263  */
264  switch (element) {
265  case SUMO_TAG_EDGE:
266  addEdge(attrs);
267  break;
268  case SUMO_TAG_LANE:
269  addLane(attrs);
270  break;
271  case SUMO_TAG_JUNCTION:
272  addJunction(attrs);
273  break;
274  case SUMO_TAG_CONNECTION:
275  addConnection(attrs);
276  break;
277  case SUMO_TAG_TLLOGIC:
279  break;
280  case SUMO_TAG_PHASE:
281  addPhase(attrs, myCurrentTL);
282  break;
283  case SUMO_TAG_LOCATION:
284  myLocation = loadLocation(attrs);
285  break;
287  addProhibition(attrs);
288  break;
289  case SUMO_TAG_ROUNDABOUT:
291  break;
292  default:
293  break;
294  }
295 }
296 
297 
298 void
300  switch (element) {
301  case SUMO_TAG_EDGE:
302  if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
303  WRITE_ERROR("Edge '" + myCurrentEdge->id + "' occured at least twice in the input.");
304  } else {
306  }
307  myCurrentEdge = 0;
308  break;
309  case SUMO_TAG_LANE:
310  if (myCurrentEdge != 0) {
312  myCurrentEdge->lanes.push_back(myCurrentLane);
313  }
314  myCurrentLane = 0;
315  break;
316  case SUMO_TAG_TLLOGIC:
317  if (!myCurrentTL) {
318  WRITE_ERROR("Unmatched closing tag for tl-logic.");
319  } else {
320  if (!myTLLCont.insert(myCurrentTL)) {
321  WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
322  delete myCurrentTL;
323  }
324  myCurrentTL = 0;
325  }
326  break;
327  default:
328  break;
329  }
330 }
331 
332 
333 void
335  // get the id, report an error if not given or empty...
336  bool ok = true;
337  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
338  if (!ok) {
339  return;
340  }
341  myCurrentEdge = new EdgeAttrs();
343  myCurrentEdge->id = id;
344  // get the function
345  myCurrentEdge->func = attrs.getEdgeFunc(ok);
347  return; // skip internal edges
348  }
349  // get the type
350  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
351  // get the origin and the destination node
352  myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
353  myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
354  myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
355  myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
359  myCurrentEdge->maxSpeed = 0;
360  myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
361  if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
362  OptionsCont::getOptions().set("output.street-names", "true");
363  }
364 
365  std::string lsfS = toString(LANESPREAD_RIGHT);
366  lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, lsfS);
367  if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
369  } else {
370  WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
371  }
372 }
373 
374 
375 void
377  bool ok = true;
378  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
379  if (!ok) {
380  return;
381  }
382  if (!myCurrentEdge) {
383  WRITE_ERROR("Found lane '" + id + "' not within edge element");
384  return;
385  }
386  myCurrentLane = new LaneAttrs;
388  myHaveSeenInternalEdge = true;
389  return; // skip internal lanes
390  }
391  if (attrs.hasAttribute("maxspeed")) {
392  // !!! deprecated
393  myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
394  } else {
395  myCurrentLane->maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_SPEED, id.c_str(), ok);
396  }
397  try {
398  myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
399  } catch (EmptyData e) {
400  // !!! deprecated
401  myCurrentLane->allow = "";
402  }
403  myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
406  myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
407  // lane coordinates are derived (via lane spread) do not include them in convex boundary
409 }
410 
411 
412 void
414  // get the id, report an error if not given or empty...
415  bool ok = true;
416  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
417  if (!ok) {
418  return;
419  }
420  if (id[0] == ':') { // internal node
421  return;
422  }
423  SumoXMLNodeType type = attrs.getNodeType(ok);
424  if (ok) {
425  if (type == NODETYPE_DEAD_END_DEPRECATED || type == NODETYPE_DEAD_END) {
426  // dead end is a computed status. Reset this to unknown so it will
427  // be corrected if additional connections are loaded
428  type = NODETYPE_UNKNOWN;
429  }
430  } else {
431  WRITE_WARNING("Unknown node type for junction '" + id + "'.");
432  }
433  Position pos = readPosition(attrs, id, ok);
435  // the network may have non-default edge geometry.
436  // accurate reconstruction of legacy networks is not possible. We ought to warn about this
437  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
438  PositionVector shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok, PositionVector());
439  if (shape.size() > 0) {
440  shape.push_back_noDoublePos(shape[0]); // need closed shape
441  if (!shape.around(pos) && shape.distance(pos) > 1) { // MAGIC_THRESHOLD
442  // WRITE_WARNING("Junction '" + id + "': distance between pos and shape is " + toString(shape.distance(pos)));
443  mySuspectKeepShape = true;
444  }
445  }
446  }
447  NBNode* node = new NBNode(id, pos, type);
448  if (!myNodeCont.insert(node)) {
449  WRITE_ERROR("Problems on adding junction '" + id + "'.");
450  delete node;
451  return;
452  }
453 }
454 
455 
456 void
458  bool ok = true;
459  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
460  if (myEdges.count(fromID) == 0) {
461  WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
462  return;
463  }
464  EdgeAttrs* from = myEdges[fromID];
465  Connection conn;
466  conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
467  unsigned int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
468  conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
469  conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
470  conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, 0, ok, false);
471  if (conn.tlID != "") {
472  conn.tlLinkNo = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
473  }
474  if (from->lanes.size() <= (size_t) fromLaneIdx) {
475  WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
476  return;
477  }
478  from->lanes[fromLaneIdx]->connections.push_back(conn);
479 }
480 
481 
482 void
484  bool ok = true;
485  std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, 0, ok, "");
486  std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, 0, ok, "");
487  if (!ok) {
488  return;
489  }
490  Prohibition p;
493  if (!ok) {
494  return;
495  }
496  myProhibitions.push_back(p);
497 }
498 
499 
501 NIImporter_SUMO::getLaneAttrsFromID(EdgeAttrs* edge, std::string lane_id) {
502  std::string edge_id;
503  unsigned int index;
504  interpretLaneID(lane_id, edge_id, index);
505  assert(edge->id == edge_id);
506  if (edge->lanes.size() <= (size_t) index) {
507  WRITE_ERROR("Unknown lane '" + lane_id + "' given in succedge.");
508  return 0;
509  } else {
510  return edge->lanes[index];
511  }
512 }
513 
514 
515 void
516 NIImporter_SUMO::interpretLaneID(const std::string& lane_id, std::string& edge_id, unsigned int& index) {
517  // assume lane_id = edge_id + '_' + index
518  size_t sep_index = lane_id.rfind('_');
519  if (sep_index == std::string::npos) {
520  WRITE_ERROR("Invalid lane id '" + lane_id + "' (missing '_').");
521  }
522  edge_id = lane_id.substr(0, sep_index);
523  std::string index_string = lane_id.substr(sep_index + 1);
524  try {
525  index = (unsigned int)TplConvert::_2int(index_string.c_str());
526  } catch (NumberFormatException) {
527  WRITE_ERROR("Invalid lane index '" + index_string + "' for lane '" + lane_id + "'.");
528  }
529 }
530 
531 
534  if (currentTL) {
535  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
536  return 0;
537  }
538  bool ok = true;
539  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
540  SUMOTime offset = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_OFFSET, id.c_str(), ok));
541  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
542  std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
543  TrafficLightType type;
544  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
546  } else {
547  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
548  return 0;
549  }
550  if (ok) {
551  return new NBLoadedSUMOTLDef(id, programID, offset, type);
552  } else {
553  return 0;
554  }
555 }
556 
557 
558 void
560  if (!currentTL) {
561  WRITE_ERROR("found phase without tl-logic");
562  return;
563  }
564  const std::string& id = currentTL->getID();
565  bool ok = true;
566  std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
567  SUMOTime duration = TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_DURATION, id.c_str(), ok));
568  if (duration < 0) {
569  WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
570  return;
571  }
572  // if the traffic light is an actuated traffic light, try to get
573  // the minimum and maximum durations
574  //SUMOTime minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, -1);
575  //SUMOTime maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, -1);
576  if (ok) {
577  currentTL->addPhase(duration, state);
578  }
579 }
580 
581 
583 NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) {
584  const PositionVector& firstLane = edge->lanes[0]->shape;
585  PositionVector result;
586  result.push_back(from);
587 
588  // reverse logic of NBEdge::computeLaneShape
589  // !!! this will only work for old-style constant width lanes
590  const size_t noLanes = edge->lanes.size();
591  SUMOReal offset;
592  if (edge->lsf == LANESPREAD_RIGHT) {
593  offset = (SUMO_const_laneWidth + SUMO_const_laneOffset) / 2.; // @todo: why is the lane offset counted in here?
594  } else {
595  offset = (SUMO_const_laneWidth) / 2. - (SUMO_const_laneWidth * (SUMOReal)noLanes - 1) / 2.;
596  }
597  for (unsigned int i = 1; i < firstLane.size() - 1; i++) {
598  Position from = firstLane[i - 1];
599  Position me = firstLane[i];
600  Position to = firstLane[i + 1];
601  std::pair<SUMOReal, SUMOReal> offsets = NBEdge::laneOffset(from, me, offset, false);
602  std::pair<SUMOReal, SUMOReal> offsets2 = NBEdge::laneOffset(me, to, offset, false);
603 
604  Line l1(
605  Position(from.x() + offsets.first, from.y() + offsets.second),
606  Position(me.x() + offsets.first, me.y() + offsets.second));
607  l1.extrapolateBy(100);
608  Line l2(
609  Position(me.x() + offsets2.first, me.y() + offsets2.second),
610  Position(to.x() + offsets2.first, to.y() + offsets2.second));
611  l2.extrapolateBy(100);
612  if (l1.intersects(l2)) {
613  result.push_back(l1.intersectsAt(l2));
614  } else {
615  WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'.");
616  }
617  }
618 
619  result.push_back(to);
620  return result;
621 }
622 
623 
626  // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
627  bool ok = true;
628  GeoConvHelper* result = 0;
630  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, 0, ok);
631  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, 0, ok);
632  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, 0, ok);
633  if (ok) {
634  Position networkOffset = s[0];
635  result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
636  GeoConvHelper::setLoaded(*result);
637  }
638  return result;
639 }
640 
641 
642 Position
643 NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
644  SUMOReal x = attrs.get<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok);
645  SUMOReal y = attrs.get<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok);
646  SUMOReal z = 0;
647  if (attrs.hasAttribute(SUMO_ATTR_Z)) {
648  z = attrs.get<SUMOReal>(SUMO_ATTR_Z, id.c_str(), ok);
649  }
650  return Position(x, y, z);
651 }
652 
653 
654 void
655 NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
656  // split from/to
657  size_t div = attr.find("->");
658  if (div == std::string::npos) {
659  WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
660  ok = false;
661  }
662  from = attr.substr(0, div);
663  to = attr.substr(div + 2);
664  // check whether the definition includes a lane information and discard it
665  if (from.find('_') != std::string::npos) {
666  from = from.substr(0, from.find('_'));
667  }
668  if (to.find('_') != std::string::npos) {
669  to = to.substr(0, to.find('_'));
670  }
671  // check whether the edges are known
672  if (myEdges.count(from) == 0) {
673  WRITE_ERROR("Unknown edge prohibition '" + from + "'");
674  ok = false;
675  }
676  if (myEdges.count(to) == 0) {
677  WRITE_ERROR("Unknown edge prohibition '" + to + "'");
678  ok = false;
679  }
680 }
681 /****************************************************************************/
std::map< std::string, EdgeAttrs * > myEdges
Loaded edge definitions.
LaneAttrs * myCurrentLane
The currently parsed lanes's definition (to add the shape to)
The information about how to spread the lanes from the given position.
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'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
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:45
void haveSeenRoundabouts()
declare that roundabouts have been seen during loading
Definition: NBNetBuilder.h:209
static bool transformCoordinates(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
NBNodeCont & myNodeCont
The node container to fill.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
SUMOReal maxSpeed
The maximum velocity allowed on this lane.
A loaded (complete) traffic light logic.
std::vector< LaneAttrs * > lanes
This edge's lanes.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2003
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2049
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:486
void setOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2033
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:1005
A connection description.
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:1253
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's lane and an approached one.
Definition: NBEdge.cpp:617
T MAX2(T a, T b)
Definition: StdDefs.h:71
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:440
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:2065
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:48
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point ...
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'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:196
Describes the values found in a lane'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 "myCurrentLane".
NBNetBuilder & myNetBuilder
The network builder to fill.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
void addConnection(const SUMOSAXAttributes &attrs)
Parses a connection and saves it into the lane's definition stored in "myCurrentLane".
std::string toNode
The node this edge ends at.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:158
Describes the values found in an edge's definition and this edge's lanes.
void setFileName(const std::string &name)
Sets the current file name.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:59
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:164
std::string getLaneID(unsigned int lane) const
Definition: NBEdge.cpp:1895
std::string allow
This lane'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'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.
SUMOReal distance(const Position &p) const
static bool exists(std::string path)
Checks whether the given file exists.
Definition: FileHelpers.cpp:57
Definition: Line.h:51
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:198
std::string disallow
This lane'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. ...
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:52
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2108
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's function.
void _loadNetwork(OptionsCont &oc)
load the network
SUMOReal width
The width of this lane.
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::string streetName
This edge'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 (!!!)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
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:362
std::vector< Connection > connections
This lane's connections.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
std::string type
This edge'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:251
bool hasLaneSpecificOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1352
static const SUMOReal UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:205
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...
SUMOReal offset
This lane's offset from the intersection.
bool mySuspectKeepShape
whether we suspect a net that was built with xml.keep-shape
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
A storage for options typed value containers)
Definition: OptionsCont.h:108
int priority
This edge's priority.
std::string id
This edge'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.
std::string fromNode
The node this edge starts at.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
T get(const std::string &str) const
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
~NIImporter_SUMO()
Destructor.
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's shape (needed to reconstruct edge shape for legacy networks)
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1330
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Definition: NBNode.cpp:928
#define SUMOReal
Definition: config.h:215
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
void push_back_noDoublePos(const Position &p)
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.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:124
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:727
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:199
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.
SUMOReal getOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:465
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex)
Adds a connection and immediately informs the edges.
TrafficLightType