Eclipse SUMO - Simulation of Urban MObility
NBEdgeCont.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-2019 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 /****************************************************************************/
17 // Storage for edges, including some functionality operating on multiple edges
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <vector>
27 #include <string>
28 #include <cassert>
29 #include <algorithm>
30 #include <cmath>
31 #include <utils/geom/Boundary.h>
32 #include <utils/geom/GeomHelper.h>
35 #include <utils/common/ToString.h>
43 #include "NBNetBuilder.h"
44 #include "NBEdgeCont.h"
45 #include "NBNodeCont.h"
46 #include "NBHelpers.h"
47 #include "NBCont.h"
49 #include "NBDistrictCont.h"
50 #include "NBTypeCont.h"
51 
52 //#define DEBUG_GUESS_ROUNDABOUT
53 #define DEBUG_EDGE_ID "301241681#2"
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
59  myTypeCont(tc),
60  myEdgesSplit(0),
61  myVehicleClasses2Keep(0),
62  myVehicleClasses2Remove(0),
63  myNeedGeoTransformedPruningBoundary(false) {
64 }
65 
66 
68  clear();
69 }
70 
71 
72 void
74  // set edges dismiss/accept options
75  myEdgesMinSpeed = oc.getFloat("keep-edges.min-speed");
76  myRemoveEdgesAfterJoining = oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload");
77  // we possibly have to load the edges to keep/remove
78  if (oc.isSet("keep-edges.input-file")) {
79  NBHelpers::loadEdgesFromFile(oc.getString("keep-edges.input-file"), myEdges2Keep);
80  }
81  if (oc.isSet("remove-edges.input-file")) {
82  NBHelpers::loadEdgesFromFile(oc.getString("remove-edges.input-file"), myEdges2Remove);
83  }
84  if (oc.isSet("keep-edges.explicit")) {
85  const std::vector<std::string> edges = oc.getStringVector("keep-edges.explicit");
86  myEdges2Keep.insert(edges.begin(), edges.end());
87  }
88  if (oc.isSet("remove-edges.explicit")) {
89  const std::vector<std::string> edges = oc.getStringVector("remove-edges.explicit");
90  myEdges2Remove.insert(edges.begin(), edges.end());
91  }
92  if (oc.exists("keep-edges.by-vclass") && oc.isSet("keep-edges.by-vclass")) {
93  myVehicleClasses2Keep = parseVehicleClasses(oc.getStringVector("keep-edges.by-vclass"));
94  }
95  if (oc.exists("remove-edges.by-vclass") && oc.isSet("remove-edges.by-vclass")) {
96  myVehicleClasses2Remove = parseVehicleClasses(oc.getStringVector("remove-edges.by-vclass"));
97  }
98  if (oc.exists("keep-edges.by-type") && oc.isSet("keep-edges.by-type")) {
99  const std::vector<std::string> types = oc.getStringVector("keep-edges.by-type");
100  myTypes2Keep.insert(types.begin(), types.end());
101  }
102  if (oc.exists("remove-edges.by-type") && oc.isSet("remove-edges.by-type")) {
103  const std::vector<std::string> types = oc.getStringVector("remove-edges.by-type");
104  myTypes2Remove.insert(types.begin(), types.end());
105  }
106 
107  if (oc.isSet("keep-edges.in-boundary") || oc.isSet("keep-edges.in-geo-boundary")) {
108  std::vector<std::string> polyS = oc.getStringVector(oc.isSet("keep-edges.in-boundary") ?
109  "keep-edges.in-boundary" : "keep-edges.in-geo-boundary");
110  // !!! throw something if length<4 || length%2!=0?
111  std::vector<double> poly;
112  for (std::vector<std::string>::iterator i = polyS.begin(); i != polyS.end(); ++i) {
113  poly.push_back(StringUtils::toDouble((*i))); // !!! may throw something anyhow...
114  }
115  if (poly.size() < 4) {
116  throw ProcessError("Invalid boundary: need at least 2 coordinates");
117  } else if (poly.size() % 2 != 0) {
118  throw ProcessError("Invalid boundary: malformed coordinate");
119  } else if (poly.size() == 4) {
120  // prunning boundary (box)
121  myPruningBoundary.push_back(Position(poly[0], poly[1]));
122  myPruningBoundary.push_back(Position(poly[2], poly[1]));
123  myPruningBoundary.push_back(Position(poly[2], poly[3]));
124  myPruningBoundary.push_back(Position(poly[0], poly[3]));
125  } else {
126  for (std::vector<double>::iterator j = poly.begin(); j != poly.end();) {
127  double x = *j++;
128  double y = *j++;
129  myPruningBoundary.push_back(Position(x, y));
130  }
131  }
132  myNeedGeoTransformedPruningBoundary = oc.isSet("keep-edges.in-geo-boundary");
133  }
134 }
135 
136 
137 void
139  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
140  delete ((*i).second);
141  }
142  myEdges.clear();
143  for (EdgeCont::iterator i = myExtractedEdges.begin(); i != myExtractedEdges.end(); i++) {
144  delete ((*i).second);
145  }
146  myExtractedEdges.clear();
147 }
148 
149 
150 
151 // ----- edge access methods
152 bool
153 NBEdgeCont::insert(NBEdge* edge, bool ignorePrunning) {
154  if (myEdges.count(edge->getID()) != 0) {
155  return false;
156  }
157  if (!ignorePrunning && ignoreFilterMatch(edge)) {
158  edge->getFromNode()->removeEdge(edge);
159  edge->getToNode()->removeEdge(edge);
160  myIgnoredEdges.insert(edge->getID());
161  delete edge;
162  } else {
164  if (oc.exists("dismiss-vclasses") && oc.getBool("dismiss-vclasses")) {
166  }
167  myEdges[edge->getID()] = edge;
168  }
169  return true;
170 }
171 
172 
173 bool
175  // remove edges which allow a speed below a set one (set using "keep-edges.min-speed")
176  if (edge->getSpeed() < myEdgesMinSpeed) {
177  return true;
178  }
179  // check whether the edge is a named edge to keep
180  if (!myRemoveEdgesAfterJoining && myEdges2Keep.size() != 0) {
181  if (myEdges2Keep.count(edge->getID()) == 0) {
182  // explicit whitelisting may be combined additively with other filters
184  && myTypes2Keep.size() == 0 && myTypes2Remove.size() == 0
185  && myPruningBoundary.size() == 0) {
186  return true;
187  }
188  } else {
189  // explicit whitelisting overrides other filters
190  return false;
191  }
192  }
193  // check whether the edge is a named edge to remove
194  if (myEdges2Remove.size() != 0) {
195  if (myEdges2Remove.count(edge->getID()) != 0) {
196  return true;
197  }
198  }
199  // check whether the edge shall be removed because it does not allow any of the wished classes
200  if (myVehicleClasses2Keep != 0 && (myVehicleClasses2Keep & edge->getPermissions()) == 0) {
201  return true;
202  }
203  // check whether the edge shall be removed due to allowing unwished classes only
205  return true;
206  }
207  // check whether the edge shall be removed because it does not have one of the requested types
208  if (myTypes2Keep.size() != 0) {
209  if (myTypes2Keep.count(edge->getTypeID()) == 0) {
210  return true;
211  }
212  }
213  // check whether the edge shall be removed because it has one of the forbidden types
214  if (myTypes2Remove.size() != 0) {
215  if (myTypes2Remove.count(edge->getTypeID()) > 0) {
216  return true;
217  }
218  }
219  // check whether the edge is within the pruning boundary
220  if (myPruningBoundary.size() != 0) {
222  if (GeoConvHelper::getProcessing().usingGeoProjection()) {
224  } else if (GeoConvHelper::getLoaded().usingGeoProjection()) {
225  // XXX what if input file with different projections are loaded?
226  for (int i = 0; i < (int) myPruningBoundary.size(); i++) {
228  }
229  } else {
230  WRITE_ERROR("Cannot prune edges using a geo-boundary because no projection has been loaded");
231  }
233  }
235  return true;
236  }
237  }
239  return true;
240  }
241  return false;
242 }
243 
244 
245 NBEdge*
246 NBEdgeCont::retrieve(const std::string& id, bool retrieveExtracted) const {
247  EdgeCont::const_iterator i = myEdges.find(id);
248  if (i == myEdges.end()) {
249  if (retrieveExtracted) {
250  i = myExtractedEdges.find(id);
251  if (i == myExtractedEdges.end()) {
252  return nullptr;
253  }
254  } else {
255  return nullptr;
256  }
257  }
258  return (*i).second;
259 }
260 
261 // FIXME: This can't work
262 /*
263 NBEdge*
264 NBEdgeCont::retrievePossiblySplit(const std::string& id, bool downstream) const {
265  NBEdge* edge = retrieve(id);
266  if (edge == 0) {
267  return 0;
268  }
269  const EdgeVector* candidates = downstream ? &edge->getToNode()->getOutgoingEdges() : &edge->getFromNode()->getIncomingEdges();
270  while (candidates->size() == 1) {
271  const std::string& nextID = candidates->front()->getID();
272  if (nextID.find(id) != 0 || nextID.size() <= id.size() + 1 || (nextID[id.size()] != '.' && nextID[id.size()] != '-')) {
273  break;
274  }
275  edge = candidates->front();
276  candidates = downstream ? &edge->getToNode()->getOutgoingEdges() : &edge->getFromNode()->getIncomingEdges();
277  }
278  return edge;
279 }*/
280 
281 NBEdge*
282 NBEdgeCont::retrievePossiblySplit(const std::string& id, bool downstream) const {
283  NBEdge* edge = retrieve(id);
284  if (edge != nullptr) {
285  return edge;
286  }
287  // NOTE: (TODO) for multiply split edges (e.g. 15[0][0]) one could try recursion
288  if ((retrieve(id + "[0]") != nullptr) && (retrieve(id + "[1]") != nullptr)) {
289  // Edge was split during the netbuilding process
290  if (downstream == true) {
291  return retrieve(id + "[1]");
292  } else {
293  return retrieve(id + "[0]");
294  }
295  }
296  return edge;
297 }
298 
299 
300 NBEdge*
301 NBEdgeCont::retrievePossiblySplit(const std::string& id, const std::string& hint, bool incoming) const {
302  // try to retrieve using the given name (iterative)
303  NBEdge* edge = retrieve(id);
304  if (edge != nullptr) {
305  return edge;
306  }
307  // now, we did not find it; we have to look over all possibilities
308  EdgeVector hints;
309  // check whether at least the hint was not splitted
310  NBEdge* hintedge = retrieve(hint);
311  if (hintedge == nullptr) {
312  hints = getGeneratedFrom(hint);
313  } else {
314  hints.push_back(hintedge);
315  }
316  EdgeVector candidates = getGeneratedFrom(id);
317  for (EdgeVector::iterator i = hints.begin(); i != hints.end(); i++) {
318  NBEdge* hintedge = (*i);
319  for (EdgeVector::iterator j = candidates.begin(); j != candidates.end(); j++) {
320  NBEdge* poss_searched = (*j);
321  NBNode* node = incoming
322  ? poss_searched->myTo : poss_searched->myFrom;
323  const EdgeVector& cont = incoming
324  ? node->getOutgoingEdges() : node->getIncomingEdges();
325  if (find(cont.begin(), cont.end(), hintedge) != cont.end()) {
326  return poss_searched;
327  }
328  }
329  }
330  return nullptr;
331 }
332 
333 
334 NBEdge*
335 NBEdgeCont::retrievePossiblySplit(const std::string& id, double pos) const {
336  // check whether the edge was not split, yet
337  NBEdge* edge = retrieve(id);
338  if (edge != nullptr) {
339  return edge;
340  }
341  int maxLength = 0;
342  std::string tid = id + "[";
343  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
344  if ((*i).first.find(tid) == 0) {
345  maxLength = MAX2(maxLength, (int)(*i).first.length());
346  }
347  }
348  // find the part of the edge which matches the position
349  double seen = 0;
350  std::vector<std::string> names;
351  names.push_back(id + "[1]");
352  names.push_back(id + "[0]");
353  while (names.size() > 0) {
354  // retrieve the first subelement (to follow)
355  std::string cid = names.back();
356  names.pop_back();
357  edge = retrieve(cid);
358  // The edge was splitted; check its subparts within the
359  // next step
360  if (edge == nullptr) {
361  if ((int)cid.length() + 3 < maxLength) {
362  names.push_back(cid + "[1]");
363  names.push_back(cid + "[0]");
364  }
365  }
366  // an edge with the name was found,
367  // check whether the position lies within it
368  else {
369  seen += edge->getLength();
370  if (seen >= pos) {
371  return edge;
372  }
373  }
374  }
375  return nullptr;
376 }
377 
378 
379 void
381  extract(dc, edge);
382  delete edge;
383 }
384 
385 
386 void
387 NBEdgeCont::extract(NBDistrictCont& dc, NBEdge* edge, bool remember) {
388  if (remember) {
389  myExtractedEdges[edge->getID()] = edge;
390  }
391  myEdges.erase(edge->getID());
392  edge->myFrom->removeEdge(edge);
393  edge->myTo->removeEdge(edge);
394  dc.removeFromSinksAndSources(edge);
395 }
396 
397 
398 void
399 NBEdgeCont::rename(NBEdge* edge, const std::string& newID) {
400  if (myEdges.count(newID) != 0) {
401  throw ProcessError("Attempt to rename edge using existing id '" + newID + "'");
402  }
403  myEdges.erase(edge->getID());
404  edge->setID(newID);
405  myEdges[newID] = edge;
406 }
407 
408 
409 // ----- explicit edge manipulation methods
410 
411 void
412 NBEdgeCont::processSplits(NBEdge* e, std::vector<Split> splits,
414  if (splits.size() == 0) {
415  return;
416  }
417  const std::string origID = e->getID();
418  std::vector<Split>::iterator i;
419  sort(splits.begin(), splits.end(), split_sorter());
420  int noLanesMax = e->getNumLanes();
421  // compute the node positions and sort the lanes
422  for (i = splits.begin(); i != splits.end(); ++i) {
423  sort((*i).lanes.begin(), (*i).lanes.end());
424  noLanesMax = MAX2(noLanesMax, (int)(*i).lanes.size());
425  }
426  // split the edge
427  std::vector<int> currLanes;
428  for (int l = 0; l < e->getNumLanes(); ++l) {
429  currLanes.push_back(l);
430  }
431  if (e->getNumLanes() != (int)splits.back().lanes.size()) {
432  // invalidate traffic light definitions loaded from a SUMO network
433  e->getToNode()->invalidateTLS(tlc, true, true);
434  // if the number of lanes changes the connections should be
435  // recomputed
436  e->invalidateConnections(true);
437  }
438 
439  std::string firstID = "";
440  double seen = 0;
441  for (i = splits.begin(); i != splits.end(); ++i) {
442  const Split& exp = *i;
443  assert(exp.lanes.size() != 0);
444  if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) {
445  nc.insert(exp.node);
446  nc.markAsSplit(exp.node);
447  // split the edge
448  std::string idBefore = exp.idBefore == "" ? e->getID() : exp.idBefore;
449  std::string idAfter = exp.idAfter == "" ? exp.nameID : exp.idAfter;
450  if (firstID == "") {
451  firstID = idBefore;
452  }
453  const bool ok = splitAt(dc, e, exp.pos - seen, exp.node,
454  idBefore, idAfter, e->getNumLanes(), (int) exp.lanes.size(), exp.speed);
455  if (!ok) {
456  WRITE_WARNING("Error on parsing a split (edge '" + origID + "').");
457  }
458  seen = exp.pos;
459  std::vector<int> newLanes = exp.lanes;
460  NBEdge* pe = retrieve(idBefore);
461  NBEdge* ne = retrieve(idAfter);
462  // reconnect lanes
463  pe->invalidateConnections(true);
464  // new on right
465  int rightMostP = currLanes[0];
466  int rightMostN = newLanes[0];
467  for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) {
468  pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
469  }
470  // new on left
471  int leftMostP = currLanes.back();
472  int leftMostN = newLanes.back();
473  for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) {
474  pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true);
475  }
476  // all other connected
477  for (int l = 0; l < noLanesMax; ++l) {
478  if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
479  continue;
480  }
481  if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
482  continue;
483  }
484  pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true);
485  }
486  // if there are edges at this node which are not connected
487  // we can assume that this split was attached to an
488  // existing node. Reset all connections to let the default
489  // algorithm recompute them
490  if (exp.node->getIncomingEdges().size() > 1 || exp.node->getOutgoingEdges().size() > 1) {
491  for (NBEdge* in : exp.node->getIncomingEdges()) {
492  in->invalidateConnections(true);
493  }
494  }
495  // move to next
496  e = ne;
497  currLanes = newLanes;
498  } else if (exp.pos == 0) {
499  const int laneCountDiff = e->getNumLanes() - (int)exp.lanes.size();
500  if (laneCountDiff < 0) {
501  e->incLaneNo(-laneCountDiff);
502  } else {
503  e->decLaneNo(laneCountDiff);
504  }
505  currLanes = exp.lanes;
506  // invalidate traffic light definition loaded from a SUMO network
507  // XXX it would be preferable to reconstruct the phase definitions heuristically
508  e->getFromNode()->invalidateTLS(tlc, true, true);
509  } else {
510  WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + origID + "').");
511  }
512  }
513  // patch lane offsets
514  e = retrieve(firstID);
515  if (splits.front().pos != 0) {
516  // add a dummy split at the beginning to ensure correct offset
517  Split start;
518  start.pos = 0;
519  for (int lane = 0; lane < (int)e->getNumLanes(); ++lane) {
520  start.lanes.push_back(lane);
521  }
522  start.offset = splits.front().offset;
523  start.offsetFactor = splits.front().offsetFactor;
524  splits.insert(splits.begin(), start);
525  }
526  i = splits.begin();
527  if (e != nullptr) {
528  for (; i != splits.end(); ++i) {
529  int maxLeft = (*i).lanes.back();
530  double offset = (*i).offset;
531  if (maxLeft < noLanesMax) {
533  offset += (*i).offsetFactor * SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft);
534  } else {
535  offset += (*i).offsetFactor * SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft);
536  }
537  }
538  int maxRight = (*i).lanes.front();
539  if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) {
540  offset -= (*i).offsetFactor * SUMO_const_halfLaneAndOffset * maxRight;
541  }
542  //std::cout << " processSplits " << origID << " splitOffset=" << (*i).offset << " offset=" << offset << "\n";
543  if (offset != 0) {
544  PositionVector g = e->getGeometry();
545  g.move2side(offset);
546  e->setGeometry(g);
547  }
548  if (e->getToNode()->getOutgoingEdges().size() != 0) {
549  e = e->getToNode()->getOutgoingEdges()[0];
550  }
551  }
552  }
553 }
554 
555 
556 bool
558  return splitAt(dc, edge, node, edge->getID() + "[0]", edge->getID() + "[1]",
559  (int) edge->myLanes.size(), (int) edge->myLanes.size());
560 }
561 
562 
563 bool
565  const std::string& firstEdgeName,
566  const std::string& secondEdgeName,
567  int noLanesFirstEdge, int noLanesSecondEdge,
568  const double speed,
569  const int changedLeft) {
570  double pos;
571  pos = edge->getGeometry().nearest_offset_to_point2D(node->getPosition());
572  if (pos <= 0) {
574  edge->myFrom->getPosition(), edge->myTo->getPosition(),
575  node->getPosition());
576  }
577  if (pos <= 0 || pos + POSITION_EPS > edge->getGeometry().length()) {
578  return false;
579  }
580  return splitAt(dc, edge, pos, node, firstEdgeName, secondEdgeName,
581  noLanesFirstEdge, noLanesSecondEdge, speed, changedLeft);
582 }
583 
584 
585 bool
587  NBEdge* edge, double pos, NBNode* node,
588  const std::string& firstEdgeName,
589  const std::string& secondEdgeName,
590  int noLanesFirstEdge, int noLanesSecondEdge,
591  const double speed,
592  const int changedLeft
593  ) {
594  // there must be at least some overlap between first and second edge
595  assert(changedLeft > -((int)noLanesFirstEdge));
596  assert(changedLeft < (int)noLanesSecondEdge);
597 
598  // build the new edges' geometries
599  std::pair<PositionVector, PositionVector> geoms =
600  edge->getGeometry().splitAt(pos);
601  // build and insert the edges
602  NBEdge* one = new NBEdge(firstEdgeName, edge->myFrom, node, edge, geoms.first, noLanesFirstEdge);
603  NBEdge* two = new NBEdge(secondEdgeName, node, edge->myTo, edge, geoms.second, noLanesSecondEdge);
604  if (OptionsCont::getOptions().getBool("output.original-names")) {
605  const std::string origID = edge->getLaneStruct(0).getParameter(SUMO_PARAM_ORIGID, edge->getID());
606  if (firstEdgeName != origID) {
607  one->setOrigID(origID);
608  }
609  if (secondEdgeName != origID) {
610  two->setOrigID(origID);
611  }
612  }
613  two->copyConnectionsFrom(edge);
614  if (speed != -1.) {
615  two->setSpeed(-1, speed);
616  }
617  // replace information about this edge within the nodes
618  edge->myFrom->replaceOutgoing(edge, one, 0);
619  edge->myTo->replaceIncoming(edge, two, 0);
620  // patch tls
621  std::set<NBTrafficLightDefinition*> fromTLS = edge->myFrom->getControllingTLS();
622  for (std::set<NBTrafficLightDefinition*>::iterator i = fromTLS.begin(); i != fromTLS.end(); ++i) {
623  (*i)->replaceRemoved(edge, -1, one, -1);
624  }
625  std::set<NBTrafficLightDefinition*> toTLS = edge->myTo->getControllingTLS();
626  for (std::set<NBTrafficLightDefinition*>::iterator i = toTLS.begin(); i != toTLS.end(); ++i) {
627  (*i)->replaceRemoved(edge, -1, two, -1);
628  }
629  // the edge is now occuring twice in both nodes...
630  // clean up
631  edge->myFrom->removeDoubleEdges();
632  edge->myTo->removeDoubleEdges();
633  // add connections from the first to the second edge
634  // there will be as many connections as there are lanes on the second edge
635  // by default lanes will be added / discontinued on the right side
636  // (appropriate for highway on-/off-ramps)
637  const int offset = (int)one->getNumLanes() - (int)two->getNumLanes() + changedLeft;
638  for (int i2 = 0; i2 < (int)two->getNumLanes(); i2++) {
639  const int i1 = MIN2(MAX2((int)0, i2 + offset), (int)one->getNumLanes());
640  if (!one->addLane2LaneConnection(i1, two, i2, NBEdge::L2L_COMPUTED)) {
641  throw ProcessError("Could not set connection!");
642  }
643  }
645  if (myEdges2Keep.count(edge->getID()) != 0) {
646  myEdges2Keep.insert(one->getID());
647  myEdges2Keep.insert(two->getID());
648  }
649  if (myEdges2Remove.count(edge->getID()) != 0) {
650  myEdges2Remove.insert(one->getID());
651  myEdges2Remove.insert(two->getID());
652  }
653  }
654  // erase the splitted edge
655  patchRoundabouts(edge, one, two, myRoundabouts);
656  patchRoundabouts(edge, one, two, myGuessedRoundabouts);
657  const std::string oldID = edge->getID();
658  erase(dc, edge);
659  if (!insert(one, true)) {
660  WRITE_ERROR("Could not insert edge '" + one->getID() + "' before split of edge '" + oldID + "'");
661  };
662  if (!insert(two, true)) {
663  WRITE_ERROR("Could not insert edge '" + two->getID() + "' after split of edge '" + oldID + "'");
664  }
665  myEdgesSplit++;
666  return true;
667 }
668 
669 
670 void
671 NBEdgeCont::patchRoundabouts(NBEdge* orig, NBEdge* part1, NBEdge* part2, std::set<EdgeSet>& roundabouts) {
672  std::set<EdgeSet> addLater;
673  for (std::set<EdgeSet>::iterator it = roundabouts.begin(); it != roundabouts.end(); ++it) {
674  EdgeSet roundaboutSet = *it;
675  if (roundaboutSet.count(orig) > 0) {
676  roundaboutSet.erase(orig);
677  roundaboutSet.insert(part1);
678  roundaboutSet.insert(part2);
679  }
680  addLater.insert(roundaboutSet);
681  }
682  roundabouts.clear();
683  roundabouts.insert(addLater.begin(), addLater.end());
684 }
685 
686 
687 // ----- container access methods
688 std::vector<std::string>
690  std::vector<std::string> ret;
691  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
692  ret.push_back((*i).first);
693  }
694  return ret;
695 }
696 
697 
698 // ----- Adapting the input
699 void
701  EdgeVector toRemove;
702  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
703  NBEdge* edge = (*i).second;
704  if (!myEdges2Keep.count(edge->getID())) {
705  edge->getFromNode()->removeEdge(edge);
706  edge->getToNode()->removeEdge(edge);
707  toRemove.push_back(edge);
708  }
709  }
710  for (EdgeVector::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
711  erase(dc, *j);
712  }
713 }
714 
715 
716 void
718  // make a copy of myEdges because splitting will modify it
719  EdgeCont edges = myEdges;
720  for (auto& item : edges) {
721  NBEdge* edge = item.second;
722  if (edge->getGeometry().size() < 3) {
723  continue;
724  }
725  PositionVector geom = edge->getGeometry();
726  const std::string id = edge->getID();
727  double offset = 0;
728  for (int i = 1; i < (int)geom.size() - 1; i++) {
729  offset += geom[i - 1].distanceTo(geom[i]);
730  std::string nodeID = id + "." + toString((int)offset);
731  if (!nc.insert(nodeID, geom[i])) {
732  WRITE_WARNING("Could not split geometry of edge '" + id + "' at index " + toString(i));
733  continue;
734  }
735  NBNode* node = nc.retrieve(nodeID);
736  splitAt(dc, edge, node, edge->getID(), nodeID, edge->getNumLanes(), edge->getNumLanes());
737  edge = retrieve(nodeID);
738  }
739  }
740 }
741 
742 
743 void
744 NBEdgeCont::reduceGeometries(const double minDist) {
745  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
746  (*i).second->reduceGeometry(minDist);
747  }
748 }
749 
750 
751 void
752 NBEdgeCont::checkGeometries(const double maxAngle, const double minRadius, bool fix, bool fixRailways, bool silent) {
753  if (maxAngle > 0 || minRadius > 0) {
754  for (auto& item : myEdges) {
755  if (isSidewalk(item.second->getPermissions()) || isForbidden(item.second->getPermissions())) {
756  continue;
757  }
758  item.second->checkGeometry(maxAngle, minRadius, fix || (fixRailways && isRailway(item.second->getPermissions())), silent);
759  }
760  }
761 }
762 
763 
764 // ----- processing methods
765 void
767  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); i++) {
768  (*i).second->clearControllingTLInformation();
769  }
770 }
771 
772 
773 void
775  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
776  (*i).second->sortOutgoingConnectionsByAngle();
777  }
778 }
779 
780 
781 void
782 NBEdgeCont::computeEdge2Edges(bool noLeftMovers) {
783  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
784  (*i).second->computeEdge2Edges(noLeftMovers);
785  }
786 }
787 
788 
789 void
791  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
792  (*i).second->computeLanes2Edges();
793  }
794 }
795 
796 
797 void
799  const bool fixOppositeLengths = OptionsCont::getOptions().getBool("opposites.guess.fix-lengths");
800  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
801  NBEdge* edge = i->second;
802  edge->recheckLanes();
803  // check opposites
804  if (edge->getNumLanes() > 0) {
805  const std::string& oppositeID = edge->getLanes().back().oppositeID;
806  if (oppositeID != "" && oppositeID != "-") {
807  NBEdge* oppEdge = retrieve(oppositeID.substr(0, oppositeID.rfind("_")));
808  if (oppEdge == nullptr || oppEdge->getLaneID(oppEdge->getNumLanes() - 1) != oppositeID) {
809  WRITE_WARNING("Removing unknown opposite lane '" + oppositeID + "' for edge '" + edge->getID() + "'.");
810  edge->getLaneStruct(edge->getNumLanes() - 1).oppositeID = "";
811  continue;
812  }
813  if (fabs(oppEdge->getLoadedLength() - edge->getLoadedLength()) > NUMERICAL_EPS) {
814  if (fixOppositeLengths) {
815  const double avgLength = 0.5 * (edge->getFinalLength() + oppEdge->getFinalLength());
816  WRITE_WARNING("Averaging edge lengths for lane '" + oppositeID + "' (length " + toString(oppEdge->getLoadedLength()) + ") and edge '" + edge->getID() + "' (length "
817  + toString(edge->getLoadedLength()) + ").");
818  edge->setLoadedLength(avgLength);
819  oppEdge->setLoadedLength(avgLength);
820  } else {
821  WRITE_ERROR("Opposite lane '" + oppositeID + "' (length " + toString(oppEdge->getLoadedLength()) + ") differs in length from edge '" + edge->getID() + "' (length "
822  + toString(edge->getLoadedLength()) + "). Set --opposites.guess.fix-lengths to fix this.");
823  edge->getLaneStruct(edge->getNumLanes() - 1).oppositeID = "";
824  continue;
825  }
826  }
827  if (oppEdge->getFromNode() != edge->getToNode() || oppEdge->getToNode() != edge->getFromNode()) {
828  WRITE_ERROR("Opposite lane '" + oppositeID + "' does not connect the same nodes as edge '" + edge->getID() + "'!");
829  edge->getLaneStruct(edge->getNumLanes() - 1).oppositeID = "";
830  }
831  }
832  }
833  }
834 }
835 
836 
837 void
838 NBEdgeCont::appendTurnarounds(bool noTLSControlled, bool onlyDeadends, bool noGeometryLike) {
839  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
840  (*i).second->appendTurnaround(noTLSControlled, onlyDeadends, noGeometryLike, true);
841  }
842 }
843 
844 
845 void
846 NBEdgeCont::appendTurnarounds(const std::set<std::string>& ids, bool noTLSControlled) {
847  for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); it++) {
848  myEdges[*it]->appendTurnaround(noTLSControlled, false, false, false);
849  }
850 }
851 
852 
853 void
855  std::set<std::string> stopEdgeIDs;
856  for (auto& stopItem : sc.getStops()) {
857  stopEdgeIDs.insert(stopItem.second->getEdgeId());
858  }
859  for (auto& item : myEdges) {
860  NBEdge* edge = item.second;
861  if (edge->isBidiRail()
862  && (stopEdgeIDs.count(item.first) > 0 ||
863  stopEdgeIDs.count(edge->getTurnDestination(true)->getID()) > 0)) {
864  NBEdge* to = edge->getTurnDestination(true);
865  assert(to != 0);
866  edge->setConnection(edge->getNumLanes() - 1,
867  to, to->getNumLanes() - 1, NBEdge::L2L_VALIDATED, false, false, true,
870  }
871  }
872 }
873 
874 void
875 NBEdgeCont::computeEdgeShapes(double smoothElevationThreshold) {
876  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
877  (*i).second->computeEdgeShape(smoothElevationThreshold);
878  }
879  // equalize length of opposite edges
880  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
881  NBEdge* edge = i->second;
882  const std::string& oppositeID = edge->getLanes().back().oppositeID;
883  if (oppositeID != "" && oppositeID != "-") {
884  NBEdge* oppEdge = retrieve(oppositeID.substr(0, oppositeID.rfind("_")));
885  if (oppEdge == nullptr || oppEdge->getLaneID(oppEdge->getNumLanes() - 1) != oppositeID) {
886  continue;
887  }
888  if (fabs(oppEdge->getLength() - edge->getLength()) > NUMERICAL_EPS) {
889  double avgLength = (oppEdge->getLength() + edge->getLength()) / 2;
890  edge->setAverageLengthWithOpposite(avgLength);
891  oppEdge->setAverageLengthWithOpposite(avgLength);
892  }
893  }
894  }
895 }
896 
897 
898 void
900  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
901  (*i).second->computeLaneShapes();
902  }
903 }
904 
905 
906 void
909  EdgeVector edges) {
910  // !!! Attention!
911  // No merging of the geometry to come is being done
912  // The connections are moved from one edge to another within
913  // the replacement where the edge is a node's incoming edge.
914 
915  // count the number of lanes, the speed and the id
916  int nolanes = 0;
917  double speed = 0;
918  int priority = 0;
919  std::string id;
920  sort(edges.begin(), edges.end(), NBContHelper::same_connection_edge_sorter());
921  // retrieve the connected nodes
922  NBEdge* tpledge = *(edges.begin());
923  NBNode* from = tpledge->getFromNode();
924  NBNode* to = tpledge->getToNode();
925  EdgeVector::const_iterator i;
926  for (i = edges.begin(); i != edges.end(); i++) {
927  // some assertions
928  assert((*i)->getFromNode() == from);
929  assert((*i)->getToNode() == to);
930  // ad the number of lanes the current edge has
931  nolanes += (*i)->getNumLanes();
932  // build the id
933  if (i != edges.begin()) {
934  id += "+";
935  }
936  id += (*i)->getID();
937  // compute the speed
938  speed += (*i)->getSpeed();
939  // build the priority
940  priority = MAX2(priority, (*i)->getPriority());
941  }
942  speed /= edges.size();
943  // build the new edge
944  NBEdge* newEdge = new NBEdge(id, from, to, "", speed, nolanes, priority,
946  tpledge->getStreetName(), tpledge->myLaneSpreadFunction);
947  // copy lane attributes
948  int laneIndex = 0;
949  for (i = edges.begin(); i != edges.end(); ++i) {
950  const std::vector<NBEdge::Lane>& lanes = (*i)->getLanes();
951  for (int j = 0; j < (int)lanes.size(); ++j) {
952  newEdge->setPermissions(lanes[j].permissions, laneIndex);
953  newEdge->setLaneWidth(laneIndex, lanes[j].width);
954  newEdge->setEndOffset(laneIndex, lanes[j].endOffset);
955  laneIndex++;
956  }
957  }
958  insert(newEdge, true);
959  // replace old edge by current within the nodes
960  // and delete the old
961  from->replaceOutgoing(edges, newEdge);
962  to->replaceIncoming(edges, newEdge);
963  // patch connections
964  // add edge2edge-information
965  for (i = edges.begin(); i != edges.end(); i++) {
966  EdgeVector ev = (*i)->getConnectedEdges();
967  for (EdgeVector::iterator j = ev.begin(); j != ev.end(); j++) {
968  newEdge->addEdge2EdgeConnection(*j);
969  }
970  }
971  // copy outgoing connections to the new edge
972  int currLane = 0;
973  for (i = edges.begin(); i != edges.end(); i++) {
974  newEdge->moveOutgoingConnectionsFrom(*i, currLane);
975  currLane += (*i)->getNumLanes();
976  }
977  // patch tl-information
978  currLane = 0;
979  for (i = edges.begin(); i != edges.end(); i++) {
980  int noLanes = (*i)->getNumLanes();
981  for (int j = 0; j < noLanes; j++, currLane++) {
982  // replace in traffic lights
983  tlc.replaceRemoved(*i, j, newEdge, currLane);
984  }
985  }
986  // delete joined edges
987  for (i = edges.begin(); i != edges.end(); i++) {
988  extract(dc, *i, true);
989  }
990 }
991 
992 
993 void
995  //@todo magic values
996  const double distanceThreshold = 7;
997  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
998  NBEdge* edge = i->second;
999  const int numLanes = edge->getNumLanes();
1000  if (numLanes > 0) {
1001  NBEdge::Lane& lastLane = edge->getLaneStruct(numLanes - 1);
1002  if (lastLane.oppositeID == "") {
1003  NBEdge* opposite = nullptr;
1004  //double minOppositeDist = std::numeric_limits<double>::max();
1005  for (EdgeVector::const_iterator j = edge->getToNode()->getOutgoingEdges().begin(); j != edge->getToNode()->getOutgoingEdges().end(); ++j) {
1006  if ((*j)->getToNode() == edge->getFromNode() && !(*j)->getLanes().empty()) {
1007  const double distance = VectorHelper<double>::maxValue(lastLane.shape.distances((*j)->getLanes().back().shape));
1008  if (distance < distanceThreshold) {
1009  //minOppositeDist = distance;
1010  opposite = *j;
1011  }
1012  }
1013  }
1014  if (opposite != nullptr) {
1015  lastLane.oppositeID = opposite->getLaneID(opposite->getNumLanes() - 1);
1016  }
1017  }
1018  }
1019  }
1020 }
1021 
1022 
1023 void
1025  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
1026  NBEdge* opposite = getOppositeByID(i->first);
1027  if (opposite != nullptr) {
1028  i->second->setLaneSpreadFunction(LANESPREAD_RIGHT);
1030  } else {
1031  i->second->setLaneSpreadFunction(LANESPREAD_CENTER);
1032  }
1033  }
1034 }
1035 
1036 
1037 NBEdge*
1038 NBEdgeCont::getOppositeByID(const std::string& edgeID) const {
1039  const std::string oppositeID = edgeID[0] == '-' ? edgeID.substr(1) : "-" + edgeID;
1040  EdgeCont::const_iterator it = myEdges.find(oppositeID);
1041  return it != myEdges.end() ? it->second : (NBEdge*)nullptr;
1042 }
1043 
1044 NBEdge*
1045 NBEdgeCont::getByID(const std::string& edgeID) const {
1046  EdgeCont::const_iterator it = myEdges.find(edgeID);
1047  return it != myEdges.end() ? it->second : (NBEdge*)nullptr;
1048 }
1049 
1050 // ----- other
1051 void
1052 NBEdgeCont::addPostProcessConnection(const std::string& from, int fromLane, const std::string& to, int toLane, bool mayDefinitelyPass,
1053  bool keepClear, double contPos, double visibility, double speed,
1054  const PositionVector& customShape, bool uncontrolled, bool warnOnly, SVCPermissions permissions) {
1055  myConnections[from].push_back(PostProcessConnection(from, fromLane, to, toLane, mayDefinitelyPass, keepClear, contPos, visibility, speed, customShape, uncontrolled, warnOnly, permissions));
1056 }
1057 
1058 bool
1059 NBEdgeCont::hasPostProcessConnection(const std::string& from, const std::string& to) {
1060  if (myConnections.count(from) == 0) {
1061  return false;
1062  } else {
1063  if (to == "") {
1064  // wildcard
1065  return true;
1066  }
1067  for (const auto& ppc : myConnections[from]) {
1068  if (ppc.to == to) {
1069  return true;
1070  }
1071  }
1072  return false;
1073  }
1074 }
1075 
1076 void
1078  const bool warnOnly = OptionsCont::getOptions().exists("ignore-errors.connections") && OptionsCont::getOptions().getBool("ignore-errors.connections");
1079  for (const auto& item : myConnections) {
1080  for (std::vector<PostProcessConnection>::const_iterator i = item.second.begin(); i != item.second.end(); ++i) {
1081  NBEdge* from = retrievePossiblySplit((*i).from, true);
1082  NBEdge* to = retrievePossiblySplit((*i).to, false);
1083  if (from == nullptr || to == nullptr ||
1084  !from->addLane2LaneConnection((*i).fromLane, to, (*i).toLane, NBEdge::L2L_USER, true, (*i).mayDefinitelyPass,
1085  (*i).keepClear, (*i).contPos, (*i).visibility, (*i).speed, (*i).customShape, (*i).uncontrolled)) {
1086  const std::string msg = "Could not insert connection between '" + (*i).from + "' and '" + (*i).to + "' after build.";
1087  if (warnOnly || (*i).warnOnly) {
1088  WRITE_WARNING(msg);
1089  } else {
1090  WRITE_ERROR(msg);
1091  }
1092  }
1093  }
1094  }
1095  // during loading we also kept some ambiguous connections in hope they might be valid after processing
1096  // we need to make sure that all invalid connections are removed now
1097  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); ++it) {
1098  NBEdge* edge = it->second;
1099  NBNode* to = edge->getToNode();
1100  // make a copy because we may delete connections
1101  std::vector<NBEdge::Connection> connections = edge->getConnections();
1102  for (std::vector<NBEdge::Connection>::iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
1103  NBEdge::Connection& c = *it_con;
1104  if (c.toEdge != nullptr && c.toEdge->getFromNode() != to) {
1105  WRITE_WARNING("Found and removed invalid connection from edge '" + edge->getID() +
1106  "' to edge '" + c.toEdge->getID() + "' via junction '" + to->getID() + "'.");
1107  edge->removeFromConnections(c.toEdge);
1108  }
1109  }
1110  }
1111 }
1112 
1113 
1114 EdgeVector
1115 NBEdgeCont::getGeneratedFrom(const std::string& id) const {
1116  int len = (int)id.length();
1117  EdgeVector ret;
1118  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
1119  std::string curr = (*i).first;
1120  // the next check makes it possibly faster - we don not have
1121  // to compare the names
1122  if ((int)curr.length() <= len) {
1123  continue;
1124  }
1125  // the name must be the same as the given id but something
1126  // beginning with a '[' must be appended to it
1127  if (curr.substr(0, len) == id && curr[len] == '[') {
1128  ret.push_back((*i).second);
1129  continue;
1130  }
1131  // ok, maybe the edge is a compound made during joining of edges
1132  std::string::size_type pos = curr.find(id);
1133  // surely not
1134  if (pos == std::string::npos) {
1135  continue;
1136  }
1137  // check leading char
1138  if (pos > 0) {
1139  if (curr[pos - 1] != ']' && curr[pos - 1] != '+') {
1140  // actually, this is another id
1141  continue;
1142  }
1143  }
1144  if (pos + id.length() < curr.length()) {
1145  if (curr[pos + id.length()] != '[' && curr[pos + id.length()] != '+') {
1146  // actually, this is another id
1147  continue;
1148  }
1149  }
1150  ret.push_back((*i).second);
1151  }
1152  return ret;
1153 }
1154 
1155 
1156 int
1158  myGuessedRoundabouts.clear();
1159  std::set<NBEdge*> loadedRoundaboutEdges;
1160  for (std::set<EdgeSet>::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
1161  loadedRoundaboutEdges.insert(it->begin(), it->end());
1162  }
1163  // step 1: keep only those edges which have no turnarounds and which are not
1164  // part of a loaded roundabout
1165  std::set<NBEdge*> candidates;
1167  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
1168  NBEdge* e = (*i).second;
1169  NBNode* const to = e->getToNode();
1170  if (e->getTurnDestination() == nullptr
1171  && to->getConnectionTo(e->getFromNode()) == nullptr
1172  && loadedRoundaboutEdges.count(e) == 0
1173  && (e->getPermissions() & valid) != 0) {
1174  candidates.insert(e);
1175  }
1176  }
1177 
1178  // step 2:
1179  std::set<NBEdge*> visited;
1180  for (std::set<NBEdge*>::const_iterator i = candidates.begin(); i != candidates.end(); ++i) {
1181  EdgeVector loopEdges;
1182  // start with a random edge (this doesn't have to be a roundabout edge)
1183  // loop over connected edges (using always the leftmost one)
1184  // and keep the list in loopEdges
1185  // continue until we loop back onto a loopEdges and extract the loop
1186  NBEdge* e = (*i);
1187  if (visited.count(e) > 0) {
1188  // already seen
1189  continue;
1190  }
1191  loopEdges.push_back(e);
1192  bool doLoop = true;
1193 #ifdef DEBUG_GUESS_ROUNDABOUT
1194  gDebugFlag1 = false;
1195 #endif
1196  do {
1197 #ifdef DEBUG_GUESS_ROUNDABOUT
1198  if (e->getID() == DEBUG_EDGE_ID || gDebugFlag1) {
1199  std::cout << " e=" << e->getID() << " loopEdges=" << toString(loopEdges) << "\n";
1200  gDebugFlag1 = true;
1201  }
1202 #endif
1203  visited.insert(e);
1204  const EdgeVector& edges = e->getToNode()->getEdges();
1206  doLoop = false;
1207 #ifdef DEBUG_GUESS_ROUNDABOUT
1208  if (gDebugFlag1) {
1209  std::cout << " rbl\n";
1210  }
1211  gDebugFlag1 = false;
1212 #endif
1213  break;
1214  }
1215  if (edges.size() < 2) {
1216  doLoop = false;
1217 #ifdef DEBUG_GUESS_ROUNDABOUT
1218  if (gDebugFlag1) {
1219  std::cout << " deadend\n";
1220  }
1221  gDebugFlag1 = false;
1222 #endif
1223  break;
1224  }
1225  if (e->getTurnDestination() != nullptr || e->getToNode()->getConnectionTo(e->getFromNode()) != nullptr) {
1226  // do not follow turn-arounds while in a (tentative) loop
1227  doLoop = false;
1228 #ifdef DEBUG_GUESS_ROUNDABOUT
1229  if (gDebugFlag1) {
1230  std::cout << " turn\n";
1231  }
1232  gDebugFlag1 = false;
1233 #endif
1234  break;
1235  }
1236  EdgeVector::const_iterator me = std::find(edges.begin(), edges.end(), e);
1237  NBContHelper::nextCW(edges, me);
1238  NBEdge* left = *me;
1239  while ((left->getPermissions() & valid) == 0 && left != e) {
1240  NBContHelper::nextCW(edges, me);
1241  left = *me;
1242  }
1243  if (left == e) {
1244  // no usable continuation edge found
1245  doLoop = false;
1246 #ifdef DEBUG_GUESS_ROUNDABOUT
1247  if (gDebugFlag1) {
1248  std::cout << " noContinuation\n";
1249  }
1250  gDebugFlag1 = false;
1251 #endif
1252  break;
1253  }
1254  NBContHelper::nextCW(edges, me);
1255  NBEdge* nextLeft = *me;
1256  double angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), left->getAngleAtNode(e->getToNode())));
1257  double nextAngle = nextLeft == e ? 180 : fabs(NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), nextLeft->getAngleAtNode(e->getToNode())));
1258 #ifdef DEBUG_GUESS_ROUNDABOUT
1259  if (gDebugFlag1) {
1260  std::cout << " angle=" << angle << " nextAngle=" << nextAngle << "\n";
1261  }
1262 #endif
1263  if (angle >= 120
1264  || (angle >= 90 &&
1265  // if the edges are long or the junction shape is small we should expect roundness (low angles)
1266  (MAX2(e->getLength(), left->getLength()) > 5
1267  || e->getLaneShape(0).back().distanceTo2D(left->getLaneShape(0).front()) < 10
1268  // there should be no straigher edge further left
1269  || (nextAngle < 45)
1270  ))) {
1271  // roundabouts do not have sharp turns (or they wouldn't be called 'round')
1272  // however, if the roundabout is very small then most of the roundness may be in the junction so the angle may be as high as 120
1273  doLoop = false;
1274 #ifdef DEBUG_GUESS_ROUNDABOUT
1275  if (gDebugFlag1) {
1276  std::cout << " angle=" << angle << "\n";
1277  }
1278  gDebugFlag1 = false;
1279 #endif
1280  break;
1281  }
1282  EdgeVector::const_iterator loopClosed = std::find(loopEdges.begin(), loopEdges.end(), left);
1283  const int loopSize = (int)(loopEdges.end() - loopClosed);
1284  if (loopSize > 0) {
1285  // loop found
1286  if (loopSize < 3) {
1287  doLoop = false; // need at least 3 edges for a roundabout
1288  } else if (loopSize < (int)loopEdges.size()) {
1289  // remove initial edges not belonging to the loop
1290  EdgeVector(loopEdges.begin() + (loopEdges.size() - loopSize), loopEdges.end()).swap(loopEdges);
1291  }
1292  // count attachments to the outside. need at least 3 or a roundabout doesn't make much sense
1293  int attachments = 0;
1294  for (EdgeVector::const_iterator j = loopEdges.begin(); j != loopEdges.end(); ++j) {
1295  if ((*j)->getToNode()->getEdges().size() > 2) {
1296  attachments++;
1297  }
1298  }
1299  if (attachments < 3) {
1300  doLoop = false;
1301 #ifdef DEBUG_GUESS_ROUNDABOUT
1302  if (gDebugFlag1) {
1303  std::cout << " attachments=" << attachments << "\n";
1304  }
1305  gDebugFlag1 = false;
1306 #endif
1307  }
1308  break;
1309  }
1310  if (visited.count(left) > 0) {
1311  doLoop = false;
1312  } else {
1313  // keep going
1314  loopEdges.push_back(left);
1315  e = left;
1316  }
1317  } while (doLoop);
1318 #ifdef DEBUG_GUESS_ROUNDABOUT
1319  gDebugFlag1 = false;
1320 #endif
1321  if (doLoop) {
1322  // check form factor to avoid elongated shapes (circle: 1, square: ~0.79)
1323  if (formFactor(loopEdges) > 0.6) {
1324  // collected edges are marked in markRoundabouts
1325  myGuessedRoundabouts.insert(EdgeSet(loopEdges.begin(), loopEdges.end()));
1326  }
1327  }
1328  }
1329  return (int)myGuessedRoundabouts.size();
1330 }
1331 
1332 
1333 double
1335  PositionVector points;
1336  for (EdgeVector::const_iterator it = loopEdges.begin(); it != loopEdges.end(); ++it) {
1337  points.append((*it)->getGeometry());
1338  }
1339  double circumference = points.length2D();
1340  return 4 * M_PI * points.area() / (circumference * circumference);
1341 }
1342 
1343 
1344 const std::set<EdgeSet>
1346  std::set<EdgeSet> result = myRoundabouts;
1347  result.insert(myGuessedRoundabouts.begin(), myGuessedRoundabouts.end());
1348  return result;
1349 }
1350 
1351 
1352 void
1354  if (roundabout.size() > 0) {
1355  if (find(myRoundabouts.begin(), myRoundabouts.end(), roundabout) != myRoundabouts.end()) {
1356  WRITE_WARNING("Ignoring duplicate roundabout: " + toString(roundabout));
1357  } else {
1358  myRoundabouts.insert(roundabout);
1359  }
1360  }
1361 }
1362 
1363 void
1365  for (auto it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
1366  for (NBEdge* e : *it) {
1367  if (e->getToNode() == node) {
1368  myRoundabouts.erase(it);
1369  return;
1370  }
1371  }
1372  }
1373 }
1374 
1375 
1376 void
1378  for (const EdgeSet& roundaboutSet : getRoundabouts()) {
1379  for (NBEdge* const edge : roundaboutSet) {
1380  // disable turnarounds on incoming edges
1381  NBNode* const node = edge->getToNode();
1382  for (NBEdge* const inEdge : node->getIncomingEdges()) {
1383  if (roundaboutSet.count(inEdge) > 0) {
1384  continue;
1385  }
1386  if (inEdge->getStep() >= NBEdge::EdgeBuildingStep::LANES2LANES_USER) {
1387  continue;
1388  }
1389  if (inEdge->getTurnDestination() != nullptr) {
1390  inEdge->removeFromConnections(inEdge->getTurnDestination(), -1);
1391  }
1392  }
1393  // let the connections to succeeding roundabout edge have a higher priority
1394  edge->setJunctionPriority(node, NBEdge::ROUNDABOUT);
1395  edge->setJunctionPriority(edge->getFromNode(), NBEdge::ROUNDABOUT);
1396  node->setRoundabout();
1397  }
1398  }
1399 }
1400 
1401 
1402 void
1404  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
1405  NBEdge* e = i->second;
1406  const double offset = MAX2(0., e->getLength() - 3);
1407  if (e->getToNode()->isSimpleContinuation(false)) {
1408  // not a "real" junction?
1409  continue;
1410  }
1411  const SumoXMLNodeType nodeType = e->getToNode()->getType();
1412  switch (nodeType) {
1413  case NODETYPE_PRIORITY:
1414  // yield or major?
1415  if (e->getJunctionPriority(e->getToNode()) > 0) {
1417  } else {
1418  e->addSign(NBSign(NBSign::SIGN_TYPE_YIELD, offset));
1419  }
1420  break;
1422  // yield or major?
1423  if (e->getJunctionPriority(e->getToNode()) > 0) {
1425  } else {
1426  e->addSign(NBSign(NBSign::SIGN_TYPE_STOP, offset));
1427  }
1428  break;
1429  case NODETYPE_ALLWAY_STOP:
1431  break;
1434  break;
1435  default:
1436  break;
1437  }
1438  }
1439 }
1440 
1441 
1442 int
1443 NBEdgeCont::guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string& excludeOpt) {
1444  int lanesCreated = 0;
1445  std::vector<std::string> edges;
1446  if (excludeOpt != "") {
1447  edges = OptionsCont::getOptions().getStringVector(excludeOpt);
1448  }
1449  std::set<std::string> exclude(edges.begin(), edges.end());
1450  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); it++) {
1451  NBEdge* edge = it->second;
1452  if (// not excluded
1453  exclude.count(edge->getID()) == 0
1454  // does not yet have a sidewalk
1455  && !edge->hasRestrictedLane(svc)
1456  && (
1457  // guess.from-permissions
1458  (fromPermissions && (edge->getPermissions() & svc) != 0)
1459  // guess from speed
1460  || (!fromPermissions && edge->getSpeed() > minSpeed && edge->getSpeed() <= maxSpeed)
1461  )) {
1462  edge->addRestrictedLane(width, svc);
1463  lanesCreated += 1;
1464  }
1465  }
1466  return lanesCreated;
1467 }
1468 
1469 
1470 int
1471 NBEdgeCont::remapIDs(bool numericaIDs, bool reservedIDs, const std::string& prefix, NBPTStopCont& sc) {
1472  std::vector<std::string> avoid = getAllNames();
1473  std::set<std::string> reserve;
1474  if (reservedIDs) {
1475  NBHelpers::loadPrefixedIDsFomFile(OptionsCont::getOptions().getString("reserved-ids"), "edge:", reserve);
1476  avoid.insert(avoid.end(), reserve.begin(), reserve.end());
1477  }
1478  IDSupplier idSupplier("", avoid);
1479  std::set<NBEdge*, ComparatorIdLess> toChange;
1480  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); it++) {
1481  if (numericaIDs) {
1482  try {
1483  StringUtils::toLong(it->first);
1484  } catch (NumberFormatException&) {
1485  toChange.insert(it->second);
1486  }
1487  }
1488  if (reservedIDs && reserve.count(it->first) > 0) {
1489  toChange.insert(it->second);
1490  }
1491  }
1492 
1493  std::map<std::string, std::vector<NBPTStop*> > stopsOnEdge;
1494  for (const auto& item : sc.getStops()) {
1495  stopsOnEdge[item.second->getEdgeId()].push_back(item.second);
1496  }
1497 
1498  const bool origNames = OptionsCont::getOptions().getBool("output.original-names");
1499  for (std::set<NBEdge*, ComparatorIdLess>::iterator it = toChange.begin(); it != toChange.end(); ++it) {
1500  NBEdge* edge = *it;
1501  const std::string origID = edge->getID();
1502  myEdges.erase(origID);
1503  if (origNames) {
1504  edge->setOrigID(origID);
1505  }
1506  edge->setID(idSupplier.getNext());
1507  myEdges[edge->getID()] = edge;
1508  for (NBPTStop* stop : stopsOnEdge[origID]) {
1509  stop->setEdgeId(prefix + edge->getID(), *this);
1510  }
1511  }
1512  if (prefix.empty()) {
1513  return (int)toChange.size();
1514  } else {
1515  int renamed = 0;
1516  // make a copy because we will modify the map
1517  auto oldEdges = myEdges;
1518  for (auto item : oldEdges) {
1519  if (!StringUtils::startsWith(item.first, prefix)) {
1520  rename(item.second, prefix + item.first);
1521  renamed++;
1522  }
1523  }
1524  return renamed;
1525  }
1526 }
1527 
1528 
1529 void
1530 NBEdgeCont::checkOverlap(double threshold, double zThreshold) const {
1531  for (EdgeCont::const_iterator it = myEdges.begin(); it != myEdges.end(); it++) {
1532  const NBEdge* e1 = it->second;
1533  Boundary b1 = e1->getGeometry().getBoxBoundary();
1534  b1.grow(e1->getTotalWidth());
1535  PositionVector outline1 = e1->getCCWBoundaryLine(*e1->getFromNode());
1536  outline1.append(e1->getCCWBoundaryLine(*e1->getToNode()));
1537  // check is symmetric. only check once per pair
1538  for (EdgeCont::const_iterator it2 = it; it2 != myEdges.end(); it2++) {
1539  const NBEdge* e2 = it2->second;
1540  if (e1 == e2) {
1541  continue;
1542  }
1543  Boundary b2 = e2->getGeometry().getBoxBoundary();
1544  b2.grow(e2->getTotalWidth());
1545  if (b1.overlapsWith(b2)) {
1546  PositionVector outline2 = e2->getCCWBoundaryLine(*e2->getFromNode());
1547  outline2.append(e2->getCCWBoundaryLine(*e2->getToNode()));
1548  const double overlap = outline1.getOverlapWith(outline2, zThreshold);
1549  if (overlap > threshold) {
1550  WRITE_WARNING("Edge '" + e1->getID() + "' overlaps with edge '" + e2->getID() + "' by " + toString(overlap) + ".");
1551  }
1552  }
1553  }
1554  }
1555 }
1556 
1557 
1558 void
1559 NBEdgeCont::checkGrade(double threshold) const {
1560  for (EdgeCont::const_iterator it = myEdges.begin(); it != myEdges.end(); it++) {
1561  const NBEdge* edge = it->second;
1562  for (int i = 0; i < (int)edge->getNumLanes(); i++) {
1563  double maxJump = 0;
1564  const double grade = edge->getLaneShape(i).getMaxGrade(maxJump);
1565  if (maxJump > 0.01) {
1566  WRITE_WARNING("Edge '" + edge->getID() + "' has a vertical jump of " + toString(maxJump) + "m.");
1567  } else if (grade > threshold) {
1568  WRITE_WARNING("Edge '" + edge->getID() + "' has a grade of " + toString(grade * 100) + "%.");
1569  break;
1570  }
1571  }
1572  const std::vector<NBEdge::Connection>& connections = edge->getConnections();
1573  for (std::vector<NBEdge::Connection>::const_iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
1574  const NBEdge::Connection& c = *it_con;
1575  double maxJump = 0;
1576  const double grade = MAX2(c.shape.getMaxGrade(maxJump), c.viaShape.getMaxGrade(maxJump));
1577  if (maxJump > 0.01) {
1578  WRITE_WARNING("Connection '" + c.getDescription(edge) + "' has a vertical jump of " + toString(maxJump) + "m.");
1579  } else if (grade > threshold) {
1580  WRITE_WARNING("Connection '" + c.getDescription(edge) + "' has a grade of " + toString(grade * 100) + "%.");
1581  break;
1582  }
1583  }
1584  }
1585 }
1586 
1587 int
1589  int affectedEdges = 0;
1590  for (auto item : myEdges) {
1591  if (item.second->joinLanes(perms)) {
1592  affectedEdges++;
1593  }
1594  }
1595  return affectedEdges;
1596 }
1597 
1598 EdgeVector
1600  EdgeVector result;
1601  for (auto item : myEdges) {
1602  item.second->setNumericalID((int)result.size());
1603  result.push_back(item.second);
1604  }
1605  return result;
1606 }
1607 
1610  EdgeVector all = getAllEdges();
1611  return RouterEdgeVector(all.begin(), all.end());
1612 }
1613 
1614 /****************************************************************************/
NBEdgeCont::split_sorter
Sorts splits by their position (increasing)
Definition: NBEdgeCont.h:727
OptionsCont::isSet
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
Definition: OptionsCont.cpp:135
Boundary.h
NODETYPE_PRIORITY
@ NODETYPE_PRIORITY
Definition: SUMOXMLDefinitions.h:1061
NBEdge::UNSPECIFIED_OFFSET
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:318
SVC_PEDESTRIAN
@ SVC_PEDESTRIAN
pedestrian
Definition: SUMOVehicleClass.h:156
SUMOVehicleClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
Definition: SUMOVehicleClass.h:133
ToString.h
NBEdge::Connection::toEdge
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:212
NBEdgeCont::~NBEdgeCont
~NBEdgeCont()
Destructor.
Definition: NBEdgeCont.cpp:67
NBEdge::ROUNDABOUT
@ ROUNDABOUT
Definition: NBEdge.h:348
NBEdge::myTo
NBNode * myTo
Definition: NBEdge.h:1546
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
NBPTStopCont
Definition: NBPTStopCont.h:27
NBEdge::setOrigID
void setOrigID(const std::string origID)
set origID for all lanes
Definition: NBEdge.cpp:3703
NBEdgeCont::myTypeCont
NBTypeCont & myTypeCont
The network builder; used to obtain type information.
Definition: NBEdgeCont.h:611
NBEdgeCont::myIgnoredEdges
std::set< std::string > myIgnoredEdges
The ids of ignored edges.
Definition: NBEdgeCont.h:680
NBEdgeCont::Split::offsetFactor
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
Definition: NBEdgeCont.h:223
NBEdgeCont::retrieve
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:246
NBSign::SIGN_TYPE_RIGHT_BEFORE_LEFT
@ SIGN_TYPE_RIGHT_BEFORE_LEFT
Definition: NBSign.h:53
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
NBNode::replaceOutgoing
void replaceOutgoing(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
Definition: NBNode.cpp:1389
NBEdgeCont::myEdgesMinSpeed
double myEdgesMinSpeed
The minimum speed an edge may have in order to be kept (default: -1)
Definition: NBEdgeCont.h:689
NBEdgeCont::addPostProcessConnection
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass, bool keepClear, double contPos, double visibility, double speed, const PositionVector &customShape, bool uncontrolled, bool warnOnly, SVCPermissions permissions=SVC_UNSPECIFIED)
Adds a connection which could not be set during loading.
Definition: NBEdgeCont.cpp:1052
NBEdgeCont::myExtractedEdges
EdgeCont myExtractedEdges
The extracted nodes which are kept for reference.
Definition: NBEdgeCont.h:677
NBEdge::myLaneSpreadFunction
LaneSpreadFunction myLaneSpreadFunction
The information about how to spread the lanes.
Definition: NBEdge.h:1591
GeoConvHelper::x2cartesian_const
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
Definition: GeoConvHelper.cpp:417
NBTrafficLightLogicCont
A container for traffic light definitions and built programs.
Definition: NBTrafficLightLogicCont.h:57
NBSign::SIGN_TYPE_ALLWAY_STOP
@ SIGN_TYPE_ALLWAY_STOP
Definition: NBSign.h:50
NBEdgeCont::erase
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:380
NBEdge::hasRestrictedLane
bool hasRestrictedLane(SUMOVehicleClass vclass) const
returns whether any lane already allows the given vclass exclusively
Definition: NBEdge.cpp:3568
NBSign
A class representing a single street sign.
Definition: NBSign.h:43
NBEdgeCont::getOppositeByID
NBEdge * getOppositeByID(const std::string &edgeID) const
Returns the edge with negated id if it exists.
Definition: NBEdgeCont.cpp:1038
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
NBNodeCont::markAsSplit
void markAsSplit(const NBNode *node)
mark a node as being created form a split
Definition: NBNodeCont.h:316
OptionsCont.h
DEBUG_EDGE_ID
#define DEBUG_EDGE_ID
Definition: NBEdgeCont.cpp:53
NBNode::getConnectionTo
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
Definition: NBNode.cpp:2158
LANESPREAD_RIGHT
@ LANESPREAD_RIGHT
Definition: SUMOXMLDefinitions.h:1098
StringUtils::toDouble
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition: StringUtils.cpp:345
MsgHandler.h
EdgeVector
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
NBEdge::copyConnectionsFrom
void copyConnectionsFrom(NBEdge *src)
copy connections from antoher edge
Definition: NBEdge.cpp:1451
NBNodeCont::insert
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:78
NBEdgeCont::applyOptions
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
Definition: NBEdgeCont.cpp:73
NBEdgeCont::checkGrade
void checkGrade(double threshold) const
check whether edges are to steep
Definition: NBEdgeCont.cpp:1559
OptionsCont::getString
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:201
NBNode::getOutgoingEdges
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition: NBNode.h:260
GeoConvHelper::getProcessing
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:86
NBEdge::isBidiRail
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
Definition: NBEdge.cpp:691
NBEdge::addEdge2EdgeConnection
bool addEdge2EdgeConnection(NBEdge *dest)
Adds a connection to another edge.
Definition: NBEdge.cpp:960
NBEdgeCont::processSplits
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
Definition: NBEdgeCont.cpp:412
NBNetBuilder::transformCoordinates
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
Definition: NBNetBuilder.cpp:660
OptionsCont::exists
bool exists(const std::string &name) const
Returns the information whether the named option is known.
Definition: OptionsCont.cpp:129
NBEdgeCont.h
GeoConvHelper.h
NBEdgeCont::computeLaneShapes
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
Definition: NBEdgeCont.cpp:899
IDSupplier
Definition: IDSupplier.h:37
NBEdgeCont::myConnections
std::map< std::string, std::vector< PostProcessConnection > > myConnections
The list of connections to recheck.
Definition: NBEdgeCont.h:667
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:222
NBEdgeCont::patchRoundabouts
void patchRoundabouts(NBEdge *orig, NBEdge *part1, NBEdge *part2, std::set< EdgeSet > &roundabouts)
fix roundabout information after splitting an edge
Definition: NBEdgeCont.cpp:671
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
NBNode::getType
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:272
NBEdgeCont::getByID
NBEdge * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
Definition: NBEdgeCont.cpp:1045
NBEdgeCont::insert
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:153
PositionVector::length
double length() const
Returns the length.
Definition: PositionVector.cpp:484
NBEdgeCont::Split::offset
double offset
lateral offset to edge geometry
Definition: NBEdgeCont.h:221
GeoConvHelper::getLoaded
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
Definition: GeoConvHelper.h:91
SUMO_const_laneWidthAndOffset
const double SUMO_const_laneWidthAndOffset
Definition: StdDefs.h:53
NBEdge::setPermissions
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition: NBEdge.cpp:3376
NBEdge::getPermissions
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3404
NBEdge::setLoadedLength
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:3419
NBEdge::setLaneSpreadFunction
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition: NBEdge.cpp:885
GeomHelper::nearest_offset_on_line_to_point2D
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
Definition: GeomHelper.cpp:89
NBEdgeCont::Split::speed
double speed
The speed after this change.
Definition: NBEdgeCont.h:211
NBEdgeCont::markRoundabouts
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
Definition: NBEdgeCont.cpp:1377
NBEdge::L2L_USER
@ L2L_USER
The connection was given by the user.
Definition: NBEdge.h:133
PositionVector
A list of positions.
Definition: PositionVector.h:45
SUMO_const_halfLaneAndOffset
const double SUMO_const_halfLaneAndOffset
Definition: StdDefs.h:54
NBTypeCont::knows
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:71
NBEdgeCont::myTypes2Remove
std::set< std::string > myTypes2Remove
Set of edges types which shall be removed.
Definition: NBEdgeCont.h:710
NBDistrictCont
A container for districts.
Definition: NBDistrictCont.h:52
LANESPREAD_CENTER
@ LANESPREAD_CENTER
Definition: SUMOXMLDefinitions.h:1099
NBEdgeCont::splitAt
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:557
NBEdgeCont::ignoreFilterMatch
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:174
RouterEdgeVector
std::vector< NBRouterEdge * > RouterEdgeVector
Definition: NBCont.h:42
NBEdgeCont::remapIDs
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix, NBPTStopCont &sc)
remap node IDs accoring to options –numerical-ids and –reserved-ids
Definition: NBEdgeCont.cpp:1471
PositionVector::getBoxBoundary
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
Definition: PositionVector.cpp:390
NBHelpers::relAngle
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
Definition: NBHelpers.cpp:46
NBNodeCont
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:59
SUMO_const_haltingSpeed
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
Parameterised::getParameter
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
Definition: Parameterised.cpp:72
NBEdge
The representation of a single edge during network building.
Definition: NBEdge.h:91
OptionsCont::getStringVector
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
Definition: OptionsCont.cpp:235
NBEdgeCont::myVehicleClasses2Keep
SVCPermissions myVehicleClasses2Keep
Set of vehicle types which must be allowed on edges in order to keep them.
Definition: NBEdgeCont.h:701
NBEdgeCont::getGeneratedFrom
EdgeVector getGeneratedFrom(const std::string &id) const
Returns the edges which have been built by splitting the edge of the given id.
Definition: NBEdgeCont.cpp:1115
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
parseVehicleClasses
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
Definition: SUMOVehicleClass.cpp:222
NBEdgeCont::joinSameNodeConnectingEdges
void joinSameNodeConnectingEdges(NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, EdgeVector edges)
Joins the given edges because they connect the same nodes.
Definition: NBEdgeCont.cpp:907
NBNode::getPosition
const Position & getPosition() const
Definition: NBNode.h:247
NBEdge::setEndOffset
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3300
NBEdge::dismissVehicleClassInformation
void dismissVehicleClassInformation()
dimiss vehicle class information
Definition: NBEdge.cpp:3430
PositionVector::nearest_offset_to_point2D
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Definition: PositionVector.cpp:817
NBEdge::invalidateConnections
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1336
NumberFormatException
Definition: UtilExceptions.h:95
NBContHelper::same_connection_edge_sorter
Definition: NBContHelper.h:330
NBHelpers::loadPrefixedIDsFomFile
static void loadPrefixedIDsFomFile(const std::string &file, const std::string prefix, std::set< std::string > &into)
Add prefixed ids defined in file.
Definition: NBHelpers.cpp:105
NODETYPE_ALLWAY_STOP
@ NODETYPE_ALLWAY_STOP
Definition: SUMOXMLDefinitions.h:1064
NBEdge::myFrom
NBNode * myFrom
The source and the destination node.
Definition: NBEdge.h:1546
NBEdgeCont::myEdges
EdgeCont myEdges
The instance of the dictionary (id->edge)
Definition: NBEdgeCont.h:674
NBEdgeCont::computeLanes2Edges
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
Definition: NBEdgeCont.cpp:790
NBEdge::getToNode
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:498
NBEdge::setConnection
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED)
Adds a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1029
NBEdge::Connection::viaShape
PositionVector viaShape
shape of via
Definition: NBEdge.h:263
NBEdge::decLaneNo
void decLaneNo(int by)
decrement lane
Definition: NBEdge.cpp:3181
NBEdgeCont::checkOverlap
void checkOverlap(double threshold, double zThreshold) const
check whether edges overlap
Definition: NBEdgeCont.cpp:1530
NBEdge::getGeometry
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:692
NBEdgeCont::myEdges2Remove
std::set< std::string > myEdges2Remove
Set of ids of edges which shall explicitly be removed.
Definition: NBEdgeCont.h:698
isForbidden
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
Definition: SUMOVehicleClass.cpp:375
NBEdgeCont::Split::node
NBNode * node
The new node that is created for this split.
Definition: NBEdgeCont.h:213
NBEdgeCont::generateStreetSigns
void generateStreetSigns()
assigns street signs to edges based on toNode types
Definition: NBEdgeCont.cpp:1403
SVCPermissions
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
Definition: SUMOVehicleClass.h:218
PositionVector::getOverlapWith
double getOverlapWith(const PositionVector &poly, double zThreshold) const
Returns the maximum overlaps between this and the given polygon (when not separated by at least zThre...
Definition: PositionVector.cpp:131
NODETYPE_PRIORITY_STOP
@ NODETYPE_PRIORITY_STOP
Definition: SUMOXMLDefinitions.h:1062
NBEdgeCont::hasPostProcessConnection
bool hasPostProcessConnection(const std::string &from, const std::string &to="")
Definition: NBEdgeCont.cpp:1059
NBNode::typeWasGuessed
bool typeWasGuessed() const
return whether a priority road turns at this node
Definition: NBNode.h:764
NBEdgeCont::EdgeCont
std::map< std::string, NBEdge * > EdgeCont
The type of the dictionary where an edge may be found by its id.
Definition: NBEdgeCont.h:671
NBEdge::UNSPECIFIED_CONTPOS
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:324
NBEdge::Connection::getDescription
std::string getDescription(const NBEdge *parent) const
get string describing this connection
Definition: NBEdge.cpp:87
NBEdgeCont::guessRoundabouts
int guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
Definition: NBEdgeCont.cpp:1157
SumoXMLNodeType
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
Definition: SUMOXMLDefinitions.h:1054
NBEdge::getLaneID
std::string getLaneID(int lane) const
get lane ID
Definition: NBEdge.cpp:3093
NBEdge::recheckLanes
bool recheckLanes()
recheck whether all lanes within the edge are all right and optimises the connections once again
Definition: NBEdge.cpp:2198
EdgeSet
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:49
NBTypeCont.h
SUMO_PARAM_ORIGID
const std::string SUMO_PARAM_ORIGID
NBEdge::Connection::shape
PositionVector shape
shape of Connection
Definition: NBEdge.h:251
NBEdge::moveOutgoingConnectionsFrom
void moveOutgoingConnectionsFrom(NBEdge *e, int laneOff)
move outgoing connection
Definition: NBEdge.cpp:2783
Boundary
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:41
NBEdgeCont::myTypes2Keep
std::set< std::string > myTypes2Keep
Set of edges types which shall be kept.
Definition: NBEdgeCont.h:707
NBEdgeCont::Split::lanes
std::vector< int > lanes
The lanes after this change.
Definition: NBEdgeCont.h:207
NBEdgeCont::recheckPostProcessConnections
void recheckPostProcessConnections()
Try to set any stored connections.
Definition: NBEdgeCont.cpp:1077
NBEdge::getNumLanes
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:477
NBNode::setRoundabout
void setRoundabout()
update the type of this node as a roundabout
Definition: NBNode.cpp:3061
OutputDevice.h
NBEdge::L2L_COMPUTED
@ L2L_COMPUTED
The connection was computed.
Definition: NBEdge.h:131
NBNetBuilder.h
NBEdgeCont::clear
void clear()
Deletes all edges.
Definition: NBEdgeCont.cpp:138
ProcessError
Definition: UtilExceptions.h:39
NBEdgeCont::retrievePossiblySplit
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:282
isRailway
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
Definition: SUMOVehicleClass.cpp:363
NBEdge::setSpeed
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3345
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
PositionVector::append
void append(const PositionVector &v, double sameThreshold=2.0)
Definition: PositionVector.cpp:696
NBEdge::getTotalWidth
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
Definition: NBEdge.cpp:3276
NBEdgeCont::myNeedGeoTransformedPruningBoundary
bool myNeedGeoTransformedPruningBoundary
whether a geo transform has been applied to the pruning boundary
Definition: NBEdgeCont.h:716
UtilExceptions.h
NBHelpers.h
NBEdgeCont::removeUnwishedEdges
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:700
NBEdgeCont::recheckLanes
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:798
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:89
NBTypeCont::getShallBeDiscarded
bool getShallBeDiscarded(const std::string &type) const
Returns the information whether edges of this type shall be discarded.
Definition: NBTypeCont.cpp:195
NBNode::getEdges
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition: NBNode.h:265
NBEdge::getLaneStruct
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1287
NBEdge::UNSPECIFIED_VISIBILITY_DISTANCE
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:327
StringUtils::startsWith
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
Definition: StringUtils.cpp:174
IDSupplier.h
NBEdgeCont::splitGeometry
void splitGeometry(NBDistrictCont &dc, NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:717
PositionVector::length2D
double length2D() const
Returns the length.
Definition: PositionVector.cpp:497
NBEdgeCont::appendTurnarounds
void appendTurnarounds(bool noTLSControlled, bool onlyDeadends, bool noGeometryLike)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:838
NBEdgeCont::myPruningBoundary
PositionVector myPruningBoundary
Boundary within which an edge must be located in order to be kept.
Definition: NBEdgeCont.h:713
NBEdge::removeFromConnections
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1266
NBEdge::L2L_VALIDATED
@ L2L_VALIDATED
The connection was computed and validated.
Definition: NBEdge.h:135
NBEdgeCont::Split::pos
double pos
The position of this change.
Definition: NBEdgeCont.h:209
NODETYPE_RIGHT_BEFORE_LEFT
@ NODETYPE_RIGHT_BEFORE_LEFT
Definition: SUMOXMLDefinitions.h:1063
NBNode::removeEdge
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
Definition: NBNode.cpp:1604
PositionVector::splitAt
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
Definition: PositionVector.cpp:552
NBEdgeCont::getAllEdges
EdgeVector getAllEdges() const
return all edges
Definition: NBEdgeCont.cpp:1599
NBNodeCont::retrieve
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:107
NBEdge::getLanes
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:656
NBEdge::getStreetName
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:600
NBEdgeCont::appendRailwayTurnarounds
void appendRailwayTurnarounds(const NBPTStopCont &sc)
Appends turnarounds to all bidiRail edges with stops.
Definition: NBEdgeCont.cpp:854
NBEdge::getLoadedLength
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:554
NBEdgeCont::getAllNames
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
Definition: NBEdgeCont.cpp:689
OptionsCont::getFloat
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Definition: OptionsCont.cpp:208
NBEdge::getLength
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:545
NBEdge::getLaneShape
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:879
NBNodeCont.h
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
PositionVector::getMaxGrade
double getMaxGrade(double &maxJump) const
Definition: PositionVector.cpp:1664
StringUtils.h
NBEdgeCont::sortOutgoingLanesConnections
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
Definition: NBEdgeCont.cpp:774
NBPTStopCont::getStops
const std::map< std::string, NBPTStop * > & getStops() const
Definition: NBPTStopCont.h:61
NBEdgeCont::reduceGeometries
void reduceGeometries(const double minDist)
Definition: NBEdgeCont.cpp:744
NBEdgeCont::myEdges2Keep
std::set< std::string > myEdges2Keep
Set of ids of edges which shall explicitly be kept.
Definition: NBEdgeCont.h:695
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
NBEdgeCont::rename
void rename(NBEdge *edge, const std::string &newID)
Renames the edge. Throws exception if newID already exists.
Definition: NBEdgeCont.cpp:399
NBEdge::getJunctionPriority
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
Definition: NBEdge.cpp:1816
NBEdge::setLaneWidth
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3239
NBTypeCont
A storage for available types of edges.
Definition: NBTypeCont.h:54
NBEdgeCont::myRoundabouts
std::set< EdgeSet > myRoundabouts
Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout)
Definition: NBEdgeCont.h:720
NBEdge::getSpeed
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:571
NBSign::SIGN_TYPE_STOP
@ SIGN_TYPE_STOP
Definition: NBSign.h:49
NBNode::getControllingTLS
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
Definition: NBNode.h:318
NBEdge::Lane
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:142
NBEdge::addSign
void addSign(NBSign sign)
add Sign
Definition: NBEdge.h:1319
SVCAll
const SVCPermissions SVCAll
all VClasses are allowed
Definition: SUMOVehicleClass.cpp:146
NBEdgeCont::PostProcessConnection
A structure representing a connection between two lanes.
Definition: NBEdgeCont.h:616
NBEdgeCont::NBEdgeCont
NBEdgeCont(NBTypeCont &tc)
Constructor.
Definition: NBEdgeCont.cpp:58
NBNode::getIncomingEdges
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition: NBNode.h:255
NBEdge::Lane::oppositeID
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:169
NBEdgeCont::guessSpecialLanes
int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string &excludeOpt)
add sidwalks to edges within the given limits or permissions and return the number of edges affected
Definition: NBEdgeCont.cpp:1443
PositionVector::distances
std::vector< double > distances(const PositionVector &s, bool perpendicular=false) const
distances of all my points to s and all of s points to myself
Definition: PositionVector.cpp:1239
NBDistrictCont.h
NBEdgeCont::extract
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
Definition: NBEdgeCont.cpp:387
NBSign::SIGN_TYPE_PRIORITY
@ SIGN_TYPE_PRIORITY
Definition: NBSign.h:52
NBEdgeCont::recheckLaneSpread
void recheckLaneSpread()
Rechecks whether the lane spread is proper.
Definition: NBEdgeCont.cpp:1024
NBEdgeCont::formFactor
static double formFactor(const EdgeVector &loopEdges)
compute the form factor for a loop of edges
Definition: NBEdgeCont.cpp:1334
NBEdge::myLanes
std::vector< Lane > myLanes
Lane information.
Definition: NBEdge.h:1608
IDSupplier::getNext
std::string getNext()
Returns the next id.
Definition: IDSupplier.cpp:51
NBEdgeCont::Split::idAfter
std::string idAfter
The id for the edge after the split.
Definition: NBEdgeCont.h:217
NBNode::isSimpleContinuation
bool isSimpleContinuation(bool checkLaneNumbers=true, bool checkWidth=false) const
check if node is a simple continuation
Definition: NBNode.cpp:471
NBEdge::UNSPECIFIED_WIDTH
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:315
NBNode::removeDoubleEdges
void removeDoubleEdges()
remove duble edges
Definition: NBNode.cpp:1493
NBEdgeCont::computeEdgeShapes
void computeEdgeShapes(double smoothElevationThreshold=-1)
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:875
NBEdgeCont::myEdgesSplit
int myEdgesSplit
the number of splits of edges during the building
Definition: NBEdgeCont.h:683
NBEdge::getFinalLength
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3682
NBEdge::getTypeID
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1074
NBContHelper::nextCW
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
Definition: NBContHelper.cpp:39
NBEdgeCont::joinLanes
int joinLanes(SVCPermissions perms)
join adjacent lanes with the given permissions
Definition: NBEdgeCont.cpp:1588
config.h
NBEdgeCont::addRoundabout
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
Definition: NBEdgeCont.cpp:1353
GeomHelper.h
gDebugFlag1
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
NBEdge::addRestrictedLane
void addRestrictedLane(double width, SUMOVehicleClass vclass)
add a lane of the given width, restricted to the given class and shift existing connections
Definition: NBEdge.cpp:3579
StringTokenizer.h
NBDistrictCont::removeFromSinksAndSources
void removeFromSinksAndSources(NBEdge *const e)
Removes the given edge from the lists of sources and sinks in all stored districts.
Definition: NBDistrictCont.cpp:97
VectorHelper::maxValue
static T maxValue(const std::vector< T > &v)
Definition: VectorHelper.h:89
Boundary::grow
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:300
NBEdgeCont::myVehicleClasses2Remove
SVCPermissions myVehicleClasses2Remove
Set of vehicle types which need not be supported (edges which allow ONLY these are removed)
Definition: NBEdgeCont.h:704
NBNode::invalidateTLS
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
Definition: NBNode.cpp:387
NBEdgeCont::removeRoundabout
void removeRoundabout(const NBNode *node)
remove roundabout that contains the given node
Definition: NBEdgeCont.cpp:1364
NBEdge::incLaneNo
void incLaneNo(int by)
increment lane
Definition: NBEdge.cpp:3150
StringUtils::toLong
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
Definition: StringUtils.cpp:297
NBEdge::Lane::shape
PositionVector shape
The lane's shape.
Definition: NBEdge.h:147
NBEdgeCont::guessOpposites
void guessOpposites()
Sets opposite lane information for geometrically close edges.
Definition: NBEdgeCont.cpp:994
NBEdgeCont::checkGeometries
void checkGeometries(const double maxAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
Definition: NBEdgeCont.cpp:752
NBNode
Represents a single node (junction) during network building.
Definition: NBNode.h:67
isSidewalk
bool isSidewalk(SVCPermissions permissions)
Returns whether an edge with the given permission is a sidewalk.
Definition: SUMOVehicleClass.cpp:381
NBTrafficLightLogicCont.h
NBEdgeCont::computeEdge2Edges
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:782
NBPTStop
The representation of a single pt stop.
Definition: NBPTStop.h:44
NBEdge::Connection
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:189
NBEdgeCont::myRemoveEdgesAfterJoining
bool myRemoveEdgesAfterJoining
Whether edges shall be joined first, then removed.
Definition: NBEdgeCont.h:692
PositionVector::area
double area() const
Returns the area (0 for non-closed)
Definition: PositionVector.cpp:510
NBEdgeCont::Split
A structure which describes changes of lane number or speed along the road.
Definition: NBEdgeCont.h:205
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
NBEdge::getAngleAtNode
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
Definition: NBEdge.cpp:1836
NBEdge::setAverageLengthWithOpposite
void setAverageLengthWithOpposite(double val)
patch average lane length in regard to the opposite edge
Definition: NBEdge.cpp:3424
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:283
NBEdgeCont::Split::idBefore
std::string idBefore
The id for the edge before the split.
Definition: NBEdgeCont.h:215
NBEdge::addLane2LaneConnection
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions=SVC_UNSPECIFIED)
Adds a connection between the specified this edge's lane and an approached one.
Definition: NBEdge.cpp:984
NBEdge::getConnections
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:934
NBEdge::getFromNode
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:491
NBEdgeCont::myGuessedRoundabouts
std::set< EdgeSet > myGuessedRoundabouts
Edges marked as belonging to a roundabout after guessing.
Definition: NBEdgeCont.h:722
NBEdgeCont::getRoundabouts
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
Definition: NBEdgeCont.cpp:1345
NBEdge::getCCWBoundaryLine
PositionVector getCCWBoundaryLine(const NBNode &n) const
get the outer boundary of this edge when going counter-clock-wise around the given node
Definition: NBEdge.cpp:2911
NBTrafficLightLogicCont::replaceRemoved
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces occurences of the removed edge/lane in all definitions by the given edge.
Definition: NBTrafficLightLogicCont.cpp:220
NBEdge::setGeometry
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Definition: NBEdge.cpp:582
PositionVector::move2side
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
Definition: PositionVector.cpp:1103
NBEdge::EdgeBuildingStep::LANES2LANES_USER
@ LANES2LANES_USER
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
NBCont.h
NBSign::SIGN_TYPE_YIELD
@ SIGN_TYPE_YIELD
Definition: NBSign.h:48
Named::setID
void setID(const std::string &newID)
resets the id
Definition: Named.h:84
NBEdgeCont::getAllRouterEdges
RouterEdgeVector getAllRouterEdges() const
Definition: NBEdgeCont.cpp:1609
NBEdge::getLaneSpreadFunction
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.h:777
NBNode::replaceIncoming
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
Definition: NBNode.cpp:1425
NBEdgeCont::Split::nameID
std::string nameID
the default node id
Definition: NBEdgeCont.h:219
NBHelpers::loadEdgesFromFile
static void loadEdgesFromFile(const std::string &file, std::set< std::string > &into)
Add edge ids defined in file (either ID or edge:ID per line) into the given set.
Definition: NBHelpers.cpp:87
Boundary::overlapsWith
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:181
NBEdge::getTurnDestination
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3084
NBEdgeCont::clearControllingTLInformation
void clearControllingTLInformation() const
Clears information about controlling traffic lights for all connenections of all edges.
Definition: NBEdgeCont.cpp:766
NBEdge::getID
const std::string & getID() const
Definition: NBEdge.h:1380