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