SUMO - Simulation of Urban MObility
NBEdgeCont.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Storage for edges, including some functionality operating on multiple edges
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <vector>
35 #include <string>
36 #include <cassert>
37 #include <algorithm>
38 #include <utils/geom/Boundary.h>
39 #include <utils/geom/GeomHelper.h>
42 #include <utils/common/ToString.h>
45 #include "NBNetBuilder.h"
46 #include "NBEdgeCont.h"
47 #include "NBNodeCont.h"
48 #include "NBHelpers.h"
49 #include "NBCont.h"
51 #include "NBDistrictCont.h"
52 #include <cmath>
53 #include "NBTypeCont.h"
57 
58 #ifdef CHECK_MEMORY_LEAKS
59 #include <foreign/nvwa/debug_new.h>
60 #endif // CHECK_MEMORY_LEAKS
61 
62 
63 // ===========================================================================
64 // method definitions
65 // ===========================================================================
67  myTypeCont(tc),
68  myEdgesSplit(0),
69  myVehicleClasses2Keep(0),
70  myVehicleClasses2Remove(0),
71  myNeedGeoTransformedPrunningBoundary(false) {
72 }
73 
74 
76  clear();
77 }
78 
79 
80 void
82  // set edges dismiss/accept options
83  myEdgesMinSpeed = oc.isSet("keep-edges.min-speed") ? oc.getFloat("keep-edges.min-speed") : -1;
84  myRemoveEdgesAfterJoining = oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload");
85  // we possibly have to load the edges to keep/remove
86  if (oc.isSet("keep-edges.input-file")) {
87  NBHelpers::loadEdgesFromFile(oc.getString("keep-edges.input-file"), myEdges2Keep);
88  }
89  if (oc.isSet("remove-edges.input-file")) {
90  NBHelpers::loadEdgesFromFile(oc.getString("remove-edges.input-file"), myEdges2Remove);
91  }
92  if (oc.isSet("keep-edges.explicit")) {
93  const std::vector<std::string> edges = oc.getStringVector("keep-edges.explicit");
94  myEdges2Keep.insert(edges.begin(), edges.end());
95  }
96  if (oc.isSet("remove-edges.explicit")) {
97  const std::vector<std::string> edges = oc.getStringVector("remove-edges.explicit");
98  myEdges2Remove.insert(edges.begin(), edges.end());
99  }
100  if (oc.exists("keep-edges.by-vclass") && oc.isSet("keep-edges.by-vclass")) {
101  myVehicleClasses2Keep = parseVehicleClasses(oc.getStringVector("keep-edges.by-vclass"));
102  }
103  if (oc.exists("remove-edges.by-vclass") && oc.isSet("remove-edges.by-vclass")) {
104  myVehicleClasses2Remove = parseVehicleClasses(oc.getStringVector("remove-edges.by-vclass"));
105  }
106  if (oc.exists("keep-edges.by-type") && oc.isSet("keep-edges.by-type")) {
107  const std::vector<std::string> types = oc.getStringVector("keep-edges.by-type");
108  myTypes2Keep.insert(types.begin(), types.end());
109  }
110  if (oc.exists("remove-edges.by-type") && oc.isSet("remove-edges.by-type")) {
111  const std::vector<std::string> types = oc.getStringVector("remove-edges.by-type");
112  myTypes2Remove.insert(types.begin(), types.end());
113  }
114 
115  if (oc.isSet("keep-edges.in-boundary") || oc.isSet("keep-edges.in-geo-boundary")) {
116  std::vector<std::string> polyS = oc.getStringVector(oc.isSet("keep-edges.in-boundary") ?
117  "keep-edges.in-boundary" : "keep-edges.in-geo-boundary");
118  // !!! throw something if length<4 || length%2!=0?
119  std::vector<SUMOReal> poly;
120  for (std::vector<std::string>::iterator i = polyS.begin(); i != polyS.end(); ++i) {
121  poly.push_back(TplConvert::_2SUMOReal((*i).c_str())); // !!! may throw something anyhow...
122  }
123  if (poly.size() < 4) {
124  throw ProcessError("Invalid boundary: need at least 2 coordinates");
125  } else if (poly.size() % 2 != 0) {
126  throw ProcessError("Invalid boundary: malformed coordinate");
127  } else if (poly.size() == 4) {
128  // prunning boundary (box)
129  myPrunningBoundary.push_back(Position(poly[0], poly[1]));
130  myPrunningBoundary.push_back(Position(poly[2], poly[1]));
131  myPrunningBoundary.push_back(Position(poly[2], poly[3]));
132  myPrunningBoundary.push_back(Position(poly[0], poly[3]));
133  } else {
134  for (std::vector<SUMOReal>::iterator j = poly.begin(); j != poly.end();) {
135  SUMOReal x = *j++;
136  SUMOReal y = *j++;
137  myPrunningBoundary.push_back(Position(x, y));
138  }
139  }
140  myNeedGeoTransformedPrunningBoundary = oc.isSet("keep-edges.in-geo-boundary");
141  }
142 }
143 
144 
145 void
147  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
148  delete((*i).second);
149  }
150  myEdges.clear();
151  for (EdgeCont::iterator i = myExtractedEdges.begin(); i != myExtractedEdges.end(); i++) {
152  delete((*i).second);
153  }
154  myExtractedEdges.clear();
155 }
156 
157 
158 
159 // ----- edge access methods
160 bool
161 NBEdgeCont::insert(NBEdge* edge, bool ignorePrunning) {
162  if (myEdges.count(edge->getID())) {
163  return false;
164  }
165  if (!ignorePrunning && ignoreFilterMatch(edge)) {
166  edge->getFromNode()->removeEdge(edge);
167  edge->getToNode()->removeEdge(edge);
168  myIgnoredEdges.insert(edge->getID());
169  delete edge;
170  } else {
172  if (oc.exists("dismiss-vclasses") && oc.getBool("dismiss-vclasses")) {
174  }
175  myEdges[edge->getID()] = edge;
176  }
177  return true;
178 }
179 
180 
181 bool
183  // remove edges which allow a speed below a set one (set using "keep-edges.min-speed")
184  if (edge->getSpeed() < myEdgesMinSpeed) {
185  return true;
186  }
187  // check whether the edge is a named edge to keep
188  if (!myRemoveEdgesAfterJoining && myEdges2Keep.size() != 0) {
189  if (find(myEdges2Keep.begin(), myEdges2Keep.end(), edge->getID()) == myEdges2Keep.end()) {
190  return true;
191  }
192  }
193  // check whether the edge is a named edge to remove
194  if (myEdges2Remove.size() != 0) {
195  if (find(myEdges2Remove.begin(), myEdges2Remove.end(), edge->getID()) != myEdges2Remove.end()) {
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 prunning boundary
220  if (myPrunningBoundary.size() != 0) {
224  } else if (GeoConvHelper::getLoaded().usingGeoProjection()) {
225  // XXX what if input file with different projections are loaded?
226  for (int i = 0; i < (int) myPrunningBoundary.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 0;
253  }
254  } else {
255  return 0;
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 != 0) {
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]") != 0) && (retrieve(id + "[1]") != 0)) {
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 != 0) {
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 == 0) {
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 0;
331 }
332 
333 
334 NBEdge*
335 NBEdgeCont::retrievePossiblySplit(const std::string& id, SUMOReal pos) const {
336  // check whether the edge was not split, yet
337  NBEdge* edge = retrieve(id);
338  if (edge != 0) {
339  return edge;
340  }
341  size_t 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, (*i).first.length());
346  }
347  }
348  // find the part of the edge which matches the position
349  SUMOReal 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 == 0) {
361  if (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 0;
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 bool
412  return splitAt(dc, edge, node, edge->getID() + "[0]", edge->getID() + "[1]",
413  (unsigned int) edge->myLanes.size(), (unsigned int) edge->myLanes.size());
414 }
415 
416 
417 bool
419  const std::string& firstEdgeName,
420  const std::string& secondEdgeName,
421  unsigned int noLanesFirstEdge, unsigned int noLanesSecondEdge,
422  const SUMOReal speed,
423  const int changedLeft) {
424  SUMOReal pos;
425  pos = edge->getGeometry().nearest_offset_to_point2D(node->getPosition());
426  if (pos <= 0) {
428  edge->myFrom->getPosition(), edge->myTo->getPosition(),
429  node->getPosition());
430  }
431  if (pos <= 0 || pos + POSITION_EPS > edge->getGeometry().length()) {
432  return false;
433  }
434  return splitAt(dc, edge, pos, node, firstEdgeName, secondEdgeName,
435  noLanesFirstEdge, noLanesSecondEdge, speed, changedLeft);
436 }
437 
438 
439 bool
441  NBEdge* edge, SUMOReal pos, NBNode* node,
442  const std::string& firstEdgeName,
443  const std::string& secondEdgeName,
444  unsigned int noLanesFirstEdge, unsigned int noLanesSecondEdge,
445  const SUMOReal speed,
446  const int changedLeft
447  ) {
448  // there must be at least some overlap between first and second edge
449  assert(changedLeft > -((int)noLanesFirstEdge));
450  assert(changedLeft < (int)noLanesSecondEdge);
451 
452  // build the new edges' geometries
453  std::pair<PositionVector, PositionVector> geoms =
454  edge->getGeometry().splitAt(pos);
455  if (geoms.first[-1] != node->getPosition()) {
456  geoms.first.pop_back();
457  geoms.first.push_back(node->getPosition());
458  }
459 
460  if (geoms.second[0] != node->getPosition()) {
461  geoms.second[0] = node->getPosition();
462  }
463  // build and insert the edges
464  NBEdge* one = new NBEdge(firstEdgeName, edge->myFrom, node, edge, geoms.first, noLanesFirstEdge);
465  NBEdge* two = new NBEdge(secondEdgeName, node, edge->myTo, edge, geoms.second, noLanesSecondEdge);
466  two->copyConnectionsFrom(edge);
467  if (speed != -1.) {
468  two->setSpeed(-1, speed);
469  }
470  // replace information about this edge within the nodes
471  edge->myFrom->replaceOutgoing(edge, one, 0);
472  edge->myTo->replaceIncoming(edge, two, 0);
473  // patch tls
474  std::set<NBTrafficLightDefinition*> fromTLS = edge->myFrom->getControllingTLS();
475  for (std::set<NBTrafficLightDefinition*>::iterator i = fromTLS.begin(); i != fromTLS.end(); ++i) {
476  (*i)->replaceRemoved(edge, -1, one, -1);
477  }
478  std::set<NBTrafficLightDefinition*> toTLS = edge->myTo->getControllingTLS();
479  for (std::set<NBTrafficLightDefinition*>::iterator i = toTLS.begin(); i != toTLS.end(); ++i) {
480  (*i)->replaceRemoved(edge, -1, two, -1);
481  }
482  // the edge is now occuring twice in both nodes...
483  // clean up
484  edge->myFrom->removeDoubleEdges();
485  edge->myTo->removeDoubleEdges();
486  // add connections from the first to the second edge
487  // there will be as many connections as there are lanes on the second edge
488  // by default lanes will be added / discontinued on the right side
489  // (appropriate for highway on-/off-ramps)
490  const int offset = (int)one->getNumLanes() - (int)two->getNumLanes() + changedLeft;
491  for (int i2 = 0; i2 < (int)two->getNumLanes(); i2++) {
492  const int i1 = MIN2(MAX2((int)0, i2 + offset), (int)one->getNumLanes());
493  if (!one->addLane2LaneConnection(i1, two, i2, NBEdge::L2L_COMPUTED)) {
494  throw ProcessError("Could not set connection!");
495  }
496  }
498  if (find(myEdges2Keep.begin(), myEdges2Keep.end(), edge->getID()) != myEdges2Keep.end()) {
499  myEdges2Keep.insert(one->getID());
500  myEdges2Keep.insert(two->getID());
501  }
502  if (find(myEdges2Remove.begin(), myEdges2Remove.end(), edge->getID()) != myEdges2Remove.end()) {
503  myEdges2Remove.insert(one->getID());
504  myEdges2Remove.insert(two->getID());
505  }
506  }
507  // erase the splitted edge
508  erase(dc, edge);
509  insert(one, true);
510  insert(two, true);
511  myEdgesSplit++;
512  return true;
513 }
514 
515 
516 
517 // ----- container access methods
518 std::vector<std::string>
520  std::vector<std::string> ret;
521  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
522  ret.push_back((*i).first);
523  }
524  return ret;
525 }
526 
527 
528 // ----- Adapting the input
529 void
531  EdgeVector toRemove;
532  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
533  NBEdge* edge = (*i).second;
534  if (!myEdges2Keep.count(edge->getID())) {
535  edge->getFromNode()->removeEdge(edge);
536  edge->getToNode()->removeEdge(edge);
537  toRemove.push_back(edge);
538  }
539  }
540  for (EdgeVector::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
541  erase(dc, *j);
542  }
543 }
544 
545 
546 void
548  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
549  if ((*i).second->getGeometry().size() < 3) {
550  continue;
551  }
552  (*i).second->splitGeometry(*this, nc);
553  }
554 }
555 
556 
557 void
559  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
560  (*i).second->reduceGeometry(minDist);
561  }
562 }
563 
564 
565 void
566 NBEdgeCont::checkGeometries(const SUMOReal maxAngle, const SUMOReal minRadius, bool fix) {
567  if (maxAngle > 0 || minRadius > 0) {
568  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
569  (*i).second->checkGeometry(maxAngle, minRadius, fix);
570  }
571  }
572 }
573 
574 
575 // ----- processing methods
576 void
578  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); i++) {
579  (*i).second->clearControllingTLInformation();
580  }
581 }
582 
583 
584 void
586  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
587  (*i).second->sortOutgoingConnectionsByAngle();
588  }
589 }
590 
591 
592 void
593 NBEdgeCont::computeEdge2Edges(bool noLeftMovers) {
594  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
595  (*i).second->computeEdge2Edges(noLeftMovers);
596  }
597 }
598 
599 
600 void
602  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
603  (*i).second->computeLanes2Edges();
604  }
605 }
606 
607 
608 void
610  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
611  (*i).second->recheckLanes();
612  }
613 }
614 
615 
616 void
617 NBEdgeCont::appendTurnarounds(bool noTLSControlled) {
618  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
619  (*i).second->appendTurnaround(noTLSControlled, true);
620  }
621 }
622 
623 
624 void
625 NBEdgeCont::appendTurnarounds(const std::set<std::string>& ids, bool noTLSControlled) {
626  for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); it++) {
627  myEdges[*it]->appendTurnaround(noTLSControlled, false);
628  }
629 }
630 
631 
632 void
634  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
635  (*i).second->computeEdgeShape();
636  }
637 }
638 
639 
640 void
642  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
643  (*i).second->computeLaneShapes();
644  }
645 }
646 
647 
648 void
651  EdgeVector edges) {
652  // !!! Attention!
653  // No merging of the geometry to come is being done
654  // The connections are moved from one edge to another within
655  // the replacement where the edge is a node's incoming edge.
656 
657  // count the number of lanes, the speed and the id
658  unsigned int nolanes = 0;
659  SUMOReal speed = 0;
660  int priority = 0;
661  std::string id;
662  sort(edges.begin(), edges.end(), NBContHelper::same_connection_edge_sorter());
663  // retrieve the connected nodes
664  NBEdge* tpledge = *(edges.begin());
665  NBNode* from = tpledge->getFromNode();
666  NBNode* to = tpledge->getToNode();
667  EdgeVector::const_iterator i;
668  for (i = edges.begin(); i != edges.end(); i++) {
669  // some assertions
670  assert((*i)->getFromNode() == from);
671  assert((*i)->getToNode() == to);
672  // ad the number of lanes the current edge has
673  nolanes += (*i)->getNumLanes();
674  // build the id
675  if (i != edges.begin()) {
676  id += "+";
677  }
678  id += (*i)->getID();
679  // compute the speed
680  speed += (*i)->getSpeed();
681  // build the priority
682  priority = MAX2(priority, (*i)->getPriority());
683  }
684  speed /= edges.size();
685  // build the new edge
686  NBEdge* newEdge = new NBEdge(id, from, to, "", speed, nolanes, priority,
688  tpledge->getStreetName(), tpledge->myLaneSpreadFunction);
689  // copy lane attributes
690  int laneIndex = 0;
691  for (i = edges.begin(); i != edges.end(); ++i) {
692  const std::vector<NBEdge::Lane>& lanes = (*i)->getLanes();
693  for (int j = 0; j < (int)lanes.size(); ++j) {
694  newEdge->setPermissions(lanes[j].permissions, laneIndex);
695  newEdge->setLaneWidth(laneIndex, lanes[j].width);
696  newEdge->setEndOffset(laneIndex, lanes[j].endOffset);
697  laneIndex++;
698  }
699  }
700  insert(newEdge, true);
701  // replace old edge by current within the nodes
702  // and delete the old
703  from->replaceOutgoing(edges, newEdge);
704  to->replaceIncoming(edges, newEdge);
705  // patch connections
706  // add edge2edge-information
707  for (i = edges.begin(); i != edges.end(); i++) {
708  EdgeVector ev = (*i)->getConnectedEdges();
709  for (EdgeVector::iterator j = ev.begin(); j != ev.end(); j++) {
710  newEdge->addEdge2EdgeConnection(*j);
711  }
712  }
713  // copy outgoing connections to the new edge
714  unsigned int currLane = 0;
715  for (i = edges.begin(); i != edges.end(); i++) {
716  newEdge->moveOutgoingConnectionsFrom(*i, currLane);
717  currLane += (*i)->getNumLanes();
718  }
719  // patch tl-information
720  currLane = 0;
721  for (i = edges.begin(); i != edges.end(); i++) {
722  unsigned int noLanes = (*i)->getNumLanes();
723  for (unsigned int j = 0; j < noLanes; j++, currLane++) {
724  // replace in traffic lights
725  tlc.replaceRemoved(*i, j, newEdge, currLane);
726  }
727  }
728  // delete joined edges
729  for (i = edges.begin(); i != edges.end(); i++) {
730  extract(dc, *i, true);
731  }
732 }
733 
734 
735 void
737  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
738  std::string oppositeID;
739  if ((*i).first[0] == '-') {
740  oppositeID = (*i).first.substr(1);
741  } else {
742  oppositeID = "-" + (*i).first;
743  }
744  if (myEdges.find(oppositeID) != myEdges.end()) {
745  (*i).second->setLaneSpreadFunction(LANESPREAD_RIGHT);
746  myEdges.find(oppositeID)->second->setLaneSpreadFunction(LANESPREAD_RIGHT);
747  } else {
748  (*i).second->setLaneSpreadFunction(LANESPREAD_CENTER);
749  }
750  }
751 }
752 
753 
754 
755 // ----- other
756 void
757 NBEdgeCont::addPostProcessConnection(const std::string& from, int fromLane, const std::string& to, int toLane, bool mayDefinitelyPass, bool keepClear, SUMOReal contPos) {
758  myConnections.push_back(PostProcessConnection(from, fromLane, to, toLane, mayDefinitelyPass, keepClear, contPos));
759 }
760 
761 
762 void
764  for (std::vector<PostProcessConnection>::const_iterator i = myConnections.begin(); i != myConnections.end(); ++i) {
765  NBEdge* from = retrievePossiblySplit((*i).from, true);
766  NBEdge* to = retrievePossiblySplit((*i).to, false);
767  if (from == 0 || to == 0 ||
768  !from->addLane2LaneConnection((*i).fromLane, to, (*i).toLane, NBEdge::L2L_USER, true, (*i).mayDefinitelyPass, (*i).keepClear, (*i).contPos)) {
769  WRITE_ERROR("Could not insert connection between '" + (*i).from + "' and '" + (*i).to + "' after build.");
770  }
771  }
772  // during loading we also kept some ambiguous connections in hope they might be valid after processing
773  // we need to make sure that all invalid connections are removed now
774  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); ++it) {
775  NBEdge* edge = it->second;
776  NBNode* to = edge->getToNode();
777  // make a copy because we may delete connections
778  std::vector<NBEdge::Connection> connections = edge->getConnections();
779  for (std::vector<NBEdge::Connection>::iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
780  NBEdge::Connection& c = *it_con;
781  if (c.toEdge != 0 && c.toEdge->getFromNode() != to) {
782  WRITE_WARNING("Found and removed invalid connection from edge '" + edge->getID() +
783  "' to edge '" + c.toEdge->getID() + "' via junction '" + to->getID() + "'.");
784  edge->removeFromConnections(c.toEdge);
785  }
786  }
787  }
788 }
789 
790 
792 NBEdgeCont::getGeneratedFrom(const std::string& id) const {
793  size_t len = id.length();
794  EdgeVector ret;
795  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
796  std::string curr = (*i).first;
797  // the next check makes it possibly faster - we don not have
798  // to compare the names
799  if (curr.length() <= len) {
800  continue;
801  }
802  // the name must be the same as the given id but something
803  // beginning with a '[' must be appended to it
804  if (curr.substr(0, len) == id && curr[len] == '[') {
805  ret.push_back((*i).second);
806  continue;
807  }
808  // ok, maybe the edge is a compound made during joining of edges
809  size_t pos = curr.find(id);
810  // surely not
811  if (pos == std::string::npos) {
812  continue;
813  }
814  // check leading char
815  if (pos > 0) {
816  if (curr[pos - 1] != ']' && curr[pos - 1] != '+') {
817  // actually, this is another id
818  continue;
819  }
820  }
821  if (pos + id.length() < curr.length()) {
822  if (curr[pos + id.length()] != '[' && curr[pos + id.length()] != '+') {
823  // actually, this is another id
824  continue;
825  }
826  }
827  ret.push_back((*i).second);
828  }
829  return ret;
830 }
831 
832 
833 int
835  myGuessedRoundabouts.clear();
836  std::set<NBEdge*> loadedRoundaboutEdges;
837  for (std::set<EdgeSet>::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
838  loadedRoundaboutEdges.insert(it->begin(), it->end());
839  }
840  // step 1: keep only those edges which have no turnarounds and which are not
841  // part of a loaded roundabout
842  std::set<NBEdge*> candidates;
843  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
844  NBEdge* e = (*i).second;
845  NBNode* const to = e->getToNode();
846  if (e->getTurnDestination() == 0 && to->getConnectionTo(e->getFromNode()) == 0 && loadedRoundaboutEdges.count(e) == 0) {
847  candidates.insert(e);
848  }
849  }
850 
851  // step 2:
852  std::set<NBEdge*> visited;
853  for (std::set<NBEdge*>::const_iterator i = candidates.begin(); i != candidates.end(); ++i) {
854  EdgeVector loopEdges;
855  // start with a random edge (this doesn't have to be a roundabout edge)
856  // loop over connected edges (using always the leftmost one)
857  // and keep the list in loopEdges
858  // continue until we loop back onto a loopEdges and extract the loop
859  NBEdge* e = (*i);
860  if (visited.count(e) > 0) {
861  // already seen
862  continue;
863  }
864  loopEdges.push_back(e);
865  bool doLoop = true;
866  do {
867  visited.insert(e);
868  const EdgeVector& edges = e->getToNode()->getEdges();
869  if (edges.size() < 2) {
870  doLoop = false;
871  break;
872  }
873  if (e->getTurnDestination() != 0 || e->getToNode()->getConnectionTo(e->getFromNode()) != 0) {
874  // do not follow turn-arounds while in a (tentative) loop
875  doLoop = false;
876  break;
877  }
878  EdgeVector::const_iterator me = find(edges.begin(), edges.end(), e);
879  NBContHelper::nextCW(edges, me);
880  NBEdge* left = *me;
881  SUMOReal angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), left->getAngleAtNode(e->getToNode())));
882  if (angle >= 90) {
883  // roundabouts do not have sharp turns (or they wouldn't be called 'round')
884  doLoop = false;
885  break;
886  }
887  EdgeVector::const_iterator loopClosed = find(loopEdges.begin(), loopEdges.end(), left);
888  const size_t loopSize = loopEdges.end() - loopClosed;
889  if (loopSize > 0) {
890  // loop found
891  if (loopSize < 3) {
892  doLoop = false; // need at least 3 edges for a roundabout
893  } else if (loopSize < loopEdges.size()) {
894  // remove initial edges not belonging to the loop
895  EdgeVector(loopEdges.begin() + (loopEdges.size() - loopSize), loopEdges.end()).swap(loopEdges);
896  }
897  // count attachments to the outside. need at least 3 or a roundabout doesn't make much sense
898  int attachments = 0;
899  for (EdgeVector::const_iterator j = loopEdges.begin(); j != loopEdges.end(); ++j) {
900  if ((*j)->getToNode()->getEdges().size() > 2) {
901  attachments++;
902  }
903  }
904  if (attachments < 3) {
905  doLoop = false;
906  }
907  break;
908  }
909  if (visited.count(left) > 0) {
910  doLoop = false;
911  } else {
912  // keep going
913  loopEdges.push_back(left);
914  e = left;
915  }
916  } while (doLoop);
917  if (doLoop) {
918  // check form factor to avoid elongated shapes (circle: 1, square: ~0.79)
919  if (formFactor(loopEdges) > 0.6) {
920  // collected edges are marked in markRoundabouts
921  myGuessedRoundabouts.insert(EdgeSet(loopEdges.begin(), loopEdges.end()));
922  }
923  }
924  }
925  return (int)myGuessedRoundabouts.size();
926 }
927 
928 
929 SUMOReal
931  PositionVector points;
932  for (EdgeVector::const_iterator it = loopEdges.begin(); it != loopEdges.end(); ++it) {
933  points.append((*it)->getGeometry());
934  }
935  SUMOReal circumference = points.length2D();
936  return 4 * M_PI * points.area() / (circumference * circumference);
937 }
938 
939 
940 const std::set<EdgeSet>
942  std::set<EdgeSet> result = myRoundabouts;
943  result.insert(myGuessedRoundabouts.begin(), myGuessedRoundabouts.end());
944  return result;
945 }
946 
947 
948 void
949 NBEdgeCont::addRoundabout(const EdgeSet& roundabout) {
950  if (find(myRoundabouts.begin(), myRoundabouts.end(), roundabout) != myRoundabouts.end()) {
951  WRITE_WARNING("Ignoring duplicate roundabout: " + toString(roundabout));
952  } else {
953  myRoundabouts.insert(roundabout);
954  }
955 }
956 
957 
958 void
960  const std::set<EdgeSet> roundabouts = getRoundabouts();
961  for (std::set<EdgeSet>::const_iterator it = roundabouts.begin(); it != roundabouts.end(); ++it) {
962  const EdgeSet roundaboutSet = *it;
963  for (std::set<NBEdge*>::const_iterator j = roundaboutSet.begin(); j != roundaboutSet.end(); ++j) {
964  // disable turnarounds on incoming edges
965  NBNode* node = (*j)->getToNode();
966  const EdgeVector& incoming = node->getIncomingEdges();
967  for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
968  NBEdge* inEdge = *k;
969  if (roundaboutSet.count(inEdge) > 0) {
970  continue;
971  }
972  if ((inEdge)->getStep() >= NBEdge::LANES2LANES_USER) {
973  continue;
974  }
975  inEdge->removeFromConnections(inEdge->getTurnDestination(), -1);
976  }
977  // let the connections to succeeding roundabout edge have a higher priority
978  (*j)->setJunctionPriority(node, 1000);
979  node->setRoundabout();
980  }
981  }
982 }
983 
984 void
986  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
987  NBEdge* e = i->second;
988  // is this a "real" junction?
989  // XXX nyi
990  //continue
991  const SUMOReal offset = MAX2((SUMOReal)0, e->getLength() - 3);
992  switch (e->getToNode()->getType()) {
993  case NODETYPE_PRIORITY:
994  // yield or major?
995  if (e->getJunctionPriority(e->getToNode()) > 0) {
997  } else {
999  }
1000  break;
1002  // yield or major?
1003  if (e->getJunctionPriority(e->getToNode()) > 0) {
1005  } else {
1006  e->addSign(NBSign(NBSign::SIGN_TYPE_STOP, offset));
1007  }
1008  break;
1009  case NODETYPE_ALLWAY_STOP:
1011  break;
1014  break;
1015  default:
1016  break;
1017  }
1018  }
1019 }
1020 
1021 
1022 int
1023 NBEdgeCont::guessSidewalks(SUMOReal width, SUMOReal minSpeed, SUMOReal maxSpeed, bool fromPermissions) {
1024  int sidewalksCreated = 0;
1025  const std::vector<std::string> edges = OptionsCont::getOptions().getStringVector("sidewalks.guess.exclude");
1026  std::set<std::string> exclude(edges.begin(), edges.end());
1027  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); it++) {
1028  NBEdge* edge = it->second;
1029  if (// not excluded
1030  exclude.count(edge->getID()) == 0
1031  // does not yet have a sidewalk
1032  && edge->getPermissions(0) != SVC_PEDESTRIAN
1033  && (
1034  // guess.from-permissions
1035  (fromPermissions && (edge->getPermissions() & SVC_PEDESTRIAN) != 0)
1036  // guess from speed
1037  || (!fromPermissions && edge->getSpeed() > minSpeed && edge->getSpeed() <= maxSpeed)
1038  )) {
1039  edge->addSidewalk(width);
1040  sidewalksCreated += 1;
1041  }
1042  }
1043  return sidewalksCreated;
1044 }
1045 
1046 
1047 /****************************************************************************/
~NBEdgeCont()
Destructor.
Definition: NBEdgeCont.cpp:75
int guessSidewalks(SUMOReal width, SUMOReal minSpeed, SUMOReal maxSpeed, bool fromPermissions)
add sidwalks to edges within the given limits or permissions and return the number of edges affected ...
std::vector< Lane > myLanes
Lane information.
Definition: NBEdge.h:1317
void replaceIncoming(NBEdge *which, NBEdge *by, unsigned int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
Definition: NBNode.cpp:1033
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges.
Definition: NBNode.h:240
const std::string & getTypeID() const
Definition: NBEdge.h:907
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:148
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
Definition: NBEdgeCont.cpp:585
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
Definition: NBEdgeCont.cpp:959
void setRoundabout()
update the type of this node as a roundabout
Definition: NBNode.cpp:2437
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:282
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
A class representing a single street sign.
Definition: NBSign.h:51
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation. ...
is a pedestrian
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
Definition: NBEdgeCont.cpp:519
static bool transformCoordinates(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
void addSign(NBSign sign)
Definition: NBEdge.h:1094
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:164
NBNode * myTo
Definition: NBEdge.h:1266
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
Definition: NBEdgeCont.cpp:941
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:242
bool myNeedGeoTransformedPrunningBoundary
whether a geo transform has been applied to the pruning boundary
Definition: NBEdgeCont.h:620
#define M_PI
Definition: angles.h:37
A container for traffic light definitions and built programs.
int guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
Definition: NBEdgeCont.cpp:834
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2294
bool myRemoveEdgesAfterJoining
Whether edges shall be joined first, then removed.
Definition: NBEdgeCont.h:596
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2349
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:502
void moveOutgoingConnectionsFrom(NBEdge *e, unsigned int laneOff)
Definition: NBEdge.cpp:1894
void addSidewalk(SUMOReal width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:2478
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:98
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
Definition: NBNode.cpp:1213
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:70
bool addLane2LaneConnection(unsigned int fromLane, NBEdge *dest, unsigned int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, SUMOReal contPos=UNSPECIFIED_CONTPOS)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:684
A container for districts.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
void removeDoubleEdges()
Definition: NBNode.cpp:1101
T MAX2(T a, T b)
Definition: StdDefs.h:75
void clearControllingTLInformation() const
Clears information about controlling traffic lights for all connenections of all edges.
Definition: NBEdgeCont.cpp:577
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:2365
void generateStreetSigns()
assigns street signs to edges based on toNode types
Definition: NBEdgeCont.cpp:985
void rename(NBEdge *edge, const std::string &newID)
Renames the edge. Throws exception if newID already exists.
Definition: NBEdgeCont.cpp:399
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:411
void recheckPostProcessConnections()
Try to set any stored connections.
Definition: NBEdgeCont.cpp:763
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
unsigned int myEdgesSplit
the number of splits of edges during the building
Definition: NBEdgeCont.h:587
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
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:97
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
Definition: NBEdgeCont.cpp:601
std::vector< PostProcessConnection > myConnections
The list of connections to recheck.
Definition: NBEdgeCont.h:571
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
void checkGeometries(const SUMOReal maxAngle, const SUMOReal minRadius, bool fix)
Definition: NBEdgeCont.cpp:566
NBEdgeCont(NBTypeCont &tc)
Constructor.
Definition: NBEdgeCont.cpp:66
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges.
Definition: NBNode.h:248
const std::string & getID() const
Returns the id.
Definition: Named.h:65
SUMOReal length2D() const
Returns the length.
bool addEdge2EdgeConnection(NBEdge *dest)
Adds a connection to another edge.
Definition: NBEdge.cpp:660
bool overlapsWith(const AbstractPoly &poly, SUMOReal offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:156
SVCPermissions myVehicleClasses2Keep
Set of vehicle types which must be allowed on edges in order to keep them.
Definition: NBEdgeCont.h:605
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
void reduceGeometries(const SUMOReal minDist)
Definition: NBEdgeCont.cpp:558
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
Definition: NBEdge.h:102
std::set< NBEdge * > EdgeSet
Definition: NBCont.h:51
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node.
Definition: NBNode.h:318
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:161
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:530
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
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
Definition: NBEdgeCont.cpp:81
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:345
std::set< std::string > myEdges2Keep
Set of ids of edges which shall explicitly be kept.
Definition: NBEdgeCont.h:599
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:265
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:593
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
Definition: NBEdgeCont.cpp:641
const EdgeVector & getEdges() const
Returns all edges which participate in this node.
Definition: NBNode.h:256
T MIN2(T a, T b)
Definition: StdDefs.h:69
void splitGeometry(NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:547
EdgeCont myEdges
The instance of the dictionary (id->edge)
Definition: NBEdgeCont.h:578
#define POSITION_EPS
Definition: config.h:187
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
void clear()
Deletes all edges.
Definition: NBEdgeCont.cpp:146
EdgeCont myExtractedEdges
The extracted nodes which are kept for reference.
Definition: NBEdgeCont.h:581
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:75
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:54
The connection was given by the user.
Definition: NBEdge.h:113
std::set< EdgeSet > myGuessedRoundabouts
Edges marked as belonging to a roundabout after guessing.
Definition: NBEdgeCont.h:626
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:922
std::set< EdgeSet > myRoundabouts
Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout) ...
Definition: NBEdgeCont.h:624
NBEdge * getConnectionTo(NBNode *n) const
Definition: NBNode.cpp:1661
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
Definition: NBEdge.cpp:1267
void joinSameNodeConnectingEdges(NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, EdgeVector edges)
Joins the given edges because they connect the same nodes.
Definition: NBEdgeCont.cpp:649
static SUMOReal formFactor(const EdgeVector &loopEdges)
compute the form factor for a loop of edges
Definition: NBEdgeCont.cpp:930
std::pair< PositionVector, PositionVector > splitAt(SUMOReal where) const
Returns the two lists made when this list vector is splitted at the given point.
SVCPermissions myVehicleClasses2Remove
Set of vehicle types which need not be supported (edges which allow ONLY these are removed) ...
Definition: NBEdgeCont.h:608
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2393
PositionVector myPrunningBoundary
Boundary within which an edge must be located in order to be kept.
Definition: NBEdgeCont.h:617
SUMOReal length() const
Returns the length.
std::set< std::string > myTypes2Keep
Set of edges types which shall be kept.
Definition: NBEdgeCont.h:611
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:201
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
SUMOReal myEdgesMinSpeed
The minimum speed an edge may have in order to be kept (default: -1)
Definition: NBEdgeCont.h:593
void setID(const std::string &newID)
resets the id
Definition: Named.h:73
void replaceOutgoing(NBEdge *which, NBEdge *by, unsigned int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
Definition: NBNode.cpp:997
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:246
void appendTurnarounds(bool noTLSControlled)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:617
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
bool getShallBeDiscarded(const std::string &type) const
Returns the information whether edges of this type shall be discarded.
Definition: NBTypeCont.cpp:199
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:523
A storage for options typed value containers)
Definition: OptionsCont.h:108
static SUMOReal nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
Definition: GeomHelper.cpp:100
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:380
A structure representing a connection between two lanes.
Definition: NBEdgeCont.h:542
void computeEdgeShapes()
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:633
The connection was computed.
Definition: NBEdge.h:111
Represents a single node (junction) during network building.
Definition: NBNode.h:74
void dismissVehicleClassInformation()
Definition: NBEdge.cpp:2414
NBTypeCont & myTypeCont
The network builder; used to obtain type information.
Definition: NBEdgeCont.h:537
void recheckLaneSpread()
Rechecks whether the lane spread is proper.
Definition: NBEdgeCont.cpp:736
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2333
#define SUMOReal
Definition: config.h:213
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
Definition: NBHelpers.cpp:56
void removeFromSinksAndSources(NBEdge *const e)
Removes the given edge from the lists of sources and sinks in all stored districts.
std::set< std::string > myTypes2Remove
Set of edges types which shall be removed.
Definition: NBEdgeCont.h:614
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:609
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:431
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
std::set< std::string > myIgnoredEdges
The ids of ignored edges.
Definition: NBEdgeCont.h:584
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:792
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces occurences of the removed edge/lane in all definitions by the given edge.
SUMOReal area() const
Returns the area (0 for non-closed)
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
Definition: NBEdgeCont.cpp:949
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass, bool keepClear, SUMOReal contPos)
Adds a connection which could not be set during loading.
Definition: NBEdgeCont.cpp:757
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:763
NBNode * myFrom
The source and the destination node.
Definition: NBEdge.h:1266
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2157
bool exists(const std::string &name) const
Returns the information whether the named option is known.
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
void copyConnectionsFrom(NBEdge *src)
Definition: NBEdge.cpp:1030
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:182
A storage for available types of edges.
Definition: NBTypeCont.h:62
SUMOReal getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:404
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
SUMOReal getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge&#39;s geometry at the given node.
Definition: NBEdge.cpp:1287
std::set< std::string > myEdges2Remove
Set of ids of edges which shall explicitly be removed.
Definition: NBEdgeCont.h:602
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:361