SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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-2015 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 <iostream>
39 #include <fstream>
40 #include <iomanip>
41 #include <utils/geom/Boundary.h>
42 #include <utils/geom/GeomHelper.h>
45 #include <utils/common/ToString.h>
48 #include "NBNetBuilder.h"
49 #include "NBEdgeCont.h"
50 #include "NBNodeCont.h"
51 #include "NBHelpers.h"
52 #include "NBCont.h"
54 #include "NBDistrictCont.h"
55 #include <cmath>
56 #include "NBTypeCont.h"
60 
61 #ifdef CHECK_MEMORY_LEAKS
62 #include <foreign/nvwa/debug_new.h>
63 #endif // CHECK_MEMORY_LEAKS
64 
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
70  myTypeCont(tc),
71  myEdgesSplit(0),
72  myVehicleClasses2Keep(0),
73  myVehicleClasses2Remove(0),
74  myNeedGeoTransformedPrunningBoundary(false)
75 {}
76 
77 
79  clear();
80 }
81 
82 
83 void
85  myAmLeftHanded = oc.getBool("lefthand");
86  // set edges dismiss/accept options
87  myEdgesMinSpeed = oc.isSet("keep-edges.min-speed") ? oc.getFloat("keep-edges.min-speed") : -1;
88  myRemoveEdgesAfterJoining = oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload");
89  // we possibly have to load the edges to keep
90  if (oc.isSet("keep-edges.input-file")) {
91  std::ifstream strm(oc.getString("keep-edges.input-file").c_str());
92  if (!strm.good()) {
93  throw ProcessError("Could not load names of edges too keep from '" + oc.getString("keep-edges.input-file") + "'.");
94  }
95  while (strm.good()) {
96  std::string name;
97  strm >> name;
98  myEdges2Keep.insert(name);
99  }
100  }
101  if (oc.isSet("keep-edges.explicit")) {
102  const std::vector<std::string> edges = oc.getStringVector("keep-edges.explicit");
103  myEdges2Keep.insert(edges.begin(), edges.end());
104  }
105  if (oc.isSet("remove-edges.explicit")) {
106  const std::vector<std::string> edges = oc.getStringVector("remove-edges.explicit");
107  myEdges2Remove.insert(edges.begin(), edges.end());
108  }
109  if (oc.exists("keep-edges.by-vclass") && oc.isSet("keep-edges.by-vclass")) {
110  myVehicleClasses2Keep = parseVehicleClasses(oc.getStringVector("keep-edges.by-vclass"));
111  }
112  if (oc.exists("remove-edges.by-vclass") && oc.isSet("remove-edges.by-vclass")) {
113  myVehicleClasses2Remove = parseVehicleClasses(oc.getStringVector("remove-edges.by-vclass"));
114  }
115  if (oc.exists("keep-edges.by-type") && oc.isSet("keep-edges.by-type")) {
116  const std::vector<std::string> types = oc.getStringVector("keep-edges.by-type");
117  myTypes2Keep.insert(types.begin(), types.end());
118  }
119  if (oc.exists("remove-edges.by-type") && oc.isSet("remove-edges.by-type")) {
120  const std::vector<std::string> types = oc.getStringVector("remove-edges.by-type");
121  myTypes2Remove.insert(types.begin(), types.end());
122  }
123 
124  if (oc.isSet("keep-edges.in-boundary") || oc.isSet("keep-edges.in-geo-boundary")) {
125  std::vector<std::string> polyS = oc.getStringVector(oc.isSet("keep-edges.in-boundary") ?
126  "keep-edges.in-boundary" : "keep-edges.in-geo-boundary");
127  // !!! throw something if length<4 || length%2!=0?
128  std::vector<SUMOReal> poly;
129  for (std::vector<std::string>::iterator i = polyS.begin(); i != polyS.end(); ++i) {
130  poly.push_back(TplConvert::_2SUMOReal((*i).c_str())); // !!! may throw something anyhow...
131  }
132  if (poly.size() < 4) {
133  throw ProcessError("Invalid boundary: need at least 2 coordinates");
134  } else if (poly.size() % 2 != 0) {
135  throw ProcessError("Invalid boundary: malformed coordinate");
136  } else if (poly.size() == 4) {
137  // prunning boundary (box)
138  myPrunningBoundary.push_back(Position(poly[0], poly[1]));
139  myPrunningBoundary.push_back(Position(poly[2], poly[1]));
140  myPrunningBoundary.push_back(Position(poly[2], poly[3]));
141  myPrunningBoundary.push_back(Position(poly[0], poly[3]));
142  } else {
143  for (std::vector<SUMOReal>::iterator j = poly.begin(); j != poly.end();) {
144  SUMOReal x = *j++;
145  SUMOReal y = *j++;
147  }
148  }
149  myNeedGeoTransformedPrunningBoundary = oc.isSet("keep-edges.in-geo-boundary");
150  }
151 }
152 
153 
154 void
156  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
157  delete((*i).second);
158  }
159  myEdges.clear();
160  for (EdgeCont::iterator i = myExtractedEdges.begin(); i != myExtractedEdges.end(); i++) {
161  delete((*i).second);
162  }
163  myExtractedEdges.clear();
164 }
165 
166 
167 
168 // ----- edge access methods
169 bool
170 NBEdgeCont::insert(NBEdge* edge, bool ignorePrunning) {
171  if (myAmLeftHanded) {
172  edge->setLeftHanded();
173  }
174  if (myEdges.count(edge->getID())) {
175  return false;
176  }
177  if (!ignorePrunning && ignoreFilterMatch(edge)) {
178  edge->getFromNode()->removeEdge(edge);
179  edge->getToNode()->removeEdge(edge);
180  myIgnoredEdges.insert(edge->getID());
181  delete edge;
182  } else {
184  if (oc.exists("dismiss-vclasses") && oc.getBool("dismiss-vclasses")) {
186  }
187  myEdges[edge->getID()] = edge;
188  }
189  return true;
190 }
191 
192 
193 bool
195  // remove edges which allow a speed below a set one (set using "keep-edges.min-speed")
196  if (edge->getSpeed() < myEdgesMinSpeed) {
197  return true;
198  }
199  // check whether the edge is a named edge to keep
200  if (!myRemoveEdgesAfterJoining && myEdges2Keep.size() != 0) {
201  if (find(myEdges2Keep.begin(), myEdges2Keep.end(), edge->getID()) == myEdges2Keep.end()) {
202  return true;
203  }
204  }
205  // check whether the edge is a named edge to remove
206  if (myEdges2Remove.size() != 0) {
207  if (find(myEdges2Remove.begin(), myEdges2Remove.end(), edge->getID()) != myEdges2Remove.end()) {
208  return true;
209  }
210  }
211  // check whether the edge shall be removed because it does not allow any of the wished classes
212  if (myVehicleClasses2Keep != 0 && (myVehicleClasses2Keep & edge->getPermissions()) == 0) {
213  return true;
214  }
215  // check whether the edge shall be removed due to allowing unwished classes only
217  return true;
218  }
219  // check whether the edge shall be removed because it does not have one of the requested types
220  if (myTypes2Keep.size() != 0) {
221  if (myTypes2Keep.count(edge->getTypeID()) == 0) {
222  return true;
223  }
224  }
225  // check whether the edge shall be removed because it has one of the forbidden types
226  if (myTypes2Remove.size() != 0) {
227  if (myTypes2Remove.count(edge->getTypeID()) > 0) {
228  return true;
229  }
230  }
231  // check whether the edge is within the prunning boundary
232  if (myPrunningBoundary.size() != 0) {
236  } else if (GeoConvHelper::getLoaded().usingGeoProjection()) {
237  // XXX what if input file with different projections are loaded?
238  for (int i = 0; i < (int) myPrunningBoundary.size(); i++) {
240  }
241  } else {
242  WRITE_ERROR("Cannot prune edges using a geo-boundary because no projection has been loaded");
243  }
245  }
247  return true;
248  }
249  }
251  return true;
252  }
253  return false;
254 }
255 
256 
257 NBEdge*
258 NBEdgeCont::retrieve(const std::string& id, bool retrieveExtracted) const {
259  EdgeCont::const_iterator i = myEdges.find(id);
260  if (i == myEdges.end()) {
261  if (retrieveExtracted) {
262  i = myExtractedEdges.find(id);
263  if (i == myExtractedEdges.end()) {
264  return 0;
265  }
266  } else {
267  return 0;
268  }
269  }
270  return (*i).second;
271 }
272 
273 
274 NBEdge*
275 NBEdgeCont::retrievePossiblySplit(const std::string& id, bool downstream) const {
276  NBEdge* edge = retrieve(id);
277  if (edge == 0) {
278  return 0;
279  }
280  const EdgeVector* candidates = downstream ? &edge->getToNode()->getOutgoingEdges() : &edge->getFromNode()->getIncomingEdges();
281  while (candidates->size() == 1) {
282  const std::string& nextID = candidates->front()->getID();
283  if (nextID.find(id) != 0 || nextID.size() <= id.size() + 1 || (nextID[id.size()] != '.' && nextID[id.size()] != '-')) {
284  break;
285  }
286  edge = candidates->front();
287  candidates = downstream ? &edge->getToNode()->getOutgoingEdges() : &edge->getFromNode()->getIncomingEdges();
288  }
289  return edge;
290 }
291 
292 
293 NBEdge*
294 NBEdgeCont::retrievePossiblySplit(const std::string& id, const std::string& hint, bool incoming) const {
295  // try to retrieve using the given name (iterative)
296  NBEdge* edge = retrieve(id);
297  if (edge != 0) {
298  return edge;
299  }
300  // now, we did not find it; we have to look over all possibilities
301  EdgeVector hints;
302  // check whether at least the hint was not splitted
303  NBEdge* hintedge = retrieve(hint);
304  if (hintedge == 0) {
305  hints = getGeneratedFrom(hint);
306  } else {
307  hints.push_back(hintedge);
308  }
309  EdgeVector candidates = getGeneratedFrom(id);
310  for (EdgeVector::iterator i = hints.begin(); i != hints.end(); i++) {
311  NBEdge* hintedge = (*i);
312  for (EdgeVector::iterator j = candidates.begin(); j != candidates.end(); j++) {
313  NBEdge* poss_searched = (*j);
314  NBNode* node = incoming
315  ? poss_searched->myTo : poss_searched->myFrom;
316  const EdgeVector& cont = incoming
317  ? node->getOutgoingEdges() : node->getIncomingEdges();
318  if (find(cont.begin(), cont.end(), hintedge) != cont.end()) {
319  return poss_searched;
320  }
321  }
322  }
323  return 0;
324 }
325 
326 
327 NBEdge*
328 NBEdgeCont::retrievePossiblySplit(const std::string& id, SUMOReal pos) const {
329  // check whether the edge was not split, yet
330  NBEdge* edge = retrieve(id);
331  if (edge != 0) {
332  return edge;
333  }
334  size_t maxLength = 0;
335  std::string tid = id + "[";
336  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
337  if ((*i).first.find(tid) == 0) {
338  maxLength = MAX2(maxLength, (*i).first.length());
339  }
340  }
341  // find the part of the edge which matches the position
342  SUMOReal seen = 0;
343  std::vector<std::string> names;
344  names.push_back(id + "[1]");
345  names.push_back(id + "[0]");
346  while (names.size() > 0) {
347  // retrieve the first subelement (to follow)
348  std::string cid = names.back();
349  names.pop_back();
350  edge = retrieve(cid);
351  // The edge was splitted; check its subparts within the
352  // next step
353  if (edge == 0) {
354  if (cid.length() + 3 < maxLength) {
355  names.push_back(cid + "[1]");
356  names.push_back(cid + "[0]");
357  }
358  }
359  // an edge with the name was found,
360  // check whether the position lies within it
361  else {
362  seen += edge->getLength();
363  if (seen >= pos) {
364  return edge;
365  }
366  }
367  }
368  return 0;
369 }
370 
371 
372 void
374  extract(dc, edge);
375  delete edge;
376 }
377 
378 
379 void
380 NBEdgeCont::extract(NBDistrictCont& dc, NBEdge* edge, bool remember) {
381  if (remember) {
382  myExtractedEdges[edge->getID()] = edge;
383  }
384  myEdges.erase(edge->getID());
385  edge->myFrom->removeEdge(edge);
386  edge->myTo->removeEdge(edge);
387  dc.removeFromSinksAndSources(edge);
388 }
389 
390 
391 void
392 NBEdgeCont::rename(NBEdge* edge, const std::string& newID) {
393  if (myEdges.count(newID) != 0) {
394  throw ProcessError("Attempt to rename edge using existing id '" + newID + "'");
395  }
396  myEdges.erase(edge->getID());
397  edge->setID(newID);
398  myEdges[newID] = edge;
399 }
400 
401 
402 // ----- explicit edge manipulation methods
403 bool
405  return splitAt(dc, edge, node, edge->getID() + "[0]", edge->getID() + "[1]",
406  (unsigned int) edge->myLanes.size(), (unsigned int) edge->myLanes.size());
407 }
408 
409 
410 bool
412  const std::string& firstEdgeName,
413  const std::string& secondEdgeName,
414  unsigned int noLanesFirstEdge, unsigned int noLanesSecondEdge,
415  const SUMOReal speed,
416  const int changedLeft) {
417  SUMOReal pos;
418  pos = edge->getGeometry().nearest_offset_to_point2D(node->getPosition());
419  if (pos <= 0) {
421  edge->myFrom->getPosition(), edge->myTo->getPosition(),
422  node->getPosition());
423  }
424  if (pos <= 0 || pos + POSITION_EPS > edge->getGeometry().length()) {
425  return false;
426  }
427  return splitAt(dc, edge, pos, node, firstEdgeName, secondEdgeName,
428  noLanesFirstEdge, noLanesSecondEdge, speed, changedLeft);
429 }
430 
431 
432 bool
434  NBEdge* edge, SUMOReal pos, NBNode* node,
435  const std::string& firstEdgeName,
436  const std::string& secondEdgeName,
437  unsigned int noLanesFirstEdge, unsigned int noLanesSecondEdge,
438  const SUMOReal speed,
439  const int changedLeft
440  ) {
441  // there must be at least some overlap between first and second edge
442  assert(changedLeft > -((int)noLanesFirstEdge));
443  assert(changedLeft < (int)noLanesSecondEdge);
444 
445  // build the new edges' geometries
446  std::pair<PositionVector, PositionVector> geoms =
447  edge->getGeometry().splitAt(pos);
448  if (geoms.first[-1] != node->getPosition()) {
449  geoms.first.pop_back();
450  geoms.first.push_back(node->getPosition());
451  }
452 
453  if (geoms.second[0] != node->getPosition()) {
454  geoms.second.pop_front();
455  geoms.second.push_front(node->getPosition());
456  }
457  // build and insert the edges
458  NBEdge* one = new NBEdge(firstEdgeName, edge->myFrom, node, edge, geoms.first, noLanesFirstEdge);
459  NBEdge* two = new NBEdge(secondEdgeName, node, edge->myTo, edge, geoms.second, noLanesSecondEdge);
460  two->copyConnectionsFrom(edge);
461  if (speed != -1.) {
462  two->setSpeed(-1, speed);
463  }
464  // replace information about this edge within the nodes
465  edge->myFrom->replaceOutgoing(edge, one, 0);
466  edge->myTo->replaceIncoming(edge, two, 0);
467  // the edge is now occuring twice in both nodes...
468  // clean up
469  edge->myFrom->removeDoubleEdges();
470  edge->myTo->removeDoubleEdges();
471  // add connections from the first to the second edge
472  // there will be as many connections as there are lanes on the second edge
473  // by default lanes will be added / discontinued on the right side
474  // (appropriate for highway on-/off-ramps)
475  const int offset = (int)one->getNumLanes() - (int)two->getNumLanes() + changedLeft;
476  for (int i2 = 0; i2 < (int)two->getNumLanes(); i2++) {
477  const int i1 = MIN2(MAX2((int)0, i2 + offset), (int)one->getNumLanes());
478  if (!one->addLane2LaneConnection(i1, two, i2, NBEdge::L2L_COMPUTED)) {
479  throw ProcessError("Could not set connection!");
480  }
481  }
483  if (find(myEdges2Keep.begin(), myEdges2Keep.end(), edge->getID()) != myEdges2Keep.end()) {
484  myEdges2Keep.insert(one->getID());
485  myEdges2Keep.insert(two->getID());
486  }
487  if (find(myEdges2Remove.begin(), myEdges2Remove.end(), edge->getID()) != myEdges2Remove.end()) {
488  myEdges2Remove.insert(one->getID());
489  myEdges2Remove.insert(two->getID());
490  }
491  }
492  // erase the splitted edge
493  erase(dc, edge);
494  insert(one, true);
495  insert(two, true);
496  myEdgesSplit++;
497  return true;
498 }
499 
500 
501 
502 // ----- container access methods
503 std::vector<std::string>
505  std::vector<std::string> ret;
506  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
507  ret.push_back((*i).first);
508  }
509  return ret;
510 }
511 
512 
513 // ----- Adapting the input
514 void
516  EdgeVector toRemove;
517  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
518  NBEdge* edge = (*i).second;
519  if (!myEdges2Keep.count(edge->getID())) {
520  edge->getFromNode()->removeEdge(edge);
521  edge->getToNode()->removeEdge(edge);
522  toRemove.push_back(edge);
523  }
524  }
525  for (EdgeVector::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
526  erase(dc, *j);
527  }
528 }
529 
530 
531 void
533  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
534  if ((*i).second->getGeometry().size() < 3) {
535  continue;
536  }
537  (*i).second->splitGeometry(*this, nc);
538  }
539 }
540 
541 
542 void
544  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
545  (*i).second->reduceGeometry(minDist);
546  }
547 }
548 
549 
550 void
551 NBEdgeCont::checkGeometries(const SUMOReal maxAngle, const SUMOReal minRadius, bool fix) {
552  if (maxAngle > 0 || minRadius > 0) {
553  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
554  (*i).second->checkGeometry(maxAngle, minRadius, fix);
555  }
556  }
557 }
558 
559 
560 // ----- processing methods
561 void
563  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); i++) {
564  (*i).second->clearControllingTLInformation();
565  }
566 }
567 
568 
569 void
571  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
572  (*i).second->sortOutgoingConnectionsByAngle();
573  }
574 }
575 
576 
577 void
578 NBEdgeCont::computeEdge2Edges(bool noLeftMovers) {
579  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
580  (*i).second->computeEdge2Edges(noLeftMovers);
581  }
582 }
583 
584 
585 void
586 NBEdgeCont::computeLanes2Edges(const bool buildCrossingsAndWalkingAreas) {
587  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
588  (*i).second->computeLanes2Edges(buildCrossingsAndWalkingAreas);
589  }
590 }
591 
592 
593 void
594 NBEdgeCont::recheckLanes(const bool buildCrossingsAndWalkingAreas) {
595  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
596  (*i).second->recheckLanes(buildCrossingsAndWalkingAreas);
597  }
598 }
599 
600 
601 void
602 NBEdgeCont::appendTurnarounds(bool noTLSControlled) {
603  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
604  (*i).second->appendTurnaround(noTLSControlled);
605  }
606 }
607 
608 
609 void
610 NBEdgeCont::appendTurnarounds(const std::set<std::string>& ids, bool noTLSControlled) {
611  for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); it++) {
612  myEdges[*it]->appendTurnaround(noTLSControlled);
613  }
614 }
615 
616 
617 void
619  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); i++) {
620  (*i).second->computeEdgeShape();
621  }
622 }
623 
624 
625 void
627  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
628  (*i).second->computeLaneShapes();
629  }
630 }
631 
632 
633 void
636  EdgeVector edges) {
637  // !!! Attention!
638  // No merging of the geometry to come is being done
639  // The connections are moved from one edge to another within
640  // the replacement where the edge is a node's incoming edge.
641 
642  // count the number of lanes, the speed and the id
643  unsigned int nolanes = 0;
644  SUMOReal speed = 0;
645  int priority = 0;
646  std::string id;
647  sort(edges.begin(), edges.end(), NBContHelper::same_connection_edge_sorter());
648  // retrieve the connected nodes
649  NBEdge* tpledge = *(edges.begin());
650  NBNode* from = tpledge->getFromNode();
651  NBNode* to = tpledge->getToNode();
652  EdgeVector::const_iterator i;
653  for (i = edges.begin(); i != edges.end(); i++) {
654  // some assertions
655  assert((*i)->getFromNode() == from);
656  assert((*i)->getToNode() == to);
657  // ad the number of lanes the current edge has
658  nolanes += (*i)->getNumLanes();
659  // build the id
660  if (i != edges.begin()) {
661  id += "+";
662  }
663  id += (*i)->getID();
664  // compute the speed
665  speed += (*i)->getSpeed();
666  // build the priority
667  priority = MAX2(priority, (*i)->getPriority());
668  }
669  speed /= edges.size();
670  // build the new edge
671  NBEdge* newEdge = new NBEdge(id, from, to, "", speed, nolanes, priority,
673  tpledge->getStreetName(), tpledge->myLaneSpreadFunction);
674  // copy lane attributes
675  int laneIndex = 0;
676  for (i = edges.begin(); i != edges.end(); ++i) {
677  const std::vector<NBEdge::Lane>& lanes = (*i)->getLanes();
678  for (int j = 0; j < (int)lanes.size(); ++j) {
679  newEdge->setPermissions(lanes[j].permissions, laneIndex);
680  newEdge->setLaneWidth(laneIndex, lanes[j].width);
681  newEdge->setEndOffset(laneIndex, lanes[j].endOffset);
682  laneIndex++;
683  }
684  }
685  insert(newEdge, true);
686  // replace old edge by current within the nodes
687  // and delete the old
688  from->replaceOutgoing(edges, newEdge);
689  to->replaceIncoming(edges, newEdge);
690  // patch connections
691  // add edge2edge-information
692  for (i = edges.begin(); i != edges.end(); i++) {
693  EdgeVector ev = (*i)->getConnectedEdges();
694  for (EdgeVector::iterator j = ev.begin(); j != ev.end(); j++) {
695  newEdge->addEdge2EdgeConnection(*j);
696  }
697  }
698  // move lane2lane-connections
699  unsigned int currLane = 0;
700  for (i = edges.begin(); i != edges.end(); i++) {
701  newEdge->moveOutgoingConnectionsFrom(*i, currLane);
702  currLane += (*i)->getNumLanes();
703  }
704  // patch tl-information
705  currLane = 0;
706  for (i = edges.begin(); i != edges.end(); i++) {
707  unsigned int noLanes = (*i)->getNumLanes();
708  for (unsigned int j = 0; j < noLanes; j++, currLane++) {
709  // replace in traffic lights
710  tlc.replaceRemoved(*i, j, newEdge, currLane);
711  }
712  }
713  // delete joined edges
714  for (i = edges.begin(); i != edges.end(); i++) {
715  erase(dc, *i);
716  }
717 }
718 
719 
720 void
722  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
723  std::string oppositeID;
724  if ((*i).first[0] == '-') {
725  oppositeID = (*i).first.substr(1);
726  } else {
727  oppositeID = "-" + (*i).first;
728  }
729  if (myEdges.find(oppositeID) != myEdges.end()) {
730  (*i).second->setLaneSpreadFunction(LANESPREAD_RIGHT);
731  myEdges.find(oppositeID)->second->setLaneSpreadFunction(LANESPREAD_RIGHT);
732  } else {
733  (*i).second->setLaneSpreadFunction(LANESPREAD_CENTER);
734  }
735  }
736 }
737 
738 
739 
740 // ----- other
741 void
742 NBEdgeCont::addPostProcessConnection(const std::string& from, int fromLane, const std::string& to, int toLane, bool mayDefinitelyPass) {
743  myConnections.push_back(PostProcessConnection(from, fromLane, to, toLane, mayDefinitelyPass));
744 }
745 
746 
747 void
749  for (std::vector<PostProcessConnection>::const_iterator i = myConnections.begin(); i != myConnections.end(); ++i) {
750  NBEdge* from = retrievePossiblySplit((*i).from, true);
751  NBEdge* to = retrievePossiblySplit((*i).to, false);
752  if (from != 0 && to != 0) {
753  if (!from->addLane2LaneConnection((*i).fromLane, to, (*i).toLane, NBEdge::L2L_USER, false, (*i).mayDefinitelyPass)) {
754  WRITE_WARNING("Could not insert connection between '" + (*i).from + "' and '" + (*i).to + "' after build.");
755  }
756  }
757  }
758  // during loading we also kept some ambiguous connections in hope they might be valid after processing
759  // we need to make sure that all invalid connections are removed now
760  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); ++it) {
761  NBEdge* edge = it->second;
762  NBNode* to = edge->getToNode();
763  // make a copy because we may delete connections
764  std::vector<NBEdge::Connection> connections = edge->getConnections();
765  for (std::vector<NBEdge::Connection>::iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
766  NBEdge::Connection& c = *it_con;
767  if (c.toEdge != 0 && c.toEdge->getFromNode() != to) {
768  WRITE_WARNING("Found and removed invalid connection from " + edge->getID() +
769  " to " + c.toEdge->getID() + " via " + to->getID());
770  edge->removeFromConnections(c.toEdge);
771  }
772  }
773  }
774 }
775 
776 
778 NBEdgeCont::getGeneratedFrom(const std::string& id) const {
779  size_t len = id.length();
780  EdgeVector ret;
781  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
782  std::string curr = (*i).first;
783  // the next check makes it possibly faster - we don not have
784  // to compare the names
785  if (curr.length() <= len) {
786  continue;
787  }
788  // the name must be the same as the given id but something
789  // beginning with a '[' must be appended to it
790  if (curr.substr(0, len) == id && curr[len] == '[') {
791  ret.push_back((*i).second);
792  continue;
793  }
794  // ok, maybe the edge is a compound made during joining of edges
795  size_t pos = curr.find(id);
796  // surely not
797  if (pos == std::string::npos) {
798  continue;
799  }
800  // check leading char
801  if (pos > 0) {
802  if (curr[pos - 1] != ']' && curr[pos - 1] != '+') {
803  // actually, this is another id
804  continue;
805  }
806  }
807  if (pos + id.length() < curr.length()) {
808  if (curr[pos + id.length()] != '[' && curr[pos + id.length()] != '+') {
809  // actually, this is another id
810  continue;
811  }
812  }
813  ret.push_back((*i).second);
814  }
815  return ret;
816 }
817 
818 
819 void
821  myGuessedRoundabouts.clear();
822  std::set<NBEdge*> loadedRoundaboutEdges;
823  for (std::set<EdgeSet>::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
824  loadedRoundaboutEdges.insert(it->begin(), it->end());
825  }
826  // step 1: keep only those edges which have no turnarounds and which are not
827  // part of a loaded roundabout
828  std::set<NBEdge*> candidates;
829  for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
830  NBEdge* e = (*i).second;
831  NBNode* const to = e->getToNode();
832  if (e->getTurnDestination() == 0 && to->getConnectionTo(e->getFromNode()) == 0 && loadedRoundaboutEdges.count(e) == 0) {
833  candidates.insert(e);
834  }
835  }
836 
837  // step 2:
838  std::set<NBEdge*> visited;
839  for (std::set<NBEdge*>::const_iterator i = candidates.begin(); i != candidates.end(); ++i) {
840  EdgeVector loopEdges;
841  // start with a random edge (this doesn't have to be a roundabout edge)
842  // loop over connected edges (using always the leftmost one)
843  // and keep the list in loopEdges
844  // continue until we loop back onto a loopEdges and extract the loop
845  NBEdge* e = (*i);
846  if (visited.count(e) > 0) {
847  // already seen
848  continue;
849  }
850  loopEdges.push_back(e);
851  bool doLoop = true;
852  do {
853  visited.insert(e);
854  const EdgeVector& edges = e->getToNode()->getEdges();
855  if (edges.size() < 2) {
856  doLoop = false;
857  break;
858  }
859  if (e->getTurnDestination() != 0 || e->getToNode()->getConnectionTo(e->getFromNode()) != 0) {
860  // do not follow turn-arounds while in a (tentative) loop
861  doLoop = false;
862  break;
863  }
864  EdgeVector::const_iterator me = find(edges.begin(), edges.end(), e);
865  NBContHelper::nextCW(edges, me);
866  NBEdge* left = *me;
867  SUMOReal angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), left->getAngleAtNode(e->getToNode())));
868  if (angle >= 90) {
869  // roundabouts do not have sharp turns (or they wouldn't be called 'round')
870  doLoop = false;
871  break;
872  }
873  EdgeVector::const_iterator loopClosed = find(loopEdges.begin(), loopEdges.end(), left);
874  const size_t loopSize = loopEdges.end() - loopClosed;
875  if (loopSize > 0) {
876  // loop found
877  if (loopSize < 3) {
878  doLoop = false; // need at least 3 edges for a roundabout
879  } else if (loopSize < loopEdges.size()) {
880  // remove initial edges not belonging to the loop
881  EdgeVector(loopEdges.begin() + (loopEdges.size() - loopSize), loopEdges.end()).swap(loopEdges);
882  }
883  // count attachments to the outside. need at least 3 or a roundabout doesn't make much sense
884  int attachments = 0;
885  for (EdgeVector::const_iterator j = loopEdges.begin(); j != loopEdges.end(); ++j) {
886  if ((*j)->getToNode()->getEdges().size() > 2) {
887  attachments++;
888  }
889  }
890  if (attachments < 3) {
891  doLoop = false;
892  }
893  break;
894  }
895  if (visited.count(left) > 0) {
896  doLoop = false;
897  } else {
898  // keep going
899  loopEdges.push_back(left);
900  e = left;
901  }
902  } while (doLoop);
903  if (doLoop) {
904  // collected edges are marked in markRoundabouts
905  myGuessedRoundabouts.insert(EdgeSet(loopEdges.begin(), loopEdges.end()));
906  }
907  }
908 }
909 
910 
911 const std::set<EdgeSet>
913  std::set<EdgeSet> result = myRoundabouts;
914  result.insert(myGuessedRoundabouts.begin(), myGuessedRoundabouts.end());
915  return result;
916 }
917 
918 
919 void
920 NBEdgeCont::addRoundabout(const EdgeSet& roundabout) {
921  if (find(myRoundabouts.begin(), myRoundabouts.end(), roundabout) != myRoundabouts.end()) {
922  WRITE_WARNING("Ignoring duplicate roundabout: " + toString(roundabout));
923  } else {
924  myRoundabouts.insert(roundabout);
925  }
926 }
927 
928 
929 void
931  const std::set<EdgeSet> roundabouts = getRoundabouts();
932  for (std::set<EdgeSet>::const_iterator it = roundabouts.begin(); it != roundabouts.end(); ++it) {
933  const EdgeSet roundaboutSet = *it;
934  for (std::set<NBEdge*>::const_iterator j = roundaboutSet.begin(); j != roundaboutSet.end(); ++j) {
935  // disable turnarounds on incoming edges
936  NBNode* node = (*j)->getToNode();
937  const EdgeVector& incoming = node->getIncomingEdges();
938  for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
939  NBEdge* inEdge = *k;
940  if (roundaboutSet.count(inEdge) > 0) {
941  continue;
942  }
943  if ((inEdge)->getStep() >= NBEdge::LANES2LANES_USER) {
944  continue;
945  }
946  inEdge->removeFromConnections(inEdge->getTurnDestination(), -1);
947  }
948  // let the connections to succeeding roundabout edge have a higher priority
949  (*j)->setJunctionPriority(node, 1000);
950  node->setRoundabout();
951  }
952  }
953 }
954 
955 void
957  for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
958  NBEdge* e = i->second;
959  // is this a "real" junction?
960  // XXX nyi
961  //continue
962  const SUMOReal offset = e->getLength() - 3;
963  switch (e->getToNode()->getType()) {
964  case NODETYPE_PRIORITY:
965  // yield or major?
966  if (e->getJunctionPriority(e->getToNode()) > 0) {
968  } else {
970  }
971  break;
973  // yield or major?
974  if (e->getJunctionPriority(e->getToNode()) > 0) {
976  } else {
978  }
979  break;
982  break;
985  break;
986  default:
987  break;
988  }
989  }
990 }
991 
992 
993 int
994 NBEdgeCont::guessSidewalks(SUMOReal width, SUMOReal minSpeed, SUMOReal maxSpeed, bool fromPermissions) {
995  int sidewalksCreated = 0;
996  for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); it++) {
997  NBEdge* edge = it->second;
998  if ((
999  // guess.from-permissions
1000  (fromPermissions && (edge->getPermissions() & SVC_PEDESTRIAN) != 0)
1001  // guess from speed
1002  || (!fromPermissions && edge->getSpeed() > minSpeed && edge->getSpeed() <= maxSpeed))
1003  // does not yet have a sidewalk
1004  && edge->getPermissions(0) != SVC_PEDESTRIAN) {
1005  edge->addSidewalk(width);
1006  sidewalksCreated += 1;
1007  }
1008  }
1009  return sidewalksCreated;
1010 }
1011 
1012 
1013 /****************************************************************************/
~NBEdgeCont()
Destructor.
Definition: NBEdgeCont.cpp:78
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 ...
Definition: NBEdgeCont.cpp:994
std::vector< Lane > myLanes
Lane information.
Definition: NBEdge.h:1302
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:917
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's incoming edges.
Definition: NBNode.h:251
const std::string & getTypeID() const
Definition: NBEdge.h:905
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:570
bool myAmLeftHanded
Whether the network is left-handed.
Definition: NBEdgeCont.h:588
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
Definition: NBEdgeCont.cpp:930
void setRoundabout()
update the type of this node as a roundabout
Definition: NBNode.cpp:2190
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:275
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:504
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:1085
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:164
NBNode * myTo
Definition: NBEdge.h:1251
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
Definition: NBEdgeCont.cpp:912
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:223
bool myNeedGeoTransformedPrunningBoundary
whether a geo transform has been applied to the pruning boundary
Definition: NBEdgeCont.h:622
A container for traffic light definitions and built programs.
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2156
bool myRemoveEdgesAfterJoining
Whether edges shall be joined first, then removed.
Definition: NBEdgeCont.h:598
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2211
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:510
void moveOutgoingConnectionsFrom(NBEdge *e, unsigned int laneOff)
Definition: NBEdge.cpp:1783
void addSidewalk(SUMOReal width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:2339
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:1097
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:71
A container for districts.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
bool addLane2LaneConnection(unsigned int fromLane, NBEdge *dest, unsigned int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false)
Adds a connection between the specified this edge's lane and an approached one.
Definition: NBEdge.cpp:649
void removeDoubleEdges()
Definition: NBNode.cpp:985
T MAX2(T a, T b)
Definition: StdDefs.h:74
void clearControllingTLInformation() const
Clears information about controlling traffic lights for all connenections of all edges.
Definition: NBEdgeCont.cpp:562
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:2227
void generateStreetSigns()
assigns street signs to edges based on toNode types
Definition: NBEdgeCont.cpp:956
void rename(NBEdge *edge, const std::string &newID)
Renames the edge. Throws exception if newID already exists.
Definition: NBEdgeCont.cpp:392
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:404
void recheckPostProcessConnections()
Try to set any stored connections.
Definition: NBEdgeCont.cpp:748
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:585
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
std::vector< PostProcessConnection > myConnections
The list of connections to recheck.
Definition: NBEdgeCont.h:569
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
void checkGeometries(const SUMOReal maxAngle, const SUMOReal minRadius, bool fix)
Definition: NBEdgeCont.cpp:551
NBEdgeCont(NBTypeCont &tc)
Constructor.
Definition: NBEdgeCont.cpp:69
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's outgoing edges.
Definition: NBNode.h:259
const std::string & getID() const
Returns the id.
Definition: Named.h:60
bool addEdge2EdgeConnection(NBEdge *dest)
Adds a connection to another edge.
Definition: NBEdge.cpp:625
bool overlapsWith(const AbstractPoly &poly, SUMOReal offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:156
static SUMOReal nearest_offset_on_line_to_point2D(const Position &l1, const Position &l2, const Position &p, bool perpendicular=true)
Definition: GeomHelper.cpp:261
SVCPermissions myVehicleClasses2Keep
Set of vehicle types which must be allowed on edges in order to keep them.
Definition: NBEdgeCont.h:607
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:239
void reduceGeometries(const SUMOReal minDist)
Definition: NBEdgeCont.cpp:543
void computeLanes2Edges(const bool buildCrossingsAndWalkingAreas)
Computes for each edge which lanes approach the next edges.
Definition: NBEdgeCont.cpp:586
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
Definition: NBEdge.h:103
std::set< NBEdge * > EdgeSet
Definition: NBCont.h:51
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:170
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:515
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:380
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
void guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
Definition: NBEdgeCont.cpp:820
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
Definition: NBEdgeCont.cpp:84
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:347
std::set< std::string > myEdges2Keep
Set of ids of edges which shall explicitly be kept.
Definition: NBEdgeCont.h:601
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:276
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:578
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
Definition: NBEdgeCont.cpp:626
void setLeftHanded()
Marks this edge to be left-handed.
Definition: NBEdge.h:336
const EdgeVector & getEdges() const
Returns all edges which participate in this node.
Definition: NBNode.h:267
T MIN2(T a, T b)
Definition: StdDefs.h:68
void splitGeometry(NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:532
EdgeCont myEdges
The instance of the dictionary (id->edge)
Definition: NBEdgeCont.h:576
#define POSITION_EPS
Definition: config.h:189
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:155
EdgeCont myExtractedEdges
The extracted nodes which are kept for reference.
Definition: NBEdgeCont.h:579
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:80
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
The connection was given by the user.
Definition: NBEdge.h:114
std::set< EdgeSet > myGuessedRoundabouts
Edges marked as belonging to a roundabout after guessing.
Definition: NBEdgeCont.h:628
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:869
std::set< EdgeSet > myRoundabouts
Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout) ...
Definition: NBEdgeCont.h:626
NBEdge * getConnectionTo(NBNode *n) const
Definition: NBNode.cpp:1484
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
Definition: NBEdge.cpp:1225
void joinSameNodeConnectingEdges(NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, EdgeVector edges)
Joins the given edges because they connect the same nodes.
Definition: NBEdgeCont.cpp:634
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:610
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2255
PositionVector myPrunningBoundary
Boundary within which an edge must be located in order to be kept.
Definition: NBEdgeCont.h:619
SUMOReal length() const
Returns the length.
void push_back(const PositionVector &p)
Appends all positions from the given vector.
std::set< std::string > myTypes2Keep
Set of edges types which shall be kept.
Definition: NBEdgeCont.h:613
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:200
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:371
SUMOReal myEdgesMinSpeed
The minimum speed an edge may have in order to be kept (default: -1)
Definition: NBEdgeCont.h:595
void setID(const std::string &newID)
resets the id
Definition: Named.h:68
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:881
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:258
void appendTurnarounds(bool noTLSControlled)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:602
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:122
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:531
A storage for options typed value containers)
Definition: OptionsCont.h:108
void recheckLanes(const bool buildCrossingsAndWalkingAreas)
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:594
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:373
A structure representing a connection between two lanes.
Definition: NBEdgeCont.h:544
void computeEdgeShapes()
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:618
The connection was computed.
Definition: NBEdge.h:112
Represents a single node (junction) during network building.
Definition: NBNode.h:75
void dismissVehicleClassInformation()
Definition: NBEdge.cpp:2276
NBTypeCont & myTypeCont
The network builder; used to obtain type information.
Definition: NBEdgeCont.h:539
void recheckLaneSpread()
Rechecks whether the lane spread is proper.
Definition: NBEdgeCont.cpp:721
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2195
#define SUMOReal
Definition: config.h:218
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
Definition: NBHelpers.cpp:63
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:616
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:582
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:778
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces occurences of the removed edge/lane in all definitions by the given edge.
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
Definition: NBEdgeCont.cpp:920
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:761
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass)
Adds a connection which could not be set during loading.
Definition: NBEdgeCont.cpp:742
NBNode * myFrom
The source and the destination node.
Definition: NBEdge.h:1251
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2039
bool exists(const std::string &name) const
Returns the information whether the named option is known.
void copyConnectionsFrom(NBEdge *src)
Definition: NBEdge.cpp:977
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:194
A storage for available types of edges.
Definition: NBTypeCont.h:56
SUMOReal getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:406
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's geometry at the given node.
Definition: NBEdge.cpp:1245
std::set< std::string > myEdges2Remove
Set of ids of edges which shall explicitly be removed.
Definition: NBEdgeCont.h:604
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:363