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-2013 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);
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&#39;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&#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
bool insert(const std::string &id, const Position &position, NBDistrict *district)
Inserts a node into the map.
Definition: NBNodeCont.cpp:78
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:41
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 &quot;myCurrentEdge&quot;.
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
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:1977
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2023
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:2007
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:1248
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:613
T MAX2(T a, T b)
Definition: StdDefs.h:63
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:2039
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:44
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 bool runParser(GenericSAXHandler &handler, const std::string &file)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:96
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
SAX-handler base for SUMO-files.
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&#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
void addConnection(const SUMOSAXAttributes &attrs)
Parses a connection and saves it into the lane&#39;s definition stored in &quot;myCurrentLane&quot;.
std::string toNode
The node this edge ends at.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:165
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.
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:1869
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.
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&#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. ...
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:51
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2082
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.
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&#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 (!!!)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
T get(const std::string &str)
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&#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:251
bool hasLaneSpecificOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1325
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&#39;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&#39;s priority.
std::string id
This edge&#39;s id.
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
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&#39;s shape (needed to reconstruct edge shape for legacy networks)
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1303
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Definition: NBNode.cpp:934
#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:129
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:723
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