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