Eclipse SUMO - Simulation of Urban MObility
GNEPathManager.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Manager for paths in netedit (routes, trips, flows...)
19 /****************************************************************************/
20 
21 #include <netbuild/NBNetBuilder.h>
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEViewNet.h>
26 
27 #include "GNEPathManager.h"
28 
29 
30 // ===========================================================================
31 // member method definitions
32 // ===========================================================================
33 
34 // ---------------------------------------------------------------------------
35 // GNEPathManager::Segment - methods
36 // ---------------------------------------------------------------------------
37 
38 GNEPathManager::Segment::Segment(GNEPathManager* pathManager, PathElement* element, const GNELane* lane, std::vector<Segment*>& segments) :
39  myPathManager(pathManager),
40  myPathElement(element),
41  myLane(lane),
42  myJunction(nullptr),
43  myNextSegment(nullptr),
44  myPreviousSegment(nullptr),
45  myLabelSegment(false),
46  myContour(new GNEContour) {
47  // set previous segment
48  if (segments.size() > 0) {
49  // set previous segment
50  myPreviousSegment = segments.back();
52  }
53  // add this segment in segments
54  segments.push_back(this);
55  // add segment in laneSegments
57 }
58 
59 
60 GNEPathManager::Segment::Segment(GNEPathManager* pathManager, PathElement* element, const GNEJunction* junction, std::vector<Segment*>& segments) :
61  myPathManager(pathManager),
62  myPathElement(element),
63  myLane(nullptr),
64  myJunction(junction),
65  myNextSegment(nullptr),
66  myPreviousSegment(nullptr),
67  myLabelSegment(false),
68  myContour(new GNEContour) {
69  // set previous segment
70  if (segments.size() > 0) {
71  // set previous segment
72  myPreviousSegment = segments.back();
74  }
75  // add this segment in segments
76  segments.push_back(this);
77  // add segment in junctionSegments
79 }
80 
81 
83  // clear segment from LaneSegments
84  myPathManager->clearSegmentFromJunctionAndLaneSegments(this);
85  // remove references in previous and next segment
86  if (myPreviousSegment) {
87  myPreviousSegment->myNextSegment = nullptr;
88  }
89  if (myNextSegment) {
90  myNextSegment->myPreviousSegment = nullptr;
91  }
92  // delete contour
93  delete myContour;
94 }
95 
96 
99  return myContour;
100 }
101 
102 
103 bool
105  return (myPreviousSegment == nullptr);
106 }
107 
108 
109 bool
111  return (myNextSegment == nullptr);
112 }
113 
114 
117  return myPathElement;
118 }
119 
120 
121 const GNELane*
123  return myLane;
124 }
125 
126 
127 const GNELane*
129  if (myPreviousSegment) {
130  return myPreviousSegment->getLane();
131  } else {
132  return nullptr;
133  }
134 }
135 
136 
137 const GNELane*
139  if (myNextSegment) {
140  return myNextSegment->getLane();
141  } else {
142  return nullptr;
143  }
144 }
145 
146 
147 const GNEJunction*
149  return myJunction;
150 }
151 
152 
155  return myNextSegment;
156 }
157 
158 
161  return myPreviousSegment;
162 }
163 
164 
165 bool
167  return myLabelSegment;
168 }
169 
170 
171 void
173  myLabelSegment = true;
174 }
175 
176 
178  myPathManager(nullptr),
179  myPathElement(nullptr),
180  myLane(nullptr),
181  myJunction(nullptr),
182  myNextSegment(nullptr),
183  myPreviousSegment(nullptr),
184  myLabelSegment(false) {
185 }
186 
187 // ---------------------------------------------------------------------------
188 // GNEPathManager::PathElement - methods
189 // ---------------------------------------------------------------------------
190 
191 GNEPathManager::PathElement::PathElement(GUIGlObjectType type, const std::string& microsimID, FXIcon* icon, const int options) :
192  GUIGlObject(type, microsimID, icon),
193  myOption(options) {
194 }
195 
196 
198 
199 
200 bool
202  return (myOption & PathElement::Options::NETWORK_ELEMENT) != 0;
203 }
204 
205 
206 bool
208  return (myOption & PathElement::Options::ADDITIONAL_ELEMENT) != 0;
209 }
210 
211 
212 bool
214  return (myOption & PathElement::Options::DEMAND_ELEMENT) != 0;
215 }
216 
217 
218 bool
220  return (myOption & PathElement::Options::DATA_ELEMENT) != 0;
221 }
222 
223 
224 bool
226  return (myOption & PathElement::Options::ROUTE) != 0;
227 }
228 
229 // ---------------------------------------------------------------------------
230 // GNEPathManager::PathCalculator - methods
231 // ---------------------------------------------------------------------------
232 
234  myNet(net),
235  myPathCalculatorUpdated(false),
236  myDijkstraRouter(nullptr) {
237  // create myDijkstraRouter
240  true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
241 }
242 
243 
245  delete myDijkstraRouter;
246 }
247 
248 
249 void
251  // simply delete and create myDijkstraRouter again
252  if (myDijkstraRouter) {
253  delete myDijkstraRouter;
254  }
255  myDijkstraRouter = new DijkstraRouter<NBRouterEdge, NBVehicle>(
256  myNet->getNetBuilder()->getEdgeCont().getAllRouterEdges(),
257  true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
258  // update flag
259  myPathCalculatorUpdated = true;
260 }
261 
262 
263 std::vector<GNEEdge*>
264 GNEPathManager::PathCalculator::calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) const {
265  // declare a solution vector
266  std::vector<GNEEdge*> solution;
267  // check if path calculator is updated
268  if (!myPathCalculatorUpdated) {
269  // use partialEdges as solution
270  solution = edges;
271  return solution;
272  }
273  // calculate route depending of number of partial edges
274  if (edges.size() == 0) {
275  // partial edges empty, then return a empty vector
276  return solution;
277  } else if (edges.size() == 1) {
278  // if there is only one partialEdges, path has only one edge
279  solution.push_back(edges.front());
280  return solution;
281  } else if ((edges.size() == 2) && (edges.front() == edges.back())) {
282  // typical case for stops. Used to avoid unnecesary calls to compute
283  solution.push_back(edges.front());
284  return solution;
285  } else {
286  // declare temporal vehicle
287  NBVehicle tmpVehicle("temporalNBVehicle", vClass);
288  // obtain pointer to GNENet
289  GNENet* net = edges.front()->getNet();
290  // iterate over every selected myEdges
291  for (int i = 1; i < (int)edges.size(); i++) {
292  // ignore consecutive edges
293  if (edges.at(i - 1)->getNBEdge() != edges.at(i)->getNBEdge()) {
294  // declare a temporal route in which save route between two last myEdges
295  std::vector<const NBRouterEdge*> partialRoute;
296  myDijkstraRouter->compute(edges.at(i - 1)->getNBEdge(), edges.at(i)->getNBEdge(), &tmpVehicle, 10, partialRoute);
297  // if partial route is empty, return empty route
298  if (partialRoute.empty()) {
299  return {};
300  } else {
301  // save partial route in solution
302  for (const auto& edgeID : partialRoute) {
303  solution.push_back(net->getAttributeCarriers()->retrieveEdge(edgeID->getID()));
304  }
305  }
306  }
307  }
308  }
309  // filter solution
310  auto solutionIt = solution.begin();
311  // iterate over solution
312  while (solutionIt != solution.end()) {
313  if ((solutionIt + 1) != solution.end()) {
314  // if next edge is the same of current edge, remove it
315  if (*solutionIt == *(solutionIt + 1)) {
316  solutionIt = solution.erase(solutionIt);
317  } else {
318  solutionIt++;
319  }
320  } else {
321  solutionIt++;
322  }
323  }
324  return solution;
325 }
326 
327 
328 std::vector<GNEEdge*>
330  return calculateDijkstraPath(vClass, {fromEdge, toEdge});
331 }
332 
333 
334 std::vector<GNEEdge*>
336  std::vector<GNEEdge*> edges;
337  // get from and to edges
338  const auto toEdges = toJunction->getGNEIncomingEdges();
339  // try to find a path
340  for (const auto& toEdge : toEdges) {
341  edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
342  // if a path was found, clean it
343  if (edges.size() > 0) {
344  return optimizeJunctionPath(edges);
345  }
346  }
347  return {};
348 }
349 
350 
351 std::vector<GNEEdge*>
353  std::vector<GNEEdge*> edges;
354  // get from and to edges
355  const auto fromEdges = fromJunction->getGNEOutgoingEdges();
356  // try to find a path
357  for (const auto& fromEdge : fromEdges) {
358  edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
359  // if a path was found, clean it
360  if (edges.size() > 0) {
361  return optimizeJunctionPath(edges);
362  }
363  }
364  return {};
365 }
366 
367 
368 std::vector<GNEEdge*>
370  std::vector<GNEEdge*> edges;
371  // get from and to edges
372  const auto fromEdges = fromJunction->getGNEOutgoingEdges();
373  const auto toEdges = toJunction->getGNEIncomingEdges();
374  // try to find a path
375  for (const auto& fromEdge : fromEdges) {
376  for (const auto& toEdge : toEdges) {
377  edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
378  // if a path was found, clean it
379  if (edges.size() > 0) {
380  return optimizeJunctionPath(edges);
381  }
382  }
383  }
384  return {};
385 }
386 
387 
388 void
390  // first reset reachability of all lanes
391  for (const auto& edge : originEdge->getNet()->getAttributeCarriers()->getEdges()) {
392  for (const auto& lane : edge.second->getLanes()) {
393  lane->resetReachability();
394  }
395  }
396  // get max speed
397  const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(vClass).maxSpeed;
398  // declare map for reachable edges
399  std::map<GNEEdge*, double> reachableEdges;
400  // init first edge
401  reachableEdges[originEdge] = 0;
402  // declare a vector for checked edges
403  std::vector<GNEEdge*> check;
404  // add first edge
405  check.push_back(originEdge);
406  // continue while there is edges to check
407  while (check.size() > 0) {
408  GNEEdge* edge = check.front();
409  check.erase(check.begin());
410  double traveltime = reachableEdges[edge];
411  for (const auto& lane : edge->getLanes()) {
412  if ((edge->getNBEdge()->getLaneStruct(lane->getIndex()).permissions & vClass) == vClass) {
413  lane->setReachability(traveltime);
414  }
415  }
416  // update traveltime
417  traveltime += edge->getNBEdge()->getLength() / MIN2(edge->getNBEdge()->getSpeed(), defaultMaxSpeed);
418  std::vector<GNEEdge*> sucessors;
419  // get successor edges
420  for (const auto& sucessorEdge : edge->getToJunction()->getGNEOutgoingEdges()) {
421  // check if edge is connected with successor edge
422  if (consecutiveEdgesConnected(vClass, edge, sucessorEdge)) {
423  sucessors.push_back(sucessorEdge);
424  }
425  }
426  // add successors to check vector
427  for (const auto& nextEdge : sucessors) {
428  // revisit edge via faster path
429  if ((reachableEdges.count(nextEdge) == 0) || (reachableEdges[nextEdge] > traveltime)) {
430  reachableEdges[nextEdge] = traveltime;
431  check.push_back(nextEdge);
432  }
433  }
434  }
435 }
436 
437 
438 bool
440  // check conditions
441  if ((from == nullptr) || (to == nullptr)) {
442  // myEdges cannot be null
443  return false;
444  } else if (from == to) {
445  // the same edge cannot be consecutive of itself
446  return false;
447  } else if (vClass == SVC_PEDESTRIAN) {
448  // for pedestrians consecutive myEdges are always connected
449  return true;
450  } else {
451  // iterate over connections of from edge
452  for (const auto& fromLane : from->getLanes()) {
453  for (const auto& fromConnection : from->getGNEConnections()) {
454  // within from loop, iterate ove to lanes
455  for (const auto& toLane : to->getLanes()) {
456  if (fromConnection->getLaneTo() == toLane) {
457  // get lane structs for both lanes
458  const NBEdge::Lane NBFromLane = from->getNBEdge()->getLaneStruct(fromLane->getIndex());
459  const NBEdge::Lane NBToLane = to->getNBEdge()->getLaneStruct(toLane->getIndex());
460  // check vClass
461  if (((NBFromLane.permissions & vClass) == vClass) &&
462  ((NBToLane.permissions & vClass) == vClass)) {
463  return true;
464  }
465  }
466  }
467  }
468  }
469  return false;
470  }
471 }
472 
473 
474 bool
476  if (busStop->getTagProperty().getTag() != SUMO_TAG_BUS_STOP) {
477  return false;
478  }
479  // check if busstop is placed over a pedestrian lane
480  if ((busStop->getParentLanes().front()->getParentEdge() == edge) &&
481  (edge->getNBEdge()->getLaneStruct(busStop->getParentLanes().front()->getIndex()).permissions & SVC_PEDESTRIAN) != 0) {
482  // busStop is placed over an lane that supports pedestrians, then return true
483  return true;
484  }
485  // obtain a list with all edge lanes that supports pedestrians
486  std::vector<GNELane*> pedestrianLanes;
487  for (int laneIndex = 0; laneIndex < (int)edge->getLanes().size(); laneIndex++) {
488  if ((edge->getNBEdge()->getLaneStruct(laneIndex).permissions & SVC_PEDESTRIAN) != 0) {
489  pedestrianLanes.push_back(edge->getLanes().at(laneIndex));
490  }
491  }
492  // check if exist an access between busStop and pedestrian lanes
493  for (const auto& access : busStop->getChildAdditionals()) {
494  // check that child is an access
495  if (access->getTagProperty().getTag() == SUMO_TAG_ACCESS) {
496  for (const auto& lane : pedestrianLanes) {
497  if (access->getParentLanes().front() == lane) {
498  // found, then return true
499  return true;
500  }
501  }
502  }
503  }
504  // There isn't a valid access, then return false
505  return false;
506 }
507 
508 
509 bool
511  return myPathCalculatorUpdated;
512 }
513 
514 
515 void
517  myPathCalculatorUpdated = false;
518 }
519 
520 
521 std::vector<GNEEdge*>
522 GNEPathManager::PathCalculator::optimizeJunctionPath(const std::vector<GNEEdge*>& edges) const {
523  bool stop = false;
524  std::vector<GNEEdge*> solutionA, solutionB;
525  // get from and to junctions
526  const auto fromJunction = edges.front()->getFromJunction();
527  const auto toJunction = edges.back()->getToJunction();
528  // first optimize from Junction
529  for (auto it = edges.rbegin(); (it != edges.rend()) && !stop; it++) {
530  solutionA.insert(solutionA.begin(), *it);
531  if ((*it)->getFromJunction() == fromJunction) {
532  stop = true;
533  }
534  }
535  // optimize to edge
536  stop = false;
537  for (auto it = solutionA.begin(); (it != solutionA.end()) && !stop; it++) {
538  solutionB.push_back(*it);
539  if ((*it)->getToJunction() == toJunction) {
540  stop = true;
541  }
542  }
543  return solutionB;
544 }
545 
546 // ---------------------------------------------------------------------------
547 // GNEPathManager::PathDraw - methods
548 // ---------------------------------------------------------------------------
549 
551 
552 
554 
555 
556 void
558  // just clear myDrawedElements
559  myLaneDrawedElements.clear();
560  myLane2laneDrawedElements.clear();
561 }
562 
563 
564 bool
566  // check conditions
568  return true;
569  } else if (myLaneDrawedElements.count(lane) > 0) {
570  // check tag
571  if (myLaneDrawedElements.at(lane).count(tag) > 0) {
572  // element type was already inserted, then don't draw geometry
573  return false;
574  } else {
575  // insert tag for the given lane
576  myLaneDrawedElements.at(lane).insert(tag);
577  // draw geometry
578  return true;
579  }
580  } else {
581  // insert lane and tag
582  myLaneDrawedElements[lane].insert(tag);
583  // draw geometry
584  return true;
585  }
586 }
587 
588 
589 bool
591  // check conditions
593  return true;
594  } else {
595  // declare lane2lane
596  const std::pair<const GNELane*, const GNELane*> lane2lane(segment->getPreviousLane(), segment->getNextLane());
597  // check lane2lane
598  if (myLane2laneDrawedElements.count(lane2lane) > 0) {
599  // check tag
600  if (myLane2laneDrawedElements.at(lane2lane).count(tag) > 0) {
601  // element type was already inserted, then don't draw geometry
602  return false;
603  } else {
604  // insert tag for the given lane2lane
605  myLane2laneDrawedElements.at(lane2lane).insert(tag);
606  // draw geometry
607  return true;
608  }
609  } else {
610  // insert lane2lane and tag
611  myLane2laneDrawedElements[lane2lane].insert(tag);
612  // draw geometry
613  return true;
614  }
615  }
616 }
617 
618 // ---------------------------------------------------------------------------
619 // GNEPathManager - methods
620 // ---------------------------------------------------------------------------
621 
624  myPathDraw(new PathDraw()) {
625 }
626 
627 
629  // clear paths
630  clearSegments();
631  // delete route calculator Instance
632  delete myPathCalculator;
633  // delete path draw
634  delete myPathDraw;
635 }
636 
637 
640  return myPathCalculator;
641 }
642 
643 
646  // first parse pathElement
647  const auto pathElement = dynamic_cast<const GNEPathManager::PathElement*>(GLObject);
648  if (pathElement == nullptr) {
649  return nullptr;
650  } else {
651  // find it in paths
652  auto it = myPaths.find(pathElement);
653  if (it == myPaths.end()) {
654  return nullptr;
655  } else {
656  return it->first;
657  }
658  }
659 }
660 
661 
662 const std::vector<GNEPathManager::Segment*>&
664  if (myPaths.count(pathElement) > 0) {
665  return myPaths.at(pathElement);
666  } else {
667  return myEmptySegments;
668  }
669 }
670 
671 
674  return myPathDraw;
675 }
676 
677 
678 bool
679 GNEPathManager::isPathValid(const PathElement* pathElement) const {
680  // first check if path element exist
681  if (myPaths.count(pathElement) > 0) {
682  // iterate over all segments
683  for (const auto& segment : myPaths.at(pathElement)) {
684  // if we have two consecutive lane segments, then path isn't valid
685  if (segment->getLane() && segment->getNextLane()) {
686  return false;
687  }
688  }
689  // all ok, then return true
690  return true;
691  } else {
692  return false;
693  }
694 }
695 
696 
697 const GNELane*
698 GNEPathManager::getFirstLane(const PathElement* pathElement) const {
699  if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
700  return myPaths.at(pathElement).front()->getLane();
701  } else {
702  return nullptr;
703  }
704 }
705 
706 
707 
708 void
709 GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNELane* fromLane, GNELane* toLane) {
710  // build path
711  buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toLane->getParentEdge()),
712  fromLane, nullptr, toLane, nullptr);
713 }
714 
715 
716 void
717 GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNELane* fromLane, GNEJunction* toJunction) {
718  // build path
719  buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toJunction),
720  fromLane, nullptr, nullptr, toJunction);
721 }
722 
723 
724 void
725 GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNEJunction* fromJunction, GNELane* toLane) {
726  // build path
727  buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toLane->getParentEdge()),
728  nullptr, fromJunction, toLane, nullptr);
729 }
730 
731 
732 void
733 GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEJunction* toJunction) {
734  // build path
735  buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toJunction), nullptr, fromJunction, nullptr, toJunction);
736 }
737 
738 
739 void
740 GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
741  // build path
742  if (edges.size() > 0) {
743  buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, edges),
744  edges.front()->getLaneByAllowedVClass(vClass), nullptr, edges.back()->getLaneByAllowedVClass(vClass), nullptr);
745  } else {
746  removePath(pathElement);
747  }
748 }
749 
750 
751 void
752 GNEPathManager::calculateConsecutivePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
753  // declare lane vector
754  std::vector<GNELane*> lanes;
755  // reserve lanes
756  lanes.reserve(edges.size());
757  // get first allowed lane of every edge
758  for (const auto& edge : edges) {
759  lanes.push_back(edge->getLaneByAllowedVClass(vClass));
760  }
761  // calculate consecutive path lanes
762  calculateConsecutivePathLanes(pathElement, lanes);
763 }
764 
765 
766 void
767 GNEPathManager::calculateConsecutivePathLanes(PathElement* pathElement, const std::vector<GNELane*> lanes) {
768  // first remove path element from paths
769  removePath(pathElement);
770  // continue depending of number of lanes
771  if (lanes.size() > 0) {
772  // declare segment vector
773  std::vector<Segment*> segments;
774  // declare last index
775  const int lastIndex = ((int)lanes.size() - 1);
776  // reserve segments
777  segments.reserve(2 * lanes.size());
778  // iterate over lanes
779  for (int i = 0; i < (int)lanes.size(); i++) {
780  // create lane segment
781  new Segment(this, pathElement, lanes.at(i), segments);
782  // continue if this isn't the last lane
783  if (i != lastIndex) {
784  // create junction segments
785  new Segment(this, pathElement, lanes.at(i)->getParentEdge()->getToJunction(), segments);
786  }
787  }
788  // mark label segment
789  markLabelSegment(segments);
790  // add segments in paths
791  myPaths[pathElement] = segments;
792  }
793 }
794 
795 
796 void
798  // check if path element exist already in myPaths
799  if (myPaths.find(pathElement) != myPaths.end()) {
800  // delete segments
801  for (const auto& segment : myPaths.at(pathElement)) {
802  delete segment;
803  }
804  // remove path element from myPaths
805  myPaths.erase(pathElement);
806  }
807 }
808 
809 
810 void
812  // check detail level and lane segments
813  if (myLaneSegments.count(lane) > 0) {
814  int numRoutes = 0;
815  // first draw selected elements (for drawing over other elements)
816  for (const auto& segment : myLaneSegments.at(lane)) {
817  if (segment->getPathElement()->isPathElementSelected()) {
818  // draw segment
819  segment->getPathElement()->drawLanePartialGL(s, segment, 2);
820  // check if path element is a route
821  if (segment->getPathElement()->isRoute()) {
822  numRoutes++;
823  }
824  }
825  }
826  // now draw non selected elements
827  for (const auto& segment : myLaneSegments.at(lane)) {
828  if (!segment->getPathElement()->isPathElementSelected()) {
829  // draw segment
830  segment->getPathElement()->drawLanePartialGL(s, segment, 0);
831  // check if path element is a route
832  if (segment->getPathElement()->isRoute()) {
833  numRoutes++;
834  }
835  }
836  }
837  // check if draw overlapped routes
838  if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
839  lane->drawOverlappedRoutes(numRoutes);
840  }
841  }
842 }
843 
844 
845 void
847  // check detail level and junction segments
848  if (myJunctionSegments.count(junction) > 0) {
849  // first draw selected elements (for drawing over other elements)
850  for (const auto& segment : myJunctionSegments.at(junction)) {
851  if (segment->getPathElement()->isPathElementSelected()) {
852  segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
853  }
854  }
855  // now draw non selected elements
856  for (const auto& segment : myJunctionSegments.at(junction)) {
857  if (!segment->getPathElement()->isPathElementSelected()) {
858  segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
859  }
860  }
861  }
862 }
863 
864 
865 void
867  // draw all lane segments
868  for (const auto& laneSegment : myLaneSegments) {
869  for (const auto& segment : laneSegment.second) {
870  if (segment->getPathElement() == pathElement) {
871  pathElement->drawLanePartialGL(s, segment, 0);
872  }
873  }
874  }
875  // draw all junction segments
876  for (const auto& junctionSegment : myJunctionSegments) {
877  for (const auto& segment : junctionSegment.second) {
878  if (segment->getPathElement() == pathElement) {
879  segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
880  }
881  }
882  }
883 }
884 
885 
886 void
888  // declare vector for path elements to compute
889  std::vector<PathElement*> pathElementsToCompute;
890  // check lane in laneSegments
891  if (myLaneSegments.count(lane) > 0) {
892  // obtain affected path elements
893  for (const auto& segment : myLaneSegments.at(lane)) {
894  pathElementsToCompute.push_back(segment->getPathElement());
895  }
896  }
897  // compute path elements
898  for (const auto& pathElement : pathElementsToCompute) {
899  pathElement->computePathElement();
900  }
901 }
902 
903 
904 void
906  // declare vector for path elements to compute
907  std::vector<PathElement*> pathElementsToCompute;
908  // check junction in junctionSegments
909  if (myJunctionSegments.count(junction) > 0) {
910  // obtain affected path elements
911  for (const auto& segment : myJunctionSegments.at(junction)) {
912  pathElementsToCompute.push_back(segment->getPathElement());
913  }
914  }
915  // compute path elements
916  for (const auto& pathElement : pathElementsToCompute) {
917  pathElement->computePathElement();
918  }
919 }
920 
921 
922 void
924  // declare iterator
925  auto it = myPaths.begin();
926  // iterate over paths
927  while (it != myPaths.end()) {
928  if (it->first->isDemandElement()) {
929  // delete all segments
930  for (const auto& segment : it->second) {
931  delete segment;
932  }
933  // remove path
934  it = myPaths.erase(it);
935  } else {
936  it++;
937  }
938  }
939 }
940 
941 
942 void
944  myLaneSegments[lane].push_back(segment);
945 }
946 
947 
948 void
950  myJunctionSegments[junction].push_back(segment);
951 }
952 
953 
954 void
956  // check if segment has a lane
957  if (segment->getLane()) {
958  auto lane = segment->getLane();
959  // remove segment from segments associated with lane
960  auto it = myLaneSegments.at(lane).begin();
961  while (it != myLaneSegments.at(lane).end()) {
962  if (*it == segment) {
963  it = myLaneSegments.at(lane).erase(it);
964  } else {
965  it++;
966  }
967  }
968  // clear lane if doesn't have more segments
969  if (myLaneSegments.at(lane).empty()) {
970  myLaneSegments.erase(lane);
971  }
972  }
973  if (segment->getJunction()) {
974  auto junction = segment->getJunction();
975  // remove segment from segments associated with junction
976  auto it = myJunctionSegments.at(junction).begin();
977  while (it != myJunctionSegments.at(junction).end()) {
978  if (*it == segment) {
979  it = myJunctionSegments.at(junction).erase(it);
980  } else {
981  it++;
982  }
983  }
984  // clear junction if doesn't have more segments
985  if (myJunctionSegments.at(junction).empty()) {
986  myJunctionSegments.erase(junction);
987  }
988  }
989 }
990 
991 
992 void
994  // first iterate over paths
995  for (const auto& path : myPaths) {
996  // delete all segments
997  for (const auto& segment : path.second) {
998  delete segment;
999  }
1000  }
1001  // clear paths
1002  myPaths.clear();
1003 }
1004 
1005 
1006 bool
1007 GNEPathManager::connectedLanes(const GNELane* fromLane, const GNELane* toLane) const {
1008  // get from and to NBEdges
1009  NBEdge* fromNBEdge = fromLane->getParentEdge()->getNBEdge();
1010  NBEdge* toNBEdge = toLane->getParentEdge()->getNBEdge();
1011  // get connections vinculated with from Lane
1012  const std::vector<NBEdge::Connection> connections = fromNBEdge->getConnectionsFromLane(fromLane->getIndex());
1013  // find connection
1014  std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
1015  connections.begin(), connections.end(),
1016  NBEdge::connections_finder(fromLane->getIndex(), toNBEdge, toLane->getIndex()));
1017  // check if connection was found
1018  return (con_it != connections.end());
1019 }
1020 
1021 
1022 void
1023 GNEPathManager::buildPath(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> path,
1024  GNELane* fromLane, GNEJunction* fromJunction, GNELane* toLane, GNEJunction* toJunction) {
1025  // first remove path element from paths
1026  removePath(pathElement);
1027  // declare segment vector
1028  std::vector<Segment*> segments;
1029  // continue if path isn't empty
1030  if (path.size() > 0) {
1031  // declare last index
1032  const int lastIndex = ((int)path.size() - 1);
1033  // reserve segments
1034  segments.reserve(2 * path.size());
1035  if (fromJunction) {
1036  // create lane segment using fromJunction
1037  new Segment(this, pathElement, fromJunction, segments);
1038  }
1039  // iterate over path
1040  for (int i = 0; i < (int)path.size(); i++) {
1041  if ((i == 0) && fromLane) {
1042  // create lane segment using fromLane
1043  new Segment(this, pathElement, fromLane, segments);
1044  // continue if this isn't the last path edge
1045  if (i != lastIndex) {
1046  // create junction segment using to junction
1047  new Segment(this, pathElement, path.at(i)->getToJunction(), segments);
1048  }
1049  } else if ((i == lastIndex) && toLane) {
1050  // create lane segment using toLane
1051  new Segment(this, pathElement, toLane, segments);
1052  } else {
1053  // get first allowed lane
1054  const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
1055  // create lane segment
1056  new Segment(this, pathElement, lane, segments);
1057  // continue if this isn't the last path edge
1058  if (i != lastIndex) {
1059  // create junction segment using to junction
1060  new Segment(this, pathElement, path.at(i)->getToJunction(), segments);
1061  }
1062  }
1063  }
1064  if (toJunction) {
1065  // create lane segment using toJunction
1066  new Segment(this, pathElement, toJunction, segments);
1067  }
1068  // mark label segment
1069  markLabelSegment(segments);
1070  // add segments in paths
1071  myPaths[pathElement] = segments;
1072  } else {
1073  // create first segment
1074  Segment* firstSegment = nullptr;
1075  Segment* lastSegment = nullptr;
1076  // continue depending of from-to elements
1077  if (fromLane) {
1078  firstSegment = new Segment(this, pathElement, fromLane, segments);
1079  } else if (fromJunction) {
1080  firstSegment = new Segment(this, pathElement, fromJunction, segments);
1081  }
1082  if (toLane) {
1083  lastSegment = new Segment(this, pathElement, toLane, segments);
1084  } else if (toJunction) {
1085  lastSegment = new Segment(this, pathElement, toJunction, segments);
1086  }
1087  // continue depending of segments
1088  if (firstSegment && lastSegment) {
1089  // mark segment as label segment
1090  firstSegment->markSegmentLabel();
1091  // add segments in path
1092  myPaths[pathElement] = segments;
1093  } else {
1094  delete firstSegment;
1095  delete lastSegment;
1096  }
1097  }
1098 }
1099 
1100 
1101 void
1102 GNEPathManager::markLabelSegment(const std::vector<Segment*>& segments) const {
1103  // separate junction segments and lane segments
1104  std::vector<Segment*> laneSegments;
1105  laneSegments.reserve(segments.size());
1106  for (const auto& segment : segments) {
1107  if (segment->getLane()) {
1108  laneSegments.push_back(segment);
1109  }
1110  }
1111  // get lane segment index
1112  const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
1113  // mark middle label as label segment
1114  laneSegments.at(laneSegmentIndex)->markSegmentLabel();
1115 }
1116 
1117 /****************************************************************************/
GUIGlObjectType
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PEDESTRIAN
pedestrian
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
T MIN2(T a, T b)
Definition: StdDefs.h:76
Computes the shortest path through a network using the Dijkstra algorithm.
An Element which don't belong to GNENet but has influence in the simulation.
Definition: GNEAdditional.h:49
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * getNet() const
get pointer to net
void setReachability(const double reachability)
set current reachability (traveltime)
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:753
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:82
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:1090
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:1096
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:615
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition: GNELane.cpp:1684
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:196
const std::map< std::string, GNEEdge * > & getEdges() const
map with the ID and pointer to edges of net
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1540
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:123
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2136
class used to calculate paths in nets
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges) const
calculate Dijkstra path between a list of edges (for example, from-via-to edges)
bool consecutiveEdgesConnected(const SUMOVehicleClass vClass, const GNEEdge *from, const GNEEdge *to) const
check if exist a path between the two given consecutive edges for the given VClass
void updatePathCalculator()
update path calculator (called when SuperModes Demand or Data is selected)
bool isPathCalculatorUpdated() const
check if pathCalculator is updated
SUMOAbstractRouter< NBRouterEdge, NBVehicle > * myDijkstraRouter
SUMO Abstract myDijkstraRouter.
void invalidatePathCalculator()
invalidate pathCalculator
void calculateReachability(const SUMOVehicleClass vClass, GNEEdge *originEdge)
calculate reachability for given edge
std::vector< GNEEdge * > optimizeJunctionPath(const std::vector< GNEEdge * > &edges) const
optimize junction path
PathCalculator(const GNENet *net)
constructor
bool busStopConnected(const GNEAdditional *busStop, const GNEEdge *edge) const
check if exist a path between the given busStop and edge (Either a valid lane or an acces) for pedest...
const GNENet * myNet
pointer to net
class used to mark path draw
bool checkDrawPathGeometry(const GUIVisualizationSettings &s, const GNELane *lane, SumoXMLTag tag)
check if path element geometry must be drawn in the given lane
void clearPathDraw()
clear path draw
class used for path elements
virtual void drawLanePartialGL(const GUIVisualizationSettings &s, const GNEPathManager::Segment *segment, const double offsetFront) const =0
Draws partial object over lane.
bool isDataElement() const
check if pathElement is a data element
bool isDemandElement() const
check if pathElement is a demand element
bool isNetworkElement() const
check if pathElement is a network element
virtual ~PathElement()
destructor
bool isAdditionalElement() const
check if pathElement is an additional element
bool isRoute() const
check if pathElement is a route
PathElement()=delete
invalidate default constructor
const GNELane * getPreviousLane() const
get previous lane
Segment * myNextSegment
pointer to next segment (use for draw red line)
PathElement * getPathElement() const
get path element
Segment * getPreviousSegment() const
get previous segment
GNEContour * getContour() const
getcontour associated with segment
GNEPathManager * myPathManager
path manager
const GNEJunction * getJunction() const
get junction associated with this segment
const GNELane * getNextLane() const
get next lane
Segment * myPreviousSegment
pointer to previous segment (use for draw red line)
bool isLabelSegment() const
check if segment is label segment
void markSegmentLabel()
mark segment as middle segment
Segment()
default constructor
Segment * getNextSegment() const
get next segment
const GNELane * getLane() const
get lane associated with this segment
bool isLastSegment() const
check if segment is the last path's segment
bool isFirstSegment() const
check if segment is the first path's segment
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
const std::vector< Segment * > & getPathElementSegments(PathElement *pathElement) const
get path segments
const std::vector< Segment * > myEmptySegments
empty segments (used in getPathElementSegments)
void addSegmentInJunctionSegments(Segment *segment, const GNEJunction *junction)
add segments int junctionSegments (called by Segment constructor)
void invalidateJunctionPath(const GNEJunction *junction)
invalidate junction path
const PathElement * getPathElement(const GUIGlObject *GLObject) const
get path element
PathDraw * getPathDraw()
obtain instance of PathDraw
void clearSegments()
clear segments
std::map< const GNELane *, std::vector< Segment * > > myLaneSegments
map with lane segments
void markLabelSegment(const std::vector< Segment * > &segments) const
mark label segment
PathCalculator * myPathCalculator
PathCalculator instance.
void invalidateLanePath(const GNELane *lane)
invalidate lane path
void clearDemandPaths()
clear demand paths
void calculateConsecutivePathEdges(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > edges)
calculate consecutive path edges
void addSegmentInLaneSegments(Segment *segment, const GNELane *lane)
add segments int laneSegments (called by Segment constructor)
bool connectedLanes(const GNELane *fromLane, const GNELane *toLane) const
check if given lanes are connected
std::map< const PathElement *, std::vector< Segment * > > myPaths
map with path element and their associated segments
void removePath(PathElement *pathElement)
remove path
void drawLanePathElements(const GUIVisualizationSettings &s, const GNELane *lane) const
draw lane path elements
std::map< const GNEJunction *, std::vector< Segment * > > myJunctionSegments
map with junction segments
void drawJunctionPathElements(const GUIVisualizationSettings &s, const GNEJunction *junction) const
draw junction path elements
void clearSegmentFromJunctionAndLaneSegments(Segment *segment)
clear segments from junction and lane Segments (called by Segment destructor)
PathDraw * myPathDraw
PathDraw instance.
void forceDrawPath(const GUIVisualizationSettings &s, const PathElement *pathElement) const
force draw path (used carefully, ONLY when we're inspecting a path element, due slowdowns)
void buildPath(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > path, GNELane *fromLane, GNEJunction *fromJunction, GNELane *toLane, GNEJunction *toJunction)
build path
~GNEPathManager()
destructor
const GNELane * getFirstLane(const PathElement *pathElement) const
get first lane associated with path element
GNEPathManager(const GNENet *net)
constructor
bool isPathValid(const PathElement *pathElement) const
check if path element is valid
void calculatePath(PathElement *pathElement, SUMOVehicleClass vClass, GNELane *fromLane, GNELane *toLane)
calculate path between from-to edges (using dijkstra, require path calculator updated)
void calculateConsecutivePathLanes(PathElement *pathElement, const std::vector< GNELane * > lanes)
calculate consecutive path lanes
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:741
Stores the information about how to visualize structures.
bool drawForViewObjectsHandler
whether drawing is performed for the purpose of selecting objects in view using ViewObjectsHandler
RouterEdgeVector getAllRouterEdges() const
return all router edges
The representation of a single edge during network building.
Definition: NBEdge.h:92
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:589
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:615
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1280
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1424
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:139
static double getTravelTimeStatic(const NBRouterEdge *const edge, const NBVehicle *const, double)
Definition: NBEdge.h:82
A vehicle as used by router.
Definition: NBVehicle.h:42
bool showOverlappedRoutes() const
show overlapped routes
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:143
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
Definition: NBEdge.h:157
struct for default values that depend of VClass
double maxSpeed
The vehicle type's maximum speed [m/s] (technical limit, not subject to speed deviation)