SUMO - Simulation of Urban MObility
NWWriter_SUMO.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Exporter writing networks using the SUMO format
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2016 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 <cmath>
33 #include <algorithm>
37 #include <utils/common/ToString.h>
41 #include <netbuild/NBEdge.h>
42 #include <netbuild/NBEdgeCont.h>
43 #include <netbuild/NBNode.h>
44 #include <netbuild/NBNodeCont.h>
45 #include <netbuild/NBNetBuilder.h>
47 #include <netbuild/NBDistrict.h>
48 #include "NWFrame.h"
49 #include "NWWriter_SUMO.h"
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 
57 // ===========================================================================
58 // method definitions
59 // ===========================================================================
60 // ---------------------------------------------------------------------------
61 // static methods
62 // ---------------------------------------------------------------------------
63 void
65  // check whether a sumo net-file shall be generated
66  if (!oc.isSet("output-file")) {
67  return;
68  }
69  OutputDevice& device = OutputDevice::getDevice(oc.getString("output-file"));
70  const std::string lefthand = oc.getBool("lefthand") ? " " + toString(SUMO_ATTR_LEFTHAND) + "=\"true\"" : "";
71  const int cornerDetail = oc.getInt("junctions.corner-detail");
72  const int linkDetail = oc.getInt("junctions.internal-link-detail");
73  const std::string junctionCornerDetail = (cornerDetail > 0
74  ? " " + toString(SUMO_ATTR_CORNERDETAIL) + "=\"" + toString(cornerDetail) + "\"" : "");
75  const std::string junctionLinkDetail = (oc.isDefault("junctions.internal-link-detail") ? "" :
76  " " + toString(SUMO_ATTR_LINKDETAIL) + "=\"" + toString(linkDetail) + "\"");
77  device.writeXMLHeader("net", NWFrame::MAJOR_VERSION + lefthand + junctionCornerDetail + junctionLinkDetail +
78  " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/net_file.xsd\""); // street names may contain non-ascii chars
79  device.lf();
80  // get involved container
81  const NBNodeCont& nc = nb.getNodeCont();
82  const NBEdgeCont& ec = nb.getEdgeCont();
83  const NBDistrictCont& dc = nb.getDistrictCont();
84 
85  // write network offsets and projection
87 
88  // write edge types and restrictions
89  nb.getTypeCont().writeTypes(device);
90 
91  // write inner lanes
92  bool origNames = oc.getBool("output.original-names");
93  if (!oc.getBool("no-internal-links")) {
94  bool hadAny = false;
95  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
96  hadAny |= writeInternalEdges(device, ec, *(*i).second, origNames);
97  }
98  if (hadAny) {
99  device.lf();
100  }
101  }
102 
103  // write edges with lanes and connected edges
104  bool noNames = !oc.getBool("output.street-names");
105  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
106  writeEdge(device, *(*i).second, noNames, origNames);
107  }
108  device.lf();
109 
110  // write tls logics
111  writeTrafficLights(device, nb.getTLLogicCont());
112 
113  // write the nodes (junctions)
114  std::set<NBNode*> roundaboutNodes;
115  const bool checkLaneFoesAll = oc.getBool("check-lane-foes.all");
116  const bool checkLaneFoesRoundabout = !checkLaneFoesAll && oc.getBool("check-lane-foes.roundabout");
117  if (checkLaneFoesRoundabout) {
118  const std::set<EdgeSet>& roundabouts = ec.getRoundabouts();
119  for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
120  for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
121  roundaboutNodes.insert((*j)->getToNode());
122  }
123  }
124  }
125  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
126  const bool checkLaneFoes = checkLaneFoesAll || (checkLaneFoesRoundabout && roundaboutNodes.count((*i).second) > 0);
127  writeJunction(device, *(*i).second, checkLaneFoes);
128  }
129  device.lf();
130  const bool includeInternal = !oc.getBool("no-internal-links");
131  if (includeInternal) {
132  // ... internal nodes if not unwanted
133  bool hadAny = false;
134  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
135  hadAny |= writeInternalNodes(device, *(*i).second);
136  }
137  if (hadAny) {
138  device.lf();
139  }
140  }
141 
142  // write the successors of lanes
143  int numConnections = 0;
144  for (std::map<std::string, NBEdge*>::const_iterator it_edge = ec.begin(); it_edge != ec.end(); it_edge++) {
145  NBEdge* from = it_edge->second;
147  const std::vector<NBEdge::Connection> connections = from->getConnections();
148  numConnections += (int)connections.size();
149  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) {
150  writeConnection(device, *from, *it_c, includeInternal);
151  }
152  }
153  if (numConnections > 0) {
154  device.lf();
155  }
156  if (includeInternal) {
157  // ... internal successors if not unwanted
158  bool hadAny = false;
159  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
160  hadAny |= writeInternalConnections(device, *(*i).second);
161  }
162  if (hadAny) {
163  device.lf();
164  }
165  }
166  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
167  NBNode* node = (*i).second;
168  // write connections from pedestrian crossings
169  const std::vector<NBNode::Crossing>& crossings = node->getCrossings();
170  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
171  NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it).nextWalkingArea, 0, 0, "");
172  }
173  // write connections from pedestrian walking areas
174  const std::vector<NBNode::WalkingArea>& WalkingAreas = node->getWalkingAreas();
175  for (std::vector<NBNode::WalkingArea>::const_iterator it = WalkingAreas.begin(); it != WalkingAreas.end(); it++) {
176  if ((*it).nextCrossing != "") {
177  const NBNode::Crossing& nextCrossing = node->getCrossing((*it).nextCrossing);
178  // connection to next crossing (may be tls-controlled)
180  device.writeAttr(SUMO_ATTR_FROM, (*it).id);
181  device.writeAttr(SUMO_ATTR_TO, (*it).nextCrossing);
182  device.writeAttr(SUMO_ATTR_FROM_LANE, 0);
183  device.writeAttr(SUMO_ATTR_TO_LANE, 0);
184  if (node->isTLControlled()) {
185  device.writeAttr(SUMO_ATTR_TLID, (*node->getControllingTLS().begin())->getID());
186  assert(nextCrossing.tlLinkNo >= 0);
187  device.writeAttr(SUMO_ATTR_TLLINKINDEX, nextCrossing.tlLinkNo);
188  }
191  device.closeTag();
192  }
193  // optional connections from/to sidewalk
194  for (std::vector<std::string>::const_iterator it_sw = (*it).nextSidewalks.begin(); it_sw != (*it).nextSidewalks.end(); ++it_sw) {
195  NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it_sw), 0, 0, "");
196  }
197  for (std::vector<std::string>::const_iterator it_sw = (*it).prevSidewalks.begin(); it_sw != (*it).prevSidewalks.end(); ++it_sw) {
198  NWWriter_SUMO::writeInternalConnection(device, (*it_sw), (*it).id, 0, 0, "");
199  }
200  }
201  }
202 
203  // write loaded prohibitions
204  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
205  writeProhibitions(device, i->second->getProhibitions());
206  }
207 
208  // write roundabout information
209  writeRoundabouts(device, ec.getRoundabouts(), ec);
210 
211  // write the districts
212  for (std::map<std::string, NBDistrict*>::const_iterator i = dc.begin(); i != dc.end(); i++) {
213  writeDistrict(device, *(*i).second);
214  }
215  if (dc.size() != 0) {
216  device.lf();
217  }
218  device.close();
219 }
220 
221 
222 std::string
224  const NBEdge::Lane& succ = con.toEdge->getLanes()[con.toLane];
225  const NBEdge::Lane& pred = from->getLanes()[con.fromLane];
226  if (succ.oppositeID != "" && succ.oppositeID != "-" && pred.oppositeID != "" && pred.oppositeID != "-") {
227  // find the connection that connects succ.oppositeID to pred.oppositeID
228  const NBEdge* succOpp = ec.retrieve(succ.oppositeID.substr(0, succ.oppositeID.rfind("_")));
229  const NBEdge* predOpp = ec.retrieve(pred.oppositeID.substr(0, pred.oppositeID.rfind("_")));
230  assert(succOpp != 0);
231  assert(predOpp != 0);
232  const std::vector<NBEdge::Connection>& connections = succOpp->getConnections();
233  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) {
234  const NBEdge::Connection& conOpp = *it_c;
235  if (succOpp != from && // turnaround
236  succOpp->getLaneID(conOpp.fromLane) == succ.oppositeID &&
237  predOpp == conOpp.toEdge &&
238  predOpp->getLaneID(conOpp.toLane) == pred.oppositeID) {
239  return conOpp.getInternalLaneID();
240  }
241  }
242  return "";
243  } else {
244  return "";
245  }
246 }
247 
248 
249 bool
250 NWWriter_SUMO::writeInternalEdges(OutputDevice& into, const NBEdgeCont& ec, const NBNode& n, bool origNames) {
251  bool ret = false;
252  const EdgeVector& incoming = n.getIncomingEdges();
253  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
254  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
255  if (elv.size() > 0) {
256  bool haveVia = false;
257  NBEdge* toEdge = 0;
258  std::string internalEdgeID = "";
259  // first pass: compute average lengths of non-via edges
260  std::map<NBEdge*, SUMOReal> lengthSum;
261  std::map<NBEdge*, int> numLanes;
262  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
263  lengthSum[(*k).toEdge] += MAX2((*k).shape.length(), POSITION_EPS);
264  numLanes[(*k).toEdge] += 1;
265  }
266  // second pass: write non-via edges
267  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
268  if ((*k).toEdge == 0) {
269  assert(false); // should never happen. tell me when it does
270  continue;
271  }
272  if (toEdge != (*k).toEdge) {
273  internalEdgeID = (*k).id;
274  if (toEdge != 0) {
275  // close the previous edge
276  into.closeTag();
277  }
278  toEdge = (*k).toEdge;
279  into.openTag(SUMO_TAG_EDGE);
280  into.writeAttr(SUMO_ATTR_ID, internalEdgeID);
282  // open a new edge
283  }
284  // to avoid changing to an internal lane which has a successor
285  // with the wrong permissions we need to inherit them from the successor
286  const NBEdge::Lane& successor = (*k).toEdge->getLanes()[(*k).toLane];
287  const SUMOReal length = lengthSum[toEdge] / numLanes[toEdge];
288  // @note the actual length should be used once sumo supports lanes of
289  // varying length within the same edge
290  //const SUMOReal length = MAX2((*k).shape.length(), POSITION_EPS);
291  writeLane(into, (*k).getInternalLaneID(), (*k).vmax,
292  successor.permissions, successor.preferred,
293  NBEdge::UNSPECIFIED_OFFSET, successor.width, (*k).shape, (*k).origID,
294  length, (*k).internalLaneIndex, origNames, getOppositeInternalID(ec, *i, *k), &n);
295  haveVia = haveVia || (*k).haveVia;
296  }
297  ret = true;
298  into.closeTag(); // close the last edge
299  // third pass: write via edges
300  if (haveVia) {
301  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
302  if (!(*k).haveVia) {
303  continue;
304  }
305  if ((*k).toEdge == 0) {
306  assert(false); // should never happen. tell me when it does
307  continue;
308  }
309  const NBEdge::Lane& successor = (*k).toEdge->getLanes()[(*k).toLane];
310  into.openTag(SUMO_TAG_EDGE);
311  into.writeAttr(SUMO_ATTR_ID, (*k).viaID);
313  writeLane(into, (*k).viaID + "_0", (*k).viaVmax, SVCAll, SVCAll,
314  NBEdge::UNSPECIFIED_OFFSET, successor.width, (*k).viaShape, (*k).origID,
315  MAX2((*k).viaShape.length(), POSITION_EPS), // microsim needs positive length
316  0, origNames, "", &n);
317  into.closeTag();
318  }
319  }
320  }
321  }
322  // write pedestrian crossings
323  const std::vector<NBNode::Crossing>& crossings = n.getCrossings();
324  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
325  into.openTag(SUMO_TAG_EDGE);
326  into.writeAttr(SUMO_ATTR_ID, (*it).id);
328  into.writeAttr(SUMO_ATTR_CROSSING_EDGES, (*it).edges);
329  writeLane(into, (*it).id + "_0", 1, SVC_PEDESTRIAN, 0,
330  NBEdge::UNSPECIFIED_OFFSET, (*it).width, (*it).shape, "", (*it).shape.length(), 0, false, "", &n);
331  into.closeTag();
332  }
333  // write pedestrian walking areas
334  const std::vector<NBNode::WalkingArea>& WalkingAreas = n.getWalkingAreas();
335  for (std::vector<NBNode::WalkingArea>::const_iterator it = WalkingAreas.begin(); it != WalkingAreas.end(); it++) {
336  const NBNode::WalkingArea& wa = *it;
337  into.openTag(SUMO_TAG_EDGE);
338  into.writeAttr(SUMO_ATTR_ID, wa.id);
340  writeLane(into, wa.id + "_0", 1, SVC_PEDESTRIAN, 0,
341  NBEdge::UNSPECIFIED_OFFSET, wa.width, wa.shape, "", wa.length, 0, false, "", &n);
342  into.closeTag();
343  }
344  return ret;
345 }
346 
347 
348 void
349 NWWriter_SUMO::writeEdge(OutputDevice& into, const NBEdge& e, bool noNames, bool origNames) {
350  // write the edge's begin
353  into.writeAttr(SUMO_ATTR_TO, e.getToNode()->getID());
354  if (!noNames && e.getStreetName() != "") {
356  }
358  if (e.getTypeID() != "") {
360  }
361  if (e.isMacroscopicConnector()) {
363  }
364  // write the spread type if not default ("right")
367  }
368  if (e.hasLoadedLength()) {
370  }
371  if (!e.hasDefaultGeometry()) {
373  }
374  // write the lanes
375  const std::vector<NBEdge::Lane>& lanes = e.getLanes();
376 
377  const SUMOReal length = e.getFinalLength();
378  for (int i = 0; i < (int) lanes.size(); i++) {
379  const NBEdge::Lane& l = lanes[i];
380  writeLane(into, e.getLaneID(i), l.speed,
381  l.permissions, l.preferred, l.endOffset, l.width, l.shape, l.origID,
382  length, i, origNames, l.oppositeID);
383  }
384  // close the edge
385  into.closeTag();
386 }
387 
388 
389 void
390 NWWriter_SUMO::writeLane(OutputDevice& into, const std::string& lID,
391  SUMOReal speed, SVCPermissions permissions, SVCPermissions preferred,
392  SUMOReal endOffset, SUMOReal width, PositionVector shape,
393  const std::string& origID, SUMOReal length, int index, bool origNames,
394  const std::string& oppositeID, const NBNode* node) {
395  // output the lane's attributes
397  // the first lane of an edge will be the depart lane
398  into.writeAttr(SUMO_ATTR_INDEX, index);
399  // write the list of allowed/disallowed vehicle classes
400  if (permissions != SVC_UNSPECIFIED) {
401  writePermissions(into, permissions);
402  }
403  writePreferences(into, preferred);
404  // some further information
405  if (speed == 0) {
406  WRITE_WARNING("Lane '" + lID + "' has a maximum allowed speed of 0.");
407  } else if (speed < 0) {
408  throw ProcessError("Negative allowed speed (" + toString(speed) + ") on lane '" + lID + "', use --speed.minimum to prevent this.");
409  }
410  if (endOffset > 0) {
411  length = length - endOffset;
412  }
413  into.writeAttr(SUMO_ATTR_SPEED, speed);
414  into.writeAttr(SUMO_ATTR_LENGTH, length);
415  if (endOffset != NBEdge::UNSPECIFIED_OFFSET) {
416  into.writeAttr(SUMO_ATTR_ENDOFFSET, endOffset);
417  }
418  if (width != NBEdge::UNSPECIFIED_WIDTH) {
419  into.writeAttr(SUMO_ATTR_WIDTH, width);
420  }
421  if (node != 0) {
422  const NBNode::CustomShapeMap& cs = node->getCustomLaneShapes();
423  NBNode::CustomShapeMap::const_iterator it = cs.find(lID);
424  if (it != cs.end()) {
425  shape = it->second;
426  into.writeAttr(SUMO_ATTR_CUSTOMSHAPE, true);
427  }
428  }
429  into.writeAttr(SUMO_ATTR_SHAPE, endOffset > 0 ?
430  shape.getSubpart(0, shape.length() - endOffset) : shape);
431  if (oppositeID != "" && oppositeID != "-") {
432  into.openTag(SUMO_TAG_NEIGH);
433  into.writeAttr(SUMO_ATTR_LANE, oppositeID);
434  into.closeTag();
435  }
436  if (origNames && origID != "") {
437  into.openTag(SUMO_TAG_PARAM);
438  into.writeAttr(SUMO_ATTR_KEY, "origId");
439  into.writeAttr(SUMO_ATTR_VALUE, origID);
440  into.closeTag();
441  }
442  into.closeTag();
443 }
444 
445 
446 void
447 NWWriter_SUMO::writeJunction(OutputDevice& into, const NBNode& n, const bool checkLaneFoes) {
448  // write the attributes
450  into.writeAttr(SUMO_ATTR_TYPE, n.getType());
452  // write the incoming lanes
453  std::string incLanes;
454  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
455  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
456  int noLanes = (*i)->getNumLanes();
457  for (int j = 0; j < noLanes; j++) {
458  incLanes += (*i)->getLaneID(j);
459  if (i != incoming.end() - 1 || j < noLanes - 1) {
460  incLanes += ' ';
461  }
462  }
463  }
464  const std::vector<NBNode::Crossing>& crossings = n.getCrossings();
465  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
466  incLanes += ' ' + (*it).prevWalkingArea + "_0";
467  }
468  into.writeAttr(SUMO_ATTR_INCLANES, incLanes);
469  // write the internal lanes
470  std::string intLanes;
471  if (!OptionsCont::getOptions().getBool("no-internal-links")) {
472  int l = 0;
473  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
474  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
475  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
476  if ((*k).toEdge == 0) {
477  continue;
478  }
479  if (l != 0) {
480  intLanes += ' ';
481  }
482  if (!(*k).haveVia) {
483  intLanes += (*k).getInternalLaneID();
484  } else {
485  intLanes += (*k).viaID + "_0";
486  }
487  l++;
488  }
489  }
490  }
491  if (n.getType() != NODETYPE_DEAD_END && n.getType() != NODETYPE_NOJUNCTION) {
492  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
493  intLanes += ' ' + (*it).id + "_0";
494  }
495  }
496  into.writeAttr(SUMO_ATTR_INTLANES, intLanes);
497  // close writing
499  // write optional radius
502  }
503  // specify whether a custom shape was used
504  if (n.hasCustomShape()) {
505  into.writeAttr(SUMO_ATTR_CUSTOMSHAPE, true);
506  }
507  if (n.getType() == NODETYPE_DEAD_END) {
508  into.closeTag();
509  } else {
510  // write right-of-way logics
511  n.writeLogic(into, checkLaneFoes);
512  into.closeTag();
513  }
514 }
515 
516 
517 bool
519  bool ret = false;
520  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
521  // build the list of internal lane ids
522  std::vector<std::string> internalLaneIDs;
523  for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
524  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
525  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
526  if ((*k).toEdge != 0) {
527  internalLaneIDs.push_back((*k).getInternalLaneID());
528  }
529  }
530  }
531  const std::vector<NBNode::Crossing>& crossings = n.getCrossings();
532  for (std::vector<NBNode::Crossing>::const_iterator it_c = crossings.begin(); it_c != crossings.end(); ++it_c) {
533  internalLaneIDs.push_back((*it_c).id + "_0");
534  }
535  // write the internal nodes
536  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
537  const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
538  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
539  if ((*k).toEdge == 0 || !(*k).haveVia) {
540  continue;
541  }
542  Position pos = (*k).shape[-1];
543  into.openTag(SUMO_TAG_JUNCTION).writeAttr(SUMO_ATTR_ID, (*k).viaID + "_0");
545  NWFrame::writePositionLong(pos, into);
546  std::string incLanes = (*k).getInternalLaneID();
547  if ((*k).foeIncomingLanes.length() != 0) {
548  incLanes += " " + (*k).foeIncomingLanes;
549  }
550  into.writeAttr(SUMO_ATTR_INCLANES, incLanes);
551  const std::vector<int>& foes = (*k).foeInternalLinks;
552  std::vector<std::string> foeIDs;
553  for (std::vector<int>::const_iterator it = foes.begin(); it != foes.end(); ++it) {
554  foeIDs.push_back(internalLaneIDs[*it]);
555  }
556  into.writeAttr(SUMO_ATTR_INTLANES, joinToString(foeIDs, " "));
557  into.closeTag();
558  ret = true;
559  }
560  }
561  return ret;
562 }
563 
564 
565 void
567  bool includeInternal, ConnectionStyle style) {
568  assert(c.toEdge != 0);
570  into.writeAttr(SUMO_ATTR_FROM, from.getID());
571  into.writeAttr(SUMO_ATTR_TO, c.toEdge->getID());
574  if (c.mayDefinitelyPass && style != TLL) {
576  }
577  if ((from.getToNode()->getKeepClear() == false || c.keepClear == false) && style != TLL) {
578  into.writeAttr<bool>(SUMO_ATTR_KEEP_CLEAR, false);
579  }
580  if (c.contPos != NBEdge::UNSPECIFIED_CONTPOS && style != TLL) {
582  }
585  }
586  if (style != PLAIN) {
587  if (includeInternal) {
589  }
590  // set information about the controlling tl if any
591  if (c.tlID != "") {
592  into.writeAttr(SUMO_ATTR_TLID, c.tlID);
594  }
595  if (style == SUMONET) {
596  // write the direction information
597  LinkDirection dir = from.getToNode()->getDirection(&from, c.toEdge, OptionsCont::getOptions().getBool("lefthand"));
598  assert(dir != LINKDIR_NODIR);
599  into.writeAttr(SUMO_ATTR_DIR, toString(dir));
600  // write the state information
601  const LinkState linkState = from.getToNode()->getLinkState(
602  &from, c.toEdge, c.fromLane, c.toLane, c.mayDefinitelyPass, c.tlID);
603  into.writeAttr(SUMO_ATTR_STATE, linkState);
604  }
605  }
606  into.closeTag();
607 }
608 
609 
610 bool
612  bool ret = false;
613  const std::vector<NBEdge*>& incoming = n.getIncomingEdges();
614  for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
615  NBEdge* from = *i;
616  const std::vector<NBEdge::Connection>& connections = from->getConnections();
617  for (std::vector<NBEdge::Connection>::const_iterator j = connections.begin(); j != connections.end(); ++j) {
618  const NBEdge::Connection& c = *j;
619  assert(c.toEdge != 0);
620  if (c.haveVia) {
621  // internal split
622  writeInternalConnection(into, c.id, c.toEdge->getID(), c.internalLaneIndex, c.toLane, c.viaID + "_0");
623  writeInternalConnection(into, c.viaID, c.toEdge->getID(), 0, c.toLane, "");
624  } else {
625  // no internal split
627  }
628  ret = true;
629  }
630  }
631  return ret;
632 }
633 
634 
635 void
637  const std::string& from, const std::string& to,
638  int fromLane, int toLane, const std::string& via) {
640  into.writeAttr(SUMO_ATTR_FROM, from);
641  into.writeAttr(SUMO_ATTR_TO, to);
642  into.writeAttr(SUMO_ATTR_FROM_LANE, fromLane);
643  into.writeAttr(SUMO_ATTR_TO_LANE, toLane);
644  if (via != "") {
645  into.writeAttr(SUMO_ATTR_VIA, via);
646  }
647  into.writeAttr(SUMO_ATTR_DIR, "s");
648  into.writeAttr(SUMO_ATTR_STATE, (via != "" ? "m" : "M"));
649  into.closeTag();
650 }
651 
652 
653 void
654 NWWriter_SUMO::writeRoundabouts(OutputDevice& into, const std::set<EdgeSet>& roundabouts,
655  const NBEdgeCont& ec) {
656  // make output deterministic
657  std::vector<std::vector<std::string> > edgeIDs;
658  for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
659  std::vector<std::string> tEdgeIDs;
660  for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
661  // the edges may have been erased from NBEdgeCont but their pointers are still valid
662  // we verify their existance in writeRoundabout()
663  tEdgeIDs.push_back((*j)->getID());
664  }
665  std::sort(tEdgeIDs.begin(), tEdgeIDs.end());
666  edgeIDs.push_back(tEdgeIDs);
667  }
668  std::sort(edgeIDs.begin(), edgeIDs.end());
669  // write
670  for (std::vector<std::vector<std::string> >::const_iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
671  writeRoundabout(into, *i, ec);
672  }
673  if (roundabouts.size() != 0) {
674  into.lf();
675  }
676 }
677 
678 
679 void
680 NWWriter_SUMO::writeRoundabout(OutputDevice& into, const std::vector<std::string>& edgeIDs,
681  const NBEdgeCont& ec) {
682  std::vector<std::string> validEdgeIDs;
683  std::vector<std::string> invalidEdgeIDs;
684  std::vector<std::string> nodeIDs;
685  for (std::vector<std::string>::const_iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
686  const NBEdge* edge = ec.retrieve(*i);
687  if (edge != 0) {
688  nodeIDs.push_back(edge->getToNode()->getID());
689  validEdgeIDs.push_back(edge->getID());
690  } else {
691  invalidEdgeIDs.push_back(*i);
692  }
693  }
694  std::sort(nodeIDs.begin(), nodeIDs.end());
695  if (validEdgeIDs.size() > 0) {
697  into.writeAttr(SUMO_ATTR_NODES, joinToString(nodeIDs, " "));
698  into.writeAttr(SUMO_ATTR_EDGES, joinToString(validEdgeIDs, " "));
699  into.closeTag();
700  if (invalidEdgeIDs.size() > 0) {
701  WRITE_WARNING("Writing incomplete roundabout. Edges: '"
702  + joinToString(invalidEdgeIDs, " ") + "' no longer exist'");
703  }
704  }
705 }
706 
707 
708 void
710  std::vector<SUMOReal> sourceW = d.getSourceWeights();
712  std::vector<SUMOReal> sinkW = d.getSinkWeights();
714  // write the head and the id of the district
716  if (d.getShape().size() > 0) {
718  }
719  // write all sources
720  const std::vector<NBEdge*>& sources = d.getSourceEdges();
721  for (int i = 0; i < (int)sources.size(); i++) {
722  // write the head and the id of the source
723  into.openTag(SUMO_TAG_TAZSOURCE).writeAttr(SUMO_ATTR_ID, sources[i]->getID()).writeAttr(SUMO_ATTR_WEIGHT, sourceW[i]);
724  into.closeTag();
725  }
726  // write all sinks
727  const std::vector<NBEdge*>& sinks = d.getSinkEdges();
728  for (int i = 0; i < (int)sinks.size(); i++) {
729  // write the head and the id of the sink
730  into.openTag(SUMO_TAG_TAZSINK).writeAttr(SUMO_ATTR_ID, sinks[i]->getID()).writeAttr(SUMO_ATTR_WEIGHT, sinkW[i]);
731  into.closeTag();
732  }
733  // write the tail
734  into.closeTag();
735 }
736 
737 
738 std::string
740  SUMOReal time = STEPS2TIME(steps);
741  if (time == std::floor(time)) {
742  return toString(int(time));
743  } else {
744  return toString(time);
745  }
746 }
747 
748 
749 void
751  for (NBConnectionProhibits::const_iterator j = prohibitions.begin(); j != prohibitions.end(); j++) {
752  NBConnection prohibited = (*j).first;
753  const NBConnectionVector& prohibiting = (*j).second;
754  for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
755  NBConnection prohibitor = *k;
759  into.closeTag();
760  }
761  }
762 }
763 
764 
765 std::string
767  return c.getFrom()->getID() + "->" + c.getTo()->getID();
768 }
769 
770 
771 void
773  std::vector<NBTrafficLightLogic*> logics = tllCont.getComputed();
774  for (std::vector<NBTrafficLightLogic*>::iterator it = logics.begin(); it != logics.end(); it++) {
776  into.writeAttr(SUMO_ATTR_ID, (*it)->getID());
777  into.writeAttr(SUMO_ATTR_TYPE, (*it)->getType());
778  into.writeAttr(SUMO_ATTR_PROGRAMID, (*it)->getProgramID());
779  into.writeAttr(SUMO_ATTR_OFFSET, writeSUMOTime((*it)->getOffset()));
780  // write params
781  const std::map<std::string, std::string>& params = (*it)->getMap();
782  for (std::map<std::string, std::string>::const_iterator i = params.begin(); i != params.end(); ++i) {
783  into.openTag(SUMO_TAG_PARAM);
784  into.writeAttr(SUMO_ATTR_KEY, (*i).first);
785  into.writeAttr(SUMO_ATTR_VALUE, (*i).second);
786  into.closeTag();
787  }
788  // write the phases
789  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = (*it)->getPhases();
790  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator j = phases.begin(); j != phases.end(); ++j) {
791  into.openTag(SUMO_TAG_PHASE);
792  into.writeAttr(SUMO_ATTR_DURATION, writeSUMOTime(j->duration));
793  into.writeAttr(SUMO_ATTR_STATE, j->state);
794  into.closeTag();
795  }
796  into.closeTag();
797  }
798  if (logics.size() > 0) {
799  into.lf();
800  }
801 }
802 /****************************************************************************/
803 
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:278
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:646
std::string id
id of Connection
Definition: NBEdge.h:202
The information about how to spread the lanes from the given position.
int tlLinkNo
The index of this connection within the controlling traffic light.
Definition: NBEdge.h:184
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:257
void close()
Closes the device and removes it from the dictionary.
static void writeLocation(OutputDevice &into)
writes the location element
SUMOReal endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:141
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:157
const std::vector< NBEdge * > & getSourceEdges() const
Returns the sources.
Definition: NBDistrict.h:198
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
Definition: NBNode.cpp:1619
int toLane
The lane the connections yields in.
Definition: NBEdge.h:178
long long int SUMOTime
Definition: SUMOTime.h:43
a list of node ids, used for controlling joining
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:237
NBTypeCont & getTypeCont()
Returns the type container.
Definition: NBNetBuilder.h:169
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:129
whether a given shape is user-defined
SUMOReal getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:272
is a pedestrian
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:126
std::string viaID
if Connection have a via, ID of it
Definition: NBEdge.h:214
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:175
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:134
const CustomShapeMap & getCustomLaneShapes() const
sets a custom shape for an internal lane
Definition: NBNode.h:505
SUMOReal length() const
Returns the length.
A container for traffic light definitions and built programs.
SUMOReal length
This lane&#39;s width.
Definition: NBNode.h:171
SUMOReal width
This lane&#39;s width.
Definition: NBNode.h:169
static bool writeInternalEdges(OutputDevice &into, const NBEdgeCont &ec, const NBNode &n, bool origNames)
Writes internal edges (<edge ... with id[0]==&#39;:&#39;) of the given node.
void writePreferences(OutputDevice &into, SVCPermissions preferred)
writes allowed disallowed attributes if needed;
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:402
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:934
int SVCPermissions
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:520
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:71
foe visibility distance of a link
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
const std::vector< Crossing > & getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.h:657
static void writeProhibitions(OutputDevice &into, const NBConnectionProhibits &prohibitions)
writes the given prohibitions
A container for districts.
T MAX2(T a, T b)
Definition: StdDefs.h:75
const std::vector< SUMOReal > & getSinkWeights() const
Returns the weights of the sinks.
Definition: NBDistrict.h:206
the weight of a district&#39;s source or sink
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:482
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:552
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:187
NBEdge * getFrom() const
returns the from-edge (start of the connection)
std::string id
the (edge)-id of this walkingArea
Definition: NBNode.h:167
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:198
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
static const SUMOReal UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:246
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
static void writeTrafficLights(OutputDevice &into, const NBTrafficLightLogicCont &tllCont)
writes the traffic light logics to the given device
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:240
static void writeInternalConnection(OutputDevice &into, const std::string &from, const std::string &to, int fromLane, int toLane, const std::string &via)
Writes a single internal connection.
const Crossing & getCrossing(const std::string &id) const
return the crossing with the given id
Definition: NBNode.cpp:2554
static std::string getOppositeInternalID(const NBEdgeCont &ec, const NBEdge *from, const NBEdge::Connection &con)
retrieve the id of the opposite direction internal lane if it exists
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
bool priority
whether the pedestrians have priority
Definition: NBNode.h:151
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
bool writeXMLHeader(const std::string &rootElement, const std::string &attrs="", const std::string &comment="")
Writes an XML header with optional configuration.
The link is a straight direction.
The state of a link.
SUMOReal speed
The speed allowed on this lane.
Definition: NBEdge.h:132
A class representing a single district.
Definition: NBDistrict.h:72
bool keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:190
std::map< std::string, PositionVector > CustomShapeMap
Definition: NBNode.h:82
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:124
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:135
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into a SUMO-file.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:304
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
Definition: NBNode.cpp:780
The turning radius at an intersection in m.
const std::vector< SUMOReal > & getSourceWeights() const
Returns the weights of the sources.
Definition: NBDistrict.h:190
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:190
the edges of a route
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBEdge.h:181
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:138
This is an uncontrolled, minor link, has to brake.
const PositionVector & getShape() const
Returns the shape.
Definition: NBDistrict.h:222
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2499
static bool writeInternalConnections(OutputDevice &into, const NBNode &n)
Writes inner connections within the node.
static void writeLane(OutputDevice &into, const std::string &lID, SUMOReal speed, SVCPermissions permissions, SVCPermissions preferred, SUMOReal endOffset, SUMOReal width, PositionVector shape, const std::string &origID, SUMOReal length, int index, bool origNames, const std::string &oppositeID, const NBNode *node=0)
Writes a lane (<lane ...) of an edge.
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:172
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:153
A list of positions.
static const SUMOReal UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:249
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
SUMOReal getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:2961
static void writeEdge(OutputDevice &into, const NBEdge &e, bool noNames, bool origNames)
Writes an edge (<edge ...)
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:480
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
SUMOReal contPos
custom position for internal junction on this connection
Definition: NBEdge.h:193
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector
#define POSITION_EPS
Definition: config.h:187
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:518
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
Definition: NBEdgeCont.cpp:988
static void writePositionLong(const Position &pos, OutputDevice &dev)
Writes the given position to device in long format (one attribute per dimension)
Definition: NWFrame.cpp:157
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
static void normaliseSum(std::vector< T > &v, T msum=1.0)
Definition: VectorHelper.h:58
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:1555
std::string origID
An original ID, if given.
Definition: NBEdge.h:147
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1722
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:229
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:577
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.
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:150
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges.
Definition: NBNode.h:240
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:803
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:161
Instance responsible for building networks.
Definition: NBNetBuilder.h:112
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node.
Definition: NBNode.h:318
int tlLinkNo
the traffic light index of this crossing (if controlled)
Definition: NBNode.h:153
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
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:247
const std::vector< NBEdge * > & getSinkEdges() const
Returns the sinks.
Definition: NBDistrict.h:214
A definition of a pedestrian walking area.
Definition: NBNode.h:160
A storage for options typed value containers)
Definition: OptionsCont.h:99
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:265
This is an uncontrolled, major link, may pass.
void sortOutgoingConnectionsByIndex()
sorts the outgoing connections by their from-lane-index and their to-lane-index
Definition: NBEdge.cpp:1041
NBTrafficLightLogicCont & getTLLogicCont()
Returns the traffic light logics container.
Definition: NBNetBuilder.h:177
The abstract direction of a link.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
Represents a single node (junction) during network building.
Definition: NBNode.h:74
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:188
A definition of a pedestrian crossing.
Definition: NBNode.h:132
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition: NBNode.h:662
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:213
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
Definition: NBNode.h:189
static void writeJunction(OutputDevice &into, const NBNode &n, const bool checkLaneFoes)
Writes a junction (<junction ...)
bool isMacroscopicConnector() const
Returns whether this edge was marked as a macroscopic connector.
Definition: NBEdge.h:892
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:409
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
std::string getInternalLaneID() const
get ID of internal lnae
Definition: NBEdge.cpp:82
SUMOReal getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:472
bool haveVia
check if Connection have a Via
Definition: NBEdge.h:211
NBDistrictCont & getDistrictCont()
Returns the districts container.
Definition: NBNetBuilder.h:185
static const std::string MAJOR_VERSION
The version number for written files.
Definition: NWFrame.h:69
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:416
static std::string writeSUMOTime(SUMOTime time)
writes a SUMOTime as int if possible, otherwise as a float
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void lf()
writes a line feed if applicable
Definition: OutputDevice.h:235
const SVCPermissions SVC_UNSPECIFIED
SUMOReal width
This lane&#39;s width.
Definition: NBEdge.h:144
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:173
void writeTypes(OutputDevice &into) const
writes all types a s XML
Definition: NBTypeCont.cpp:131
The link has no direction (is a dead end link)
SUMOReal visibility
custom foe visiblity for connection
Definition: NBEdge.h:196