SUMO - Simulation of Urban MObility
NWWriter_SUMO.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Exporter writing networks using the SUMO format
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 #include <cmath>
27 #include <algorithm>
31 #include <utils/common/ToString.h>
36 #include <netbuild/NBEdge.h>
37 #include <netbuild/NBEdgeCont.h>
38 #include <netbuild/NBNode.h>
39 #include <netbuild/NBNodeCont.h>
40 #include <netbuild/NBNetBuilder.h>
42 #include <netbuild/NBDistrict.h>
43 #include <netbuild/NBHelpers.h>
44 #include "NWFrame.h"
45 #include "NWWriter_SUMO.h"
46 
47 
48 //#define DEBUG_OPPOSITE_INTERNAL
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 // ---------------------------------------------------------------------------
54 // static methods
55 // ---------------------------------------------------------------------------
56 void
58  // check whether a sumo net-file shall be generated
59  if (!oc.isSet("output-file")) {
60  return;
61  }
62  OutputDevice& device = OutputDevice::getDevice(oc.getString("output-file"));
63  std::map<SumoXMLAttr, std::string> attrs;
65  if (oc.getBool("lefthand")) {
66  attrs[SUMO_ATTR_LEFTHAND] = "true";
67  }
68  const int cornerDetail = oc.getInt("junctions.corner-detail");
69  if (cornerDetail > 0) {
70  attrs[SUMO_ATTR_CORNERDETAIL] = toString(cornerDetail);
71  }
72  if (!oc.isDefault("junctions.internal-link-detail")) {
73  attrs[SUMO_ATTR_LINKDETAIL] = toString(oc.getInt("junctions.internal-link-detail"));
74  }
75  if (oc.getBool("rectangular-lane-cut")) {
76  attrs[SUMO_ATTR_RECTANGULAR_LANE_CUT] = "true";
77  }
78  if (oc.getBool("crossings.guess") || oc.getBool("walkingareas")) {
79  attrs[SUMO_ATTR_WALKINGAREAS] = "true";
80  }
81  if (oc.getFloat("junctions.limit-turn-speed") > 0) {
82  attrs[SUMO_ATTR_LIMIT_TURN_SPEED] = toString(oc.getFloat("junctions.limit-turn-speed"));
83  }
84  device.writeXMLHeader("net", "net_file.xsd", attrs); // street names may contain non-ascii chars
85  device.lf();
86  // get involved container
87  const NBNodeCont& nc = nb.getNodeCont();
88  const NBEdgeCont& ec = nb.getEdgeCont();
89  const NBDistrictCont& dc = nb.getDistrictCont();
90 
91  // write network offsets and projection
93 
94  // write edge types and restrictions
95  nb.getTypeCont().writeTypes(device);
96 
97  // write inner lanes
98  if (!oc.getBool("no-internal-links")) {
99  bool hadAny = false;
100  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
101  hadAny |= writeInternalEdges(device, ec, *(*i).second);
102  }
103  if (hadAny) {
104  device.lf();
105  }
106  }
107 
108  // write edges with lanes and connected edges
109  bool noNames = !oc.getBool("output.street-names");
110  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
111  writeEdge(device, *(*i).second, noNames);
112  }
113  device.lf();
114 
115  // write tls logics
116  writeTrafficLights(device, nb.getTLLogicCont());
117 
118  // write the nodes (junctions)
119  std::set<NBNode*> roundaboutNodes;
120  const bool checkLaneFoesAll = oc.getBool("check-lane-foes.all");
121  const bool checkLaneFoesRoundabout = !checkLaneFoesAll && oc.getBool("check-lane-foes.roundabout");
122  if (checkLaneFoesRoundabout) {
123  const std::set<EdgeSet>& roundabouts = ec.getRoundabouts();
124  for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
125  for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
126  roundaboutNodes.insert((*j)->getToNode());
127  }
128  }
129  }
130  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
131  const bool checkLaneFoes = checkLaneFoesAll || (checkLaneFoesRoundabout && roundaboutNodes.count((*i).second) > 0);
132  writeJunction(device, *(*i).second, checkLaneFoes);
133  }
134  device.lf();
135  const bool includeInternal = !oc.getBool("no-internal-links");
136  if (includeInternal) {
137  // ... internal nodes if not unwanted
138  bool hadAny = false;
139  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
140  hadAny |= writeInternalNodes(device, *(*i).second);
141  }
142  if (hadAny) {
143  device.lf();
144  }
145  }
146 
147  // write the successors of lanes
148  int numConnections = 0;
149  for (std::map<std::string, NBEdge*>::const_iterator it_edge = ec.begin(); it_edge != ec.end(); it_edge++) {
150  NBEdge* from = it_edge->second;
151  const std::vector<NBEdge::Connection> connections = from->getConnections();
152  numConnections += (int)connections.size();
153  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) {
154  writeConnection(device, *from, *it_c, includeInternal);
155  }
156  }
157  if (numConnections > 0) {
158  device.lf();
159  }
160  if (includeInternal) {
161  // ... internal successors if not unwanted
162  bool hadAny = false;
163  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
164  hadAny |= writeInternalConnections(device, *(*i).second);
165  }
166  if (hadAny) {
167  device.lf();
168  }
169  }
170  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
171  NBNode* node = (*i).second;
172  // write connections from pedestrian crossings
173  std::vector<NBNode::Crossing*> crossings = node->getCrossings();
174  for (auto c : crossings) {
175  NWWriter_SUMO::writeInternalConnection(device, c->id, c->nextWalkingArea, 0, 0, "", LINKDIR_STRAIGHT, c->tlID, c->tlLinkIndex2);
176  }
177  // write connections from pedestrian walking areas
178  for (const NBNode::WalkingArea& wa : node->getWalkingAreas()) {
179  for (const std::string& cID : wa.nextCrossings) {
180  const NBNode::Crossing& nextCrossing = *node->getCrossing(cID);
181  // connection to next crossing (may be tls-controlled)
183  device.writeAttr(SUMO_ATTR_FROM, wa.id);
184  device.writeAttr(SUMO_ATTR_TO, cID);
185  device.writeAttr(SUMO_ATTR_FROM_LANE, 0);
186  device.writeAttr(SUMO_ATTR_TO_LANE, 0);
187  if (nextCrossing.tlID != "") {
188  device.writeAttr(SUMO_ATTR_TLID, nextCrossing.tlID);
189  assert(nextCrossing.tlLinkIndex >= 0);
190  device.writeAttr(SUMO_ATTR_TLLINKINDEX, nextCrossing.tlLinkIndex);
191  }
194  device.closeTag();
195  }
196  // optional connections from/to sidewalk
197  std::string edgeID;
198  int laneIndex;
199  for (const std::string& sw : wa.nextSidewalks) {
200  NBHelpers::interpretLaneID(sw, edgeID, laneIndex);
201  NWWriter_SUMO::writeInternalConnection(device, wa.id, edgeID, 0, laneIndex, "");
202  }
203  for (const std::string& sw : wa.prevSidewalks) {
204  NBHelpers::interpretLaneID(sw, edgeID, laneIndex);
205  NWWriter_SUMO::writeInternalConnection(device, edgeID, wa.id, laneIndex, 0, "");
206  }
207  }
208  }
209 
210  // write loaded prohibitions
211  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
212  writeProhibitions(device, i->second->getProhibitions());
213  }
214 
215  // write roundabout information
216  writeRoundabouts(device, ec.getRoundabouts(), ec);
217 
218  // write the districts
219  for (std::map<std::string, NBDistrict*>::const_iterator i = dc.begin(); i != dc.end(); i++) {
220  writeDistrict(device, *(*i).second);
221  }
222  if (dc.size() != 0) {
223  device.lf();
224  }
225  device.close();
226 }
227 
228 
229 std::string
230 NWWriter_SUMO::getOppositeInternalID(const NBEdgeCont& ec, const NBEdge* from, const NBEdge::Connection& con, double& oppositeLength) {
231  const NBEdge::Lane& succ = con.toEdge->getLanes()[con.toLane];
232  const NBEdge::Lane& pred = from->getLanes()[con.fromLane];
233  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
234  if (succ.oppositeID != "" && succ.oppositeID != "-" && pred.oppositeID != "" && pred.oppositeID != "-") {
235 #ifdef DEBUG_OPPOSITE_INTERNAL
236  std::cout << "getOppositeInternalID con=" << con.getDescription(from) << " (" << con.getInternalLaneID() << ")\n";
237 #endif
238  // find the connection that connects succ.oppositeID to pred.oppositeID
239  const NBEdge* succOpp = ec.retrieve(succ.oppositeID.substr(0, succ.oppositeID.rfind("_")));
240  const NBEdge* predOpp = ec.retrieve(pred.oppositeID.substr(0, pred.oppositeID.rfind("_")));
241  assert(succOpp != 0);
242  assert(predOpp != 0);
243  const std::vector<NBEdge::Connection>& connections = succOpp->getConnections();
244  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) {
245  const NBEdge::Connection& conOpp = *it_c;
246  if (succOpp != from // turnaround
247  && predOpp == conOpp.toEdge
248  && succOpp->getLaneID(conOpp.fromLane) == succ.oppositeID
249  && predOpp->getLaneID(conOpp.toLane) == pred.oppositeID
250  && from->getToNode()->getDirection(from, con.toEdge, lefthand) == LINKDIR_STRAIGHT
251  && from->getToNode()->getDirection(succOpp, predOpp, lefthand) == LINKDIR_STRAIGHT
252  ) {
253 #ifdef DEBUG_OPPOSITE_INTERNAL
254  std::cout << " found " << conOpp.getInternalLaneID() << "\n";
255 #endif
256  oppositeLength = conOpp.length;
257  return conOpp.getInternalLaneID();
258  } else {
259  /*
260  #ifdef DEBUG_OPPOSITE_INTERNAL
261  std::cout << " rejected " << conOpp.getInternalLaneID()
262  << "\n succ.oppositeID=" << succ.oppositeID
263  << "\n succOppLane=" << succOpp->getLaneID(conOpp.fromLane)
264  << "\n pred.oppositeID=" << pred.oppositeID
265  << "\n predOppLane=" << predOpp->getLaneID(conOpp.toLane)
266  << "\n predOpp=" << predOpp->getID()
267  << "\n conOppTo=" << conOpp.toEdge->getID()
268  << "\n len1=" << con.shape.length()
269  << "\n len2=" << conOpp.shape.length()
270  << "\n";
271  #endif
272  */
273  }
274  }
275  return "";
276  } else {
277  return "";
278  }
279 }
280 
281 
282 bool
284  bool ret = false;
285  const EdgeVector& incoming = n.getIncomingEdges();
286  // first pass: determine opposite internal edges and average their length
287  std::map<std::string, std::string> oppositeLaneID;
288  std::map<std::string, double> oppositeLengths;
289  for (NBEdge* e : incoming) {
290  for (const NBEdge::Connection& c : e->getConnections()) {
291  double oppositeLength = 0;
292  const std::string op = getOppositeInternalID(ec, e, c, oppositeLength);
293  oppositeLaneID[c.getInternalLaneID()] = op;
294  if (op != "") {
295  oppositeLengths[c.id] = oppositeLength;
296  }
297  }
298  }
299  if (oppositeLengths.size() > 0) {
300  for (NBEdge* e : incoming) {
301  for (NBEdge::Connection& c : e->getConnections()) {
302  if (oppositeLengths.count(c.id) > 0) {
303  c.length = (c.length + oppositeLengths[c.id]) / 2;
304  }
305  }
306  }
307  }
308 
309  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
310  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
311  if (elv.size() > 0) {
312  bool haveVia = false;
313  std::string edgeID = "";
314  // second pass: write non-via edges
315  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
316  if ((*k).toEdge == 0) {
317  assert(false); // should never happen. tell me when it does
318  continue;
319  }
320  if (edgeID != (*k).id) {
321  if (edgeID != "") {
322  // close the previous edge
323  into.closeTag();
324  }
325  edgeID = (*k).id;
326  into.openTag(SUMO_TAG_EDGE);
327  into.writeAttr(SUMO_ATTR_ID, edgeID);
329  // open a new edge
330  }
331  // to avoid changing to an internal lane which has a successor
332  // with the wrong permissions we need to inherit them from the successor
333  const NBEdge::Lane& successor = (*k).toEdge->getLanes()[(*k).toLane];
334  const double width = n.isConstantWidthTransition() && (*i)->getNumLanes() > (*k).toEdge->getNumLanes() ? (*i)->getLaneWidth((*k).fromLane) : successor.width;
335  writeLane(into, (*k).getInternalLaneID(), (*k).vmax,
336  successor.permissions, successor.preferred,
337  NBEdge::UNSPECIFIED_OFFSET, std::map<int, double>(), width, (*k).shape, &(*k),
338  (*k).length, (*k).internalLaneIndex, oppositeLaneID[(*k).getInternalLaneID()]);
339  haveVia = haveVia || (*k).haveVia;
340  }
341  ret = true;
342  into.closeTag(); // close the last edge
343  // third pass: write via edges
344  if (haveVia) {
345  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
346  if (!(*k).haveVia) {
347  continue;
348  }
349  if ((*k).toEdge == 0) {
350  assert(false); // should never happen. tell me when it does
351  continue;
352  }
353  const NBEdge::Lane& successor = (*k).toEdge->getLanes()[(*k).toLane];
354  into.openTag(SUMO_TAG_EDGE);
355  into.writeAttr(SUMO_ATTR_ID, (*k).viaID);
357  writeLane(into, (*k).viaID + "_0", (*k).vmax, SVCAll, SVCAll,
358  NBEdge::UNSPECIFIED_OFFSET, std::map<int, double>(), successor.width, (*k).viaShape, &(*k),
359  MAX2((*k).viaShape.length(), POSITION_EPS), // microsim needs positive length
360  0, "");
361  into.closeTag();
362  }
363  }
364  }
365  }
366  // write pedestrian crossings
367  for (auto c : n.getCrossings()) {
368  into.openTag(SUMO_TAG_EDGE);
369  into.writeAttr(SUMO_ATTR_ID, c->id);
371  into.writeAttr(SUMO_ATTR_CROSSING_EDGES, c->edges);
372  writeLane(into, c->id + "_0", 1, SVC_PEDESTRIAN, 0,
373  NBEdge::UNSPECIFIED_OFFSET, std::map<int, double>(), c->width, c->shape, 0, MAX2(c->shape.length(), POSITION_EPS), 0, "", false, c->customShape.size() != 0);
374  into.closeTag();
375  }
376  // write pedestrian walking areas
377  const std::vector<NBNode::WalkingArea>& WalkingAreas = n.getWalkingAreas();
378  for (std::vector<NBNode::WalkingArea>::const_iterator it = WalkingAreas.begin(); it != WalkingAreas.end(); it++) {
379  const NBNode::WalkingArea& wa = *it;
380  into.openTag(SUMO_TAG_EDGE);
381  into.writeAttr(SUMO_ATTR_ID, wa.id);
383  writeLane(into, wa.id + "_0", 1, SVC_PEDESTRIAN, 0,
384  NBEdge::UNSPECIFIED_OFFSET, std::map<int, double>(), wa.width, wa.shape, 0, wa.length, 0, "", false, wa.hasCustomShape);
385  into.closeTag();
386  }
387  return ret;
388 }
389 
390 
391 void
392 NWWriter_SUMO::writeEdge(OutputDevice& into, const NBEdge& e, bool noNames) {
393  // write the edge's begin
396  into.writeAttr(SUMO_ATTR_TO, e.getToNode()->getID());
397  if (!noNames && e.getStreetName() != "") {
399  }
401  if (e.getTypeID() != "") {
403  }
404  if (e.isMacroscopicConnector()) {
406  }
407  // write the spread type if not default ("right")
410  }
411  if (e.hasLoadedLength()) {
413  }
414  if (!e.hasDefaultGeometry()) {
416  }
417  if (e.getStopOffsets().size() != 0) {
418  writeStopOffsets(into, e.getStopOffsets());
419  }
420 
421  // write the lanes
422  const std::vector<NBEdge::Lane>& lanes = e.getLanes();
423 
424  const double length = e.getFinalLength();
425  for (int i = 0; i < (int) lanes.size(); i++) {
426  const NBEdge::Lane& l = lanes[i];
427  std::map<int, double> stopOffsets;
428  if (l.stopOffsets != e.getStopOffsets()) {
429  stopOffsets = l.stopOffsets;
430  }
431  writeLane(into, e.getLaneID(i), l.speed,
432  l.permissions, l.preferred, l.endOffset, stopOffsets, l.width, l.shape, &l,
433  length, i, l.oppositeID, l.accelRamp, l.customShape.size() > 0);
434  }
435  // close the edge
436  e.writeParams(into);
437  into.closeTag();
438 }
439 
440 
441 void
442 NWWriter_SUMO::writeLane(OutputDevice& into, const std::string& lID,
443  double speed, SVCPermissions permissions, SVCPermissions preferred,
444  double endOffset, std::map<SVCPermissions, double> stopOffsets, double width, PositionVector shape,
445  const Parameterised* params, double length, int index,
446  const std::string& oppositeID, bool accelRamp, bool customShape) {
447  // output the lane's attributes
449  // the first lane of an edge will be the depart lane
450  into.writeAttr(SUMO_ATTR_INDEX, index);
451  // write the list of allowed/disallowed vehicle classes
452  if (permissions != SVC_UNSPECIFIED) {
453  writePermissions(into, permissions);
454  }
455  writePreferences(into, preferred);
456  // some further information
457  if (speed == 0) {
458  WRITE_WARNING("Lane '" + lID + "' has a maximum allowed speed of 0.");
459  } else if (speed < 0) {
460  throw ProcessError("Negative allowed speed (" + toString(speed) + ") on lane '" + lID + "', use --speed.minimum to prevent this.");
461  }
462  if (endOffset > 0) {
463  length = length - endOffset;
464  }
465  into.writeAttr(SUMO_ATTR_SPEED, speed);
466  into.writeAttr(SUMO_ATTR_LENGTH, length);
467  if (endOffset != NBEdge::UNSPECIFIED_OFFSET) {
468  into.writeAttr(SUMO_ATTR_ENDOFFSET, endOffset);
469  }
470  if (width != NBEdge::UNSPECIFIED_WIDTH) {
471  into.writeAttr(SUMO_ATTR_WIDTH, width);
472  }
473  if (accelRamp) {
474  into.writeAttr<bool>(SUMO_ATTR_ACCELERATION, accelRamp);
475  }
476  if (customShape) {
477  into.writeAttr(SUMO_ATTR_CUSTOMSHAPE, true);
478  }
479  into.writeAttr(SUMO_ATTR_SHAPE, endOffset > 0 ?
480  shape.getSubpart(0, shape.length() - endOffset) : shape);
481 
482  if (stopOffsets.size() != 0) {
483  writeStopOffsets(into, stopOffsets);
484  }
485 
486  if (oppositeID != "" && oppositeID != "-") {
487  into.openTag(SUMO_TAG_NEIGH);
488  into.writeAttr(SUMO_ATTR_LANE, oppositeID);
489  into.closeTag();
490  }
491 
492  if (params != 0) {
493  params->writeParams(into);
494  }
495 
496  into.closeTag();
497 }
498 
499 
500 void
501 NWWriter_SUMO::writeJunction(OutputDevice& into, const NBNode& n, const bool checkLaneFoes) {
502  // write the attributes
504  into.writeAttr(SUMO_ATTR_TYPE, n.getType());
506  // write the incoming lanes
507  std::string incLanes;
508  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
509  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
510  int noLanes = (*i)->getNumLanes();
511  for (int j = 0; j < noLanes; j++) {
512  incLanes += (*i)->getLaneID(j);
513  if (i != incoming.end() - 1 || j < noLanes - 1) {
514  incLanes += ' ';
515  }
516  }
517  }
518  std::vector<NBNode::Crossing*> crossings = n.getCrossings();
519  std::set<std::string> prevWAs;
520  // avoid duplicates
521  for (auto c : crossings) {
522  if (prevWAs.count(c->prevWalkingArea) == 0) {
523  incLanes += ' ' + c->prevWalkingArea + "_0";
524  prevWAs.insert(c->prevWalkingArea);
525  }
526  }
527  into.writeAttr(SUMO_ATTR_INCLANES, incLanes);
528  // write the internal lanes
529  std::string intLanes;
530  if (!OptionsCont::getOptions().getBool("no-internal-links")) {
531  int l = 0;
532  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
533  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
534  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
535  if ((*k).toEdge == 0) {
536  continue;
537  }
538  if (l != 0) {
539  intLanes += ' ';
540  }
541  if (!(*k).haveVia) {
542  intLanes += (*k).getInternalLaneID();
543  } else {
544  intLanes += (*k).viaID + "_0";
545  }
546  l++;
547  }
548  }
549  }
550  if (n.getType() != NODETYPE_DEAD_END && n.getType() != NODETYPE_NOJUNCTION) {
551  for (auto c : crossings) {
552  intLanes += ' ' + c->id + "_0";
553  }
554  }
555  into.writeAttr(SUMO_ATTR_INTLANES, intLanes);
556  // close writing
558  // write optional radius
561  }
562  // specify whether a custom shape was used
563  if (n.hasCustomShape()) {
564  into.writeAttr(SUMO_ATTR_CUSTOMSHAPE, true);
565  }
566  if (n.getType() != NODETYPE_DEAD_END) {
567  // write right-of-way logics
568  n.writeLogic(into, checkLaneFoes);
569  }
570  n.writeParams(into);
571  into.closeTag();
572 }
573 
574 
575 bool
577  bool ret = false;
578  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
579  // build the list of internal lane ids
580  std::vector<std::string> internalLaneIDs;
581  std::map<std::string, std::string> viaIDs;
582  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
583  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
584  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
585  if ((*k).toEdge != 0) {
586  internalLaneIDs.push_back((*k).getInternalLaneID());
587  viaIDs[(*k).getInternalLaneID()] = ((*k).viaID);
588  }
589  }
590  }
591  for (auto c : n.getCrossings()) {
592  internalLaneIDs.push_back(c->id + "_0");
593  }
594  // write the internal nodes
595  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
596  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
597  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
598  if ((*k).toEdge == 0 || !(*k).haveVia) {
599  continue;
600  }
601  Position pos = (*k).shape[-1];
602  into.openTag(SUMO_TAG_JUNCTION).writeAttr(SUMO_ATTR_ID, (*k).viaID + "_0");
604  NWFrame::writePositionLong(pos, into);
605  std::string incLanes = (*k).getInternalLaneID();
606  std::vector<std::string> foeIDs;
607  for (std::string incLane : (*k).foeIncomingLanes) {
608  incLanes += " " + incLane;
609  if (incLane[0] == ':' && viaIDs[incLane] != "") {
610  // intersecting left turns
611  foeIDs.push_back(viaIDs[incLane] + "_0");
612  }
613  }
614  into.writeAttr(SUMO_ATTR_INCLANES, incLanes);
615  const std::vector<int>& foes = (*k).foeInternalLinks;
616  for (std::vector<int>::const_iterator it = foes.begin(); it != foes.end(); ++it) {
617  foeIDs.push_back(internalLaneIDs[*it]);
618  }
619  into.writeAttr(SUMO_ATTR_INTLANES, joinToString(foeIDs, " "));
620  into.closeTag();
621  ret = true;
622  }
623  }
624  return ret;
625 }
626 
627 
628 void
630  bool includeInternal, ConnectionStyle style) {
631  assert(c.toEdge != 0);
633  into.writeAttr(SUMO_ATTR_FROM, from.getID());
634  into.writeAttr(SUMO_ATTR_TO, c.toEdge->getID());
637  if (c.mayDefinitelyPass && style != TLL) {
639  }
640  if ((from.getToNode()->getKeepClear() == false || c.keepClear == false) && style != TLL) {
641  into.writeAttr<bool>(SUMO_ATTR_KEEP_CLEAR, false);
642  }
643  if (c.contPos != NBEdge::UNSPECIFIED_CONTPOS && style != TLL) {
645  }
648  }
649  if (c.speed != NBEdge::UNSPECIFIED_SPEED && style != TLL) {
651  }
652  if (c.customShape.size() != 0 && style != TLL) {
654  }
655  if (c.uncontrolled != false && style != TLL) {
657  }
658  if (style != PLAIN) {
659  if (includeInternal) {
661  }
662  // set information about the controlling tl if any
663  if (c.tlID != "") {
664  into.writeAttr(SUMO_ATTR_TLID, c.tlID);
666  }
667  if (style == SUMONET) {
668  // write the direction information
669  LinkDirection dir = from.getToNode()->getDirection(&from, c.toEdge, OptionsCont::getOptions().getBool("lefthand"));
670  assert(dir != LINKDIR_NODIR);
671  into.writeAttr(SUMO_ATTR_DIR, toString(dir));
672  // write the state information
673  const LinkState linkState = from.getToNode()->getLinkState(
674  &from, c.toEdge, c.fromLane, c.toLane, c.mayDefinitelyPass, c.tlID);
675  into.writeAttr(SUMO_ATTR_STATE, linkState);
676  }
677  }
678  into.closeTag();
679 }
680 
681 
682 bool
684  bool ret = false;
685  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
686  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
687  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
688  NBEdge* from = *i;
689  const std::vector<NBEdge::Connection>& connections = from->getConnections();
690  for (std::vector<NBEdge::Connection>::const_iterator j = connections.begin(); j != connections.end(); ++j) {
691  const NBEdge::Connection& c = *j;
692  LinkDirection dir = n.getDirection(from, c.toEdge, lefthand);
693  assert(c.toEdge != 0);
694  if (c.haveVia) {
695  // internal split
696  writeInternalConnection(into, c.id, c.toEdge->getID(), c.internalLaneIndex, c.toLane, c.viaID + "_0", dir);
697  writeInternalConnection(into, c.viaID, c.toEdge->getID(), 0, c.toLane, "", dir);
698  } else {
699  // no internal split
700  writeInternalConnection(into, c.id, c.toEdge->getID(), c.internalLaneIndex, c.toLane, "", dir);
701  }
702  ret = true;
703  }
704  }
705  return ret;
706 }
707 
708 
709 void
711  const std::string& from, const std::string& to,
712  int fromLane, int toLane, const std::string& via,
713  LinkDirection dir, const std::string& tlID, int linkIndex) {
715  into.writeAttr(SUMO_ATTR_FROM, from);
716  into.writeAttr(SUMO_ATTR_TO, to);
717  into.writeAttr(SUMO_ATTR_FROM_LANE, fromLane);
718  into.writeAttr(SUMO_ATTR_TO_LANE, toLane);
719  if (via != "") {
720  into.writeAttr(SUMO_ATTR_VIA, via);
721  }
722  if (tlID != "" && linkIndex != NBConnection::InvalidTlIndex) {
723  // used for the reverse direction of pedestrian crossings
724  into.writeAttr(SUMO_ATTR_TLID, tlID);
725  into.writeAttr(SUMO_ATTR_TLLINKINDEX, linkIndex);
726  }
727  into.writeAttr(SUMO_ATTR_DIR, dir);
728  into.writeAttr(SUMO_ATTR_STATE, (via != "" ? "m" : "M"));
729  into.closeTag();
730 }
731 
732 
733 void
734 NWWriter_SUMO::writeRoundabouts(OutputDevice& into, const std::set<EdgeSet>& roundabouts,
735  const NBEdgeCont& ec) {
736  // make output deterministic
737  std::vector<std::vector<std::string> > edgeIDs;
738  for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
739  std::vector<std::string> tEdgeIDs;
740  for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
741  // the edges may have been erased from NBEdgeCont but their pointers are still valid
742  // we verify their existance in writeRoundabout()
743  tEdgeIDs.push_back((*j)->getID());
744  }
745  std::sort(tEdgeIDs.begin(), tEdgeIDs.end());
746  edgeIDs.push_back(tEdgeIDs);
747  }
748  std::sort(edgeIDs.begin(), edgeIDs.end());
749  // write
750  for (std::vector<std::vector<std::string> >::const_iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
751  writeRoundabout(into, *i, ec);
752  }
753  if (roundabouts.size() != 0) {
754  into.lf();
755  }
756 }
757 
758 
759 void
760 NWWriter_SUMO::writeRoundabout(OutputDevice& into, const std::vector<std::string>& edgeIDs,
761  const NBEdgeCont& ec) {
762  std::vector<std::string> validEdgeIDs;
763  std::vector<std::string> invalidEdgeIDs;
764  std::vector<std::string> nodeIDs;
765  for (std::vector<std::string>::const_iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
766  const NBEdge* edge = ec.retrieve(*i);
767  if (edge != 0) {
768  nodeIDs.push_back(edge->getToNode()->getID());
769  validEdgeIDs.push_back(edge->getID());
770  } else {
771  invalidEdgeIDs.push_back(*i);
772  }
773  }
774  std::sort(nodeIDs.begin(), nodeIDs.end());
775  if (validEdgeIDs.size() > 0) {
777  into.writeAttr(SUMO_ATTR_NODES, joinToString(nodeIDs, " "));
778  into.writeAttr(SUMO_ATTR_EDGES, joinToString(validEdgeIDs, " "));
779  into.closeTag();
780  if (invalidEdgeIDs.size() > 0) {
781  WRITE_WARNING("Writing incomplete roundabout. Edges: '"
782  + joinToString(invalidEdgeIDs, " ") + "' no longer exist'");
783  }
784  }
785 }
786 
787 
788 void
790  std::vector<double> sourceW = d.getSourceWeights();
792  std::vector<double> sinkW = d.getSinkWeights();
794  // write the head and the id of the district
796  if (d.getShape().size() > 0) {
798  }
799  // write all sources
800  const std::vector<NBEdge*>& sources = d.getSourceEdges();
801  for (int i = 0; i < (int)sources.size(); i++) {
802  // write the head and the id of the source
803  into.openTag(SUMO_TAG_TAZSOURCE).writeAttr(SUMO_ATTR_ID, sources[i]->getID()).writeAttr(SUMO_ATTR_WEIGHT, sourceW[i]);
804  into.closeTag();
805  }
806  // write all sinks
807  const std::vector<NBEdge*>& sinks = d.getSinkEdges();
808  for (int i = 0; i < (int)sinks.size(); i++) {
809  // write the head and the id of the sink
810  into.openTag(SUMO_TAG_TAZSINK).writeAttr(SUMO_ATTR_ID, sinks[i]->getID()).writeAttr(SUMO_ATTR_WEIGHT, sinkW[i]);
811  into.closeTag();
812  }
813  // write the tail
814  into.closeTag();
815 }
816 
817 
818 std::string
820  double time = STEPS2TIME(steps);
821  if (time == std::floor(time)) {
822  return toString(int(time));
823  } else {
824  return toString(time);
825  }
826 }
827 
828 
829 void
831  for (NBConnectionProhibits::const_iterator j = prohibitions.begin(); j != prohibitions.end(); j++) {
832  NBConnection prohibited = (*j).first;
833  const NBConnectionVector& prohibiting = (*j).second;
834  for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
835  NBConnection prohibitor = *k;
839  into.closeTag();
840  }
841  }
842 }
843 
844 
845 std::string
847  return c.getFrom()->getID() + "->" + c.getTo()->getID();
848 }
849 
850 
851 void
853  std::vector<NBTrafficLightLogic*> logics = tllCont.getComputed();
854  for (std::vector<NBTrafficLightLogic*>::iterator it = logics.begin(); it != logics.end(); it++) {
856  into.writeAttr(SUMO_ATTR_ID, (*it)->getID());
857  into.writeAttr(SUMO_ATTR_TYPE, (*it)->getType());
858  into.writeAttr(SUMO_ATTR_PROGRAMID, (*it)->getProgramID());
859  into.writeAttr(SUMO_ATTR_OFFSET, writeSUMOTime((*it)->getOffset()));
860  // write the phases
861  const bool varPhaseLength = (*it)->getType() != TLTYPE_STATIC;
862  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = (*it)->getPhases();
863  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator j = phases.begin(); j != phases.end(); ++j) {
864  into.openTag(SUMO_TAG_PHASE);
865  into.writeAttr(SUMO_ATTR_DURATION, writeSUMOTime(j->duration));
866  if (j->duration < TIME2STEPS(10)) {
867  into.writePadding(" ");
868  }
869  into.writeAttr(SUMO_ATTR_STATE, j->state);
870  if (varPhaseLength) {
873  }
876  }
877  }
878  into.closeTag();
879  }
880  // write params
881  (*it)->writeParams(into);
882  into.closeTag();
883  }
884  if (logics.size() > 0) {
885  into.lf();
886  }
887 }
888 
889 
890 void
891 NWWriter_SUMO::writeStopOffsets(OutputDevice& into, const std::map<SVCPermissions, double>& stopOffsets) {
892  if (stopOffsets.size() == 0) {
893  return;
894  }
895  assert(stopOffsets.size() == 1);
896  std::pair<int, double> offset = *stopOffsets.begin();
897  std::string ss_vclasses = getVehicleClassNames(offset.first);
898  if (ss_vclasses.length() == 0) {
899  // This stopOffset would have no effect...
900  return;
901  }
903  std::string ss_exceptions = getVehicleClassNames(~offset.first);
904  if (ss_vclasses.length() <= ss_exceptions.length()) {
905  into.writeAttr(SUMO_ATTR_VCLASSES, ss_vclasses);
906  } else {
907  if (ss_exceptions.length() == 0) {
908  into.writeAttr(SUMO_ATTR_VCLASSES, "all");
909  } else {
910  into.writeAttr(SUMO_ATTR_EXCEPTIONS, ss_exceptions);
911  }
912  }
913  into.writeAttr(SUMO_ATTR_VALUE, offset.second);
914  into.closeTag();
915 }
916 
917 /****************************************************************************/
918 
static void writeRoundabout(OutputDevice &into, const std::vector< std::string > &r, const NBEdgeCont &ec)
Writes a roundabout.
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:276
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:702
std::string id
id of Connection
Definition: NBEdge.h:215
The information about how to spread the lanes from the given position.
std::string getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
void writePermissions(OutputDevice &into, SVCPermissions permissions)
writes allowed disallowed attributes if needed;
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
void close()
Closes the device and removes it from the dictionary.
static void writeLocation(OutputDevice &into)
writes the location element
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:160
const std::vector< NBEdge * > & getSourceEdges() const
Returns the sources.
Definition: NBDistrict.h:191
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
Definition: NBNode.cpp:1787
int toLane
The lane the connections yields in.
Definition: NBEdge.h:188
long long int SUMOTime
Definition: SUMOTime.h:36
a list of node ids, used for controlling joining
NBTypeCont & getTypeCont()
Returns a reference to the type container.
Definition: NBNetBuilder.h:160
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
Whether vehicles must keep the junction clear.
PositionVector shape
The lane&#39;s shape.
Definition: NBEdge.h:121
whether a given shape is user-defined
a source within a district (connection road)
is a pedestrian
const std::map< int, double > & getStopOffsets() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.h:560
static void writeDistrict(OutputDevice &into, const NBDistrict &d)
Writes a district.
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:116
std::string viaID
if Connection have a via, ID of it
Definition: NBEdge.h:227
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:185
begin/end of the description of a junction
begin/end of the description of a single lane
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:268
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:121
A container for traffic light definitions and built programs.
a traffic assignment zone
void writePreferences(OutputDevice &into, SVCPermissions preferred)
writes allowed disallowed attributes if needed;
connectio between two lanes
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.cpp:2223
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:425
double length
This lane&#39;s width.
Definition: NBNode.h:178
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1002
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:494
std::map< std::string, NBDistrict * >::const_iterator end() const
Returns the pointer to the end of the stored districts.
The representation of a single edge during network building.
Definition: NBEdge.h:65
foe visibility distance of a link
static void writeProhibitions(OutputDevice &into, const NBConnectionProhibits &prohibitions)
writes the given prohibitions
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition: NBNode.h:205
A container for districts.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:259
link,node: the traffic light id responsible for this link
bool hasCustomShape
whether this walkingArea has a custom shape
Definition: NBNode.h:188
T MAX2(T a, T b)
Definition: StdDefs.h:76
double length
computed length (average of all internal lane shape lengths that share an internal edge) ...
Definition: NBEdge.h:251
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:505
static const SUMOTime UNSPECIFIED_DURATION
Crossing * getCrossing(const std::string &id) const
return the crossing with the given id
Definition: NBNode.cpp:2863
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:587
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:197
double endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:133
NBEdge * getFrom() const
returns the from-edge (start of the connection)
double visibility
custom foe visiblity for connection
Definition: NBEdge.h:206
std::string id
the (edge)-id of this walkingArea
Definition: NBNode.h:174
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:193
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
maximum duration of a phase
const std::string & getID() const
Returns the id.
Definition: Named.h:69
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
std::map< std::string, NBDistrict * >::const_iterator begin() const
Returns the pointer to the begin of the stored districts.
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
const SVCPermissions SVCAll
all VClasses are allowed
static void writeTrafficLights(OutputDevice &into, const NBTrafficLightLogicCont &tllCont)
writes the traffic light logics to the given device
std::string getDescription(const NBEdge *parent) const
get string describing this connection
Definition: NBEdge.cpp:84
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:256
prohibition of circulation between two edges
PositionVector customShape
custom shape for connection
Definition: NBEdge.h:212
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:242
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static void writeStopOffsets(OutputDevice &into, const std::map< SVCPermissions, double > &stopOffsets)
Write a stopOffset element into output device.
bool accelRamp
Whether this lane is an acceleration lane.
Definition: NBEdge.h:146
bool priority
whether the pedestrians have priority
Definition: NBNode.h:145
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
The link is a straight direction.
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:262
The state of a link.
A class representing a single district.
Definition: NBDistrict.h:65
bool keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:200
static std::string prohibitionConnection(const NBConnection &c)
the attribute value for a prohibition
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:116
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
Definition: NBEdge.h:127
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into a SUMO-file.
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
writes the XML-representation of the logic as a bitset-logic XML representation
Definition: NBNode.cpp:869
static const int InvalidTlIndex
Definition: NBConnection.h:120
The turning radius at an intersection in m.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:185
double speed
custom speed for connection
Definition: NBEdge.h:209
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBEdge.h:191
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:130
This is an uncontrolled, minor link, has to brake.
const PositionVector & getShape() const
Returns the shape.
Definition: NBDistrict.h:215
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2990
static bool writeInternalConnections(OutputDevice &into, const NBNode &n)
Writes inner connections within the node.
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:182
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >())
Writes an XML header with optional configuration.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:150
A list of positions.
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:265
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static void writeInternalConnection(OutputDevice &into, const std::string &from, const std::string &to, int fromLane, int toLane, const std::string &via, LinkDirection dir=LINKDIR_STRAIGHT, const std::string &tlID="", int linkIndex=NBConnection::InvalidTlIndex)
Writes a single internal connection.
bool isConstantWidthTransition() const
detects whether a given junction splits or merges lanes while keeping constant road width ...
Definition: NBNode.cpp:694
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:528
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
roundabout defined in junction
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:61
#define POSITION_EPS
Definition: config.h:172
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:541
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
static void writePositionLong(const Position &pos, OutputDevice &dev)
Writes the given position to device in long format (one attribute per dimension)
Definition: NWFrame.cpp:188
edge: the shape in xml-definition
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
begin/end of the description of a neighboring lane
An upper class for objects with additional parameters.
Definition: Parameterised.h:44
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static std::string getOppositeInternalID(const NBEdgeCont &ec, const NBEdge *from, const NBEdge::Connection &con, double &oppositeLength)
retrieve the id of the opposite direction internal lane if it exists
double speed
The speed allowed on this lane.
Definition: NBEdge.h:124
double width
This lane&#39;s width.
Definition: NBEdge.h:140
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3543
int tlLinkIndex
The index of this connection within the controlling traffic light.
Definition: NBEdge.h:194
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
begin/end of the description of an edge
static void normaliseSum(std::vector< T > &v, T msum=1.0)
Definition: VectorHelper.h:51
int size() const
Returns the number of districts inside the container.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream&#39;s direction.
Definition: NBNode.cpp:1696
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1911
PositionVector simplified() const
return the same shape with intermediate colinear points removed
NBEdge * getTo() const
returns the to-edge (end of the connection)
int internalLaneIndex
The lane index of this internal lane within the internal edge.
Definition: NBEdge.h:239
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:620
const std::vector< double > & getSinkWeights() const
Returns the weights of the sinks.
Definition: NBDistrict.h:199
double length() const
Returns the length.
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
std::vector< NBTrafficLightLogic * > getComputed() const
Returns a list of all computed logics.
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:271
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:143
a sink within a district (connection road)
the edges crossed by a pedestrian crossing
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:249
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:865
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:155
std::map< int, double > stopOffsets
stopOffsets.second - The stop offset for vehicles stopping at the lane&#39;s end. Applies if vClass is in...
Definition: NBEdge.h:137
Instance responsible for building networks.
Definition: NBNetBuilder.h:109
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, int &index)
parses edge-id and index from lane-id
Definition: NBHelpers.cpp:121
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
static bool writeInternalNodes(OutputDevice &into, const NBNode &n)
Writes internal junctions (<junction with id[0]==&#39;:&#39; ...) of the given node.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:245
const std::vector< NBEdge * > & getSinkEdges() const
Returns the sinks.
Definition: NBDistrict.h:207
A definition of a pedestrian walking area.
Definition: NBNode.h:164
double contPos
custom position for internal junction on this connection
Definition: NBEdge.h:203
A storage for options typed value containers)
Definition: OptionsCont.h:92
bool uncontrolled
check if Connection is uncontrolled
Definition: NBEdge.h:242
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:266
This is an uncontrolled, major link, may pass.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:165
static void writeLane(OutputDevice &into, const std::string &lID, double speed, SVCPermissions permissions, SVCPermissions preferred, double endOffset, std::map< SVCPermissions, double > stopOffsets, double width, PositionVector shape, const Parameterised *params, double length, int index, const std::string &oppositeID, bool accelRamp=false, bool customShape=false)
Writes a lane (<lane ...) of an edge.
The abstract direction of a link.
int tlLinkIndex
the traffic light index of this crossing (if controlled)
Definition: NBNode.h:149
const Position & getPosition() const
Definition: NBNode.h:241
Represents a single node (junction) during network building.
Definition: NBNode.h:68
A definition of a pedestrian crossing.
Definition: NBNode.h:125
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition: NBNode.h:641
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static void writeJunction(OutputDevice &into, const NBNode &n, const bool checkLaneFoes)
Writes a junction (<junction ...)
link: the index of the link within the traffic light
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBNode.h:155
bool isMacroscopicConnector() const
Returns whether this edge was marked as a macroscopic connector.
Definition: NBEdge.h:960
const std::vector< double > & getSourceWeights() const
Returns the weights of the sources.
Definition: NBDistrict.h:183
a traffic light logic
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:432
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:60
std::string getInternalLaneID() const
get ID of internal lane
Definition: NBEdge.cpp:78
static bool writeInternalEdges(OutputDevice &into, const NBEdgeCont &ec, const NBNode &n)
Writes internal edges (<edge ... with id[0]==&#39;:&#39;) of the given node.
static void writeEdge(OutputDevice &into, const NBEdge &e, bool noNames)
Writes an edge (<edge ...)
bool haveVia
check if Connection have a Via
Definition: NBEdge.h:224
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:495
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:170
PositionVector customShape
A custom shape for this lane set by the user.
Definition: NBEdge.h:153
OutputDevice & writePadding(const std::string &val)
writes padding (ignored for binary output)
Definition: OutputDevice.h:308
static const std::string MAJOR_VERSION
The version number for written files.
Definition: NWFrame.h:62
static void writeRoundabouts(OutputDevice &into, const std::set< EdgeSet > &roundabouts, const NBEdgeCont &ec)
Writes roundabouts.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:439
a single phase description
static std::string writeSUMOTime(SUMOTime time)
writes a SUMOTime as int if possible, otherwise as a float
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:230
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void lf()
writes a line feed if applicable
Definition: OutputDevice.h:234
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
static void writeConnection(OutputDevice &into, const NBEdge &from, const NBEdge::Connection &c, bool includeInternal, ConnectionStyle style=SUMONET)
Writes connections outgoing from the given edge (also used in NWWriter_XML)
PositionVector shape
The polygonal shape.
Definition: NBNode.h:180
void writeTypes(OutputDevice &into) const
writes all types a s XML
Definition: NBTypeCont.cpp:120
The link has no direction (is a dead end link)
double width
This lane&#39;s width.
Definition: NBNode.h:176
Information on vClass specific stop offsets at lane end.