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.org/sumo
3// Copyright (C) 2001-2022 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
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
39 const bool firstSegment, const bool lastSegment) :
40 myPathManager(pathManager),
41 myPathElement(element),
42 myFirstSegment(firstSegment),
43 myLastSegment(lastSegment),
44 myLane(lane),
45 myPreviousLane(nullptr),
46 myNextLane(nullptr),
47 myJunction(nullptr),
48 myNextSegment(nullptr),
49 myPreviousSegment(nullptr),
50 myLabelSegment(false) {
51 // add segment in laneSegments
53}
54
55
57 const GNELane* previousLane, const GNELane* nextLane) :
58 myPathManager(pathManager),
59 myPathElement(element),
60 myFirstSegment(false),
61 myLastSegment(false),
62 myLane(nullptr),
63 myPreviousLane(previousLane),
64 myNextLane(nextLane),
65 myJunction(junction),
66 myNextSegment(nullptr),
67 myPreviousSegment(nullptr),
68 myLabelSegment(false) {
69 // add segment in junctionSegments
71}
72
73
75 // clear segment from LaneSegments
76 myPathManager->clearSegmentFromJunctionAndLaneSegments(this);
77}
78
79
80bool
82 if (myLane) {
83 return myFirstSegment;
84 } else {
85 throw ProcessError("Invalid call: Only allowed in lane segments");
86 }
87}
88
89
90bool
92 if (myLane) {
93 return myLastSegment;
94 } else {
95 throw ProcessError("Invalid call: Only allowed in lane segments");
96 }
97}
98
99
102 return myPathElement;
103}
104
105
106const GNELane*
108 return myLane;
109}
110
111
112const GNELane*
114 if (myJunction) {
115 return myPreviousLane;
116 } else {
117 throw ProcessError("Invalid call: Only allowed in junction segments");
118 }
119}
120
121
122const GNELane*
124 if (myJunction) {
125 return myNextLane;
126 } else {
127 throw ProcessError("Invalid call: Only allowed in junction segments");
128 }
129}
130
131
132const GNEJunction*
134 return myJunction;
135}
136
137
140 return myNextSegment;
141}
142
143
144void
146 myNextSegment = nextSegment;
147}
148
149
152 return myPreviousSegment;
153}
154
155
156void
158 myPreviousSegment = previousSegment;
159}
160
161
162bool
164 return myLabelSegment;
165}
166
167
168void
170 myLabelSegment = true;
171}
172
173
175 myPathManager(nullptr),
176 myPathElement(nullptr),
177 myFirstSegment(false),
178 myLastSegment(false),
179 myLane(nullptr),
180 myPreviousLane(nullptr),
181 myNextLane(nullptr),
182 myJunction(nullptr),
183 myNextSegment(nullptr),
184 myPreviousSegment(nullptr),
185 myLabelSegment(false) {
186}
187
188// ---------------------------------------------------------------------------
189// GNEPathManager::PathElement - methods
190// ---------------------------------------------------------------------------
191
192GNEPathManager::PathElement::PathElement(GUIGlObjectType type, const std::string& microsimID, FXIcon* icon, const int options) :
193 GUIGlObject(type, microsimID, icon),
194 myOption(options) {
195}
196
197
199
200
201bool
203 return (myOption & PathElement::Options::NETWORK_ELEMENT) != 0;
204}
205
206
207bool
209 return (myOption & PathElement::Options::ADDITIONAL_ELEMENT) != 0;
210}
211
212
213bool
215 return (myOption & PathElement::Options::DEMAND_ELEMENT) != 0;
216}
217
218
219bool
221 return (myOption & PathElement::Options::DATA_ELEMENT) != 0;
222}
223
224
225bool
227 return (myOption & PathElement::Options::ROUTE) != 0;
228}
229
230// ---------------------------------------------------------------------------
231// GNEPathManager::PathCalculator - methods
232// ---------------------------------------------------------------------------
233
235 myNet(net),
236 myPathCalculatorUpdated(false),
237 myDijkstraRouter(nullptr) {
238 // create myDijkstraRouter
241 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
242}
243
244
246 delete myDijkstraRouter;
247}
248
249
250void
252 // simply delete and create myDijkstraRouter again
253 if (myDijkstraRouter) {
254 delete myDijkstraRouter;
255 }
256 myDijkstraRouter = new DijkstraRouter<NBRouterEdge, NBVehicle>(
257 myNet->getNetBuilder()->getEdgeCont().getAllRouterEdges(),
258 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
259 // update flag
260 myPathCalculatorUpdated = true;
261}
262
263
264std::vector<GNEEdge*>
265GNEPathManager::PathCalculator::calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector<GNEEdge*>& partialEdges) const {
266 // declare a solution vector
267 std::vector<GNEEdge*> solution;
268 // calculate route depending of number of partial myEdges
269 if (partialEdges.size() == 0) {
270 // partial edges empty, then return a empty vector
271 return solution;
272 }
273 // check if path calculator is updated
274 if (!myPathCalculatorUpdated) {
275 // use partialEdges as solution
276 solution = partialEdges;
277 return solution;
278 }
279 if (partialEdges.size() == 1) {
280 // if there is only one partialEdges, route has only one edge
281 solution.push_back(partialEdges.front());
282 return solution;
283 } else {
284 // declare temporal vehicle
285 NBVehicle tmpVehicle("temporalNBVehicle", vClass);
286 // obtain pointer to GNENet
287 GNENet* net = partialEdges.front()->getNet();
288 // iterate over every selected myEdges
289 for (int i = 1; i < (int)partialEdges.size(); i++) {
290 // declare a temporal route in which save route between two last myEdges
291 std::vector<const NBRouterEdge*> partialRoute;
292 myDijkstraRouter->compute(partialEdges.at(i - 1)->getNBEdge(), partialEdges.at(i)->getNBEdge(), &tmpVehicle, 10, partialRoute);
293 // save partial route in solution
294 for (const auto& edgeID : partialRoute) {
295 solution.push_back(net->getAttributeCarriers()->retrieveEdge(edgeID->getID()));
296 }
297 }
298 }
299 // filter solution
300 auto solutionIt = solution.begin();
301 // iterate over solution
302 while (solutionIt != solution.end()) {
303 if ((solutionIt + 1) != solution.end()) {
304 // if next edge is the same of current edge, remove it
305 if (*solutionIt == *(solutionIt + 1)) {
306 solutionIt = solution.erase(solutionIt);
307 } else {
308 solutionIt++;
309 }
310 } else {
311 solutionIt++;
312 }
313 }
314 return solution;
315}
316
317
318std::vector<GNEEdge*>
319GNEPathManager::PathCalculator::calculateDijkstraPath(const SUMOVehicleClass vClass, const GNEJunction* fromJunction, const GNEJunction* toJunction) const {
320 std::vector<GNEEdge*> edges;
321 // get from and to edges
322 const auto fromEdges = fromJunction->getGNEOutgoingEdges();
323 const auto toEdges = toJunction->getGNEIncomingEdges();
324 // try to find a path
325 for (const auto& fromEdge : fromEdges) {
326 for (const auto& toEdge : toEdges) {
327 edges = calculateDijkstraPath(vClass, {fromEdge, toEdge});
328 // if a path was found, clean it
329 if (edges.size() > 0) {
330 return optimizeJunctionPath(edges);
331 }
332 }
333 }
334 return {};
335}
336
337
338void
340 // first reset reachability of all lanes
341 for (const auto& edge : originEdge->getNet()->getAttributeCarriers()->getEdges()) {
342 for (const auto& lane : edge.second->getLanes()) {
343 lane->resetReachability();
344 }
345 }
346 // get max speed
347 const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(vClass).maxSpeed;
348 // declare map for reachable edges
349 std::map<GNEEdge*, double> reachableEdges;
350 // init first edge
351 reachableEdges[originEdge] = 0;
352 // declare a vector for checked edges
353 std::vector<GNEEdge*> check;
354 // add first edge
355 check.push_back(originEdge);
356 // continue while there is edges to check
357 while (check.size() > 0) {
358 GNEEdge* edge = check.front();
359 check.erase(check.begin());
360 double traveltime = reachableEdges[edge];
361 for (const auto& lane : edge->getLanes()) {
362 if ((edge->getNBEdge()->getLaneStruct(lane->getIndex()).permissions & vClass) == vClass) {
363 lane->setReachability(traveltime);
364 }
365 }
366 // update traveltime
367 traveltime += edge->getNBEdge()->getLength() / MIN2(edge->getNBEdge()->getSpeed(), defaultMaxSpeed);
368 std::vector<GNEEdge*> sucessors;
369 // get sucessor edges
370 for (const auto& sucessorEdge : edge->getToJunction()->getGNEOutgoingEdges()) {
371 // check if edge is connected with successor edge
372 if (consecutiveEdgesConnected(vClass, edge, sucessorEdge)) {
373 sucessors.push_back(sucessorEdge);
374 }
375 }
376 // add successors to check vector
377 for (const auto& nextEdge : sucessors) {
378 // revisit edge via faster path
379 if ((reachableEdges.count(nextEdge) == 0) || (reachableEdges[nextEdge] > traveltime)) {
380 reachableEdges[nextEdge] = traveltime;
381 check.push_back(nextEdge);
382 }
383 }
384 }
385}
386
387
388bool
390 // check conditions
391 if ((from == nullptr) || (to == nullptr)) {
392 // myEdges cannot be null
393 return false;
394 } else if (from == to) {
395 // the same edge cannot be consecutive of itself
396 return false;
397 } else if (vClass == SVC_PEDESTRIAN) {
398 // for pedestrians consecutive myEdges are always connected
399 return true;
400 } else {
401 // iterate over connections of from edge
402 for (const auto& fromLane : from->getLanes()) {
403 for (const auto& fromConnection : from->getGNEConnections()) {
404 // within from loop, iterate ove to lanes
405 for (const auto& toLane : to->getLanes()) {
406 if (fromConnection->getLaneTo() == toLane) {
407 // get lane structs for both lanes
408 const NBEdge::Lane NBFromLane = from->getNBEdge()->getLaneStruct(fromLane->getIndex());
409 const NBEdge::Lane NBToLane = to->getNBEdge()->getLaneStruct(toLane->getIndex());
410 // check vClass
411 if (((NBFromLane.permissions & vClass) == vClass) &&
412 ((NBToLane.permissions & vClass) == vClass)) {
413 return true;
414 }
415 }
416 }
417 }
418 }
419 return false;
420 }
421}
422
423
424bool
426 if (busStop->getTagProperty().getTag() != SUMO_TAG_BUS_STOP) {
427 return false;
428 }
429 // check if busstop is placed over a pedestrian lane
430 if ((busStop->getParentLanes().front()->getParentEdge() == edge) &&
431 (edge->getNBEdge()->getLaneStruct(busStop->getParentLanes().front()->getIndex()).permissions & SVC_PEDESTRIAN) != 0) {
432 // busStop is placed over an lane that supports pedestrians, then return true
433 return true;
434 }
435 // obtain a list with all edge lanes that supports pedestrians
436 std::vector<GNELane*> pedestrianLanes;
437 for (int laneIndex = 0; laneIndex < (int)edge->getLanes().size(); laneIndex++) {
438 if ((edge->getNBEdge()->getLaneStruct(laneIndex).permissions & SVC_PEDESTRIAN) != 0) {
439 pedestrianLanes.push_back(edge->getLanes().at(laneIndex));
440 }
441 }
442 // check if exist an access between busStop and pedestrian lanes
443 for (const auto& access : busStop->getChildAdditionals()) {
444 // check that child is an access
445 if (access->getTagProperty().getTag() == SUMO_TAG_ACCESS) {
446 for (const auto& lane : pedestrianLanes) {
447 if (access->getParentLanes().front() == lane) {
448 // found, then return true
449 return true;
450 }
451 }
452 }
453 }
454 // There isn't a valid access, then return false
455 return false;
456}
457
458
459bool
461 return myPathCalculatorUpdated;
462}
463
464
465void
467 myPathCalculatorUpdated = false;
468}
469
470
471std::vector<GNEEdge*>
472GNEPathManager::PathCalculator::optimizeJunctionPath(const std::vector<GNEEdge*>& edges) const {
473 bool stop = false;
474 std::vector<GNEEdge*> solutionA, solutionB;
475 // get from and to junctions
476 const auto fromJunction = edges.front()->getFromJunction();
477 const auto toJunction = edges.back()->getToJunction();
478 // first optimize from Junction
479 for (auto it = edges.rbegin(); (it != edges.rend()) && !stop; it++) {
480 solutionA.insert(solutionA.begin(), *it);
481 if ((*it)->getFromJunction() == fromJunction) {
482 stop = true;
483 }
484 }
485 // optimize to edge
486 stop = false;
487 for (auto it = solutionA.begin(); (it != solutionA.end()) && !stop; it++) {
488 solutionB.push_back(*it);
489 if ((*it)->getToJunction() == toJunction) {
490 stop = true;
491 }
492 }
493 return solutionB;
494}
495
496// ---------------------------------------------------------------------------
497// GNEPathManager::PathDraw - methods
498// ---------------------------------------------------------------------------
499
501
502
504
505
506void
508 // just clear myDrawedElements
509 myLaneDrawedElements.clear();
510 myLane2laneDrawedElements.clear();
511}
512
513
514bool
515GNEPathManager::PathDraw::drawPathGeometry(const bool dottedElement, const GNELane* lane, SumoXMLTag tag) {
516 // check conditions
517 if (dottedElement) {
518 return true;
521 return true;
522 } else if (myLaneDrawedElements.count(lane) > 0) {
523 // check tag
524 if (myLaneDrawedElements.at(lane).count(tag) > 0) {
525 // element type was already inserted, then don't draw geometry
526 return false;
527 } else {
528 // insert tag for the given lane
529 myLaneDrawedElements.at(lane).insert(tag);
530 // draw geometry
531 return true;
532 }
533 } else {
534 // insert lane and tag
535 myLaneDrawedElements[lane].insert(tag);
536 // draw geometry
537 return true;
538 }
539}
540
541
542bool
543GNEPathManager::PathDraw::drawPathGeometry(const bool dottedElement, const GNELane* fromLane, const GNELane* toLane, SumoXMLTag tag) {
544 // check conditions
545 if (dottedElement) {
546 return true;
549 return true;
550 } else {
551 // declare lane2lane
552 const std::pair<const GNELane*, const GNELane*> lane2lane(fromLane, toLane);
553 // check lane2lane
554 if (myLane2laneDrawedElements.count(lane2lane) > 0) {
555 // check tag
556 if (myLane2laneDrawedElements.at(lane2lane).count(tag) > 0) {
557 // element type was already inserted, then don't draw geometry
558 return false;
559 } else {
560 // insert tag for the given lane2lane
561 myLane2laneDrawedElements.at(lane2lane).insert(tag);
562 // draw geometry
563 return true;
564 }
565 } else {
566 // insert lane2lane and tag
567 myLane2laneDrawedElements[lane2lane].insert(tag);
568 // draw geometry
569 return true;
570 }
571 }
572}
573
574// ---------------------------------------------------------------------------
575// GNEPathManager - methods
576// ---------------------------------------------------------------------------
577
580 myPathDraw(new PathDraw()) {
581}
582
583
585 // clear paths
587 // delete route calculator Instance
588 delete myPathCalculator;
589 // delete path draw
590 delete myPathDraw;
591}
592
593
596 return myPathCalculator;
597}
598
599
602 // first parse pathElement
603 const auto pathElement = dynamic_cast<const GNEPathManager::PathElement*>(GLObject);
604 if (pathElement == nullptr) {
605 return nullptr;
606 } else {
607 // find it in paths
608 auto it = myPaths.find(pathElement);
609 if (it == myPaths.end()) {
610 return nullptr;
611 } else {
612 return it->first;
613 }
614 }
615}
616
617
620 return myPathDraw;
621}
622
623
624bool
625GNEPathManager::isPathValid(const PathElement* pathElement) const {
626 // first check if path element exist
627 if (myPaths.count(pathElement) > 0) {
628 // check if path hat more than one element
629 if (myPaths.at(pathElement).size() > 0) {
630 // if there is a next segment, then is invalid
631 return (myPaths.at(pathElement).front()->getNextSegment() == nullptr);
632 } else {
633 return false;
634 }
635 } else {
636 return false;
637 }
638}
639
640
641const GNELane*
642GNEPathManager::getFirstLane(const PathElement* pathElement) const {
643 if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
644 return myPaths.at(pathElement).front()->getLane();
645 } else {
646 return nullptr;
647 }
648}
649
650
651void
652GNEPathManager::calculatePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
653 // check if path element exist already in myPaths
654 if (myPaths.find(pathElement) != myPaths.end()) {
655 // delete segments
656 for (const auto& segment : myPaths.at(pathElement)) {
657 delete segment;
658 }
659 // remove path element from myPaths
660 myPaths.erase(pathElement);
661 }
662 // continue depending of number of edges
663 if (edges.size() > 0) {
664 // declare segment vector
665 std::vector<Segment*> segments;
666 // declare lane segments
667 std::vector<Segment*> laneSegments;
668 // calculate Dijkstra path
669 const std::vector<GNEEdge*> path = myPathCalculator->calculateDijkstraPath(vClass, edges);
670 // continue if path isn't empty
671 if (path.size() > 0) {
672 // reserve
673 segments.reserve(2 * (int)path.size() - 1);
674 laneSegments.reserve(path.size());
675 // iterate over path
676 for (int i = 0; i < (int)path.size(); i++) {
677 // get first and last segment flags
678 const bool firstSegment = (i == 0);
679 const bool lastSegment = (i == ((int)path.size() - 1));
680 // get first allowed lane
681 const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
682 // create segments
683 Segment* laneSegment = new Segment(this, pathElement, lane, firstSegment, lastSegment);
684 // add it into segment and laneSegment vectors
685 segments.push_back(laneSegment);
686 laneSegments.push_back(laneSegment);
687 // continue if this isn't the last edge
688 if (!lastSegment) {
689 // obtain next lane
690 const GNELane* nextLane = path.at(i + 1)->getLaneByAllowedVClass(vClass);
691 // create junction segments
692 Segment* junctionSegment = new Segment(this, pathElement, path.at(i)->getParentJunctions().at(1), lane, nextLane);
693 // add it into segment vector
694 segments.push_back(junctionSegment);
695 }
696 }
697 // get lane segment index
698 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
699 // mark middle label as label segment
700 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
701 } else {
702 // create first segment
703 Segment* firstSegment = new Segment(this, pathElement, edges.front()->getLaneByAllowedVClass(vClass), true, false);
704 // mark segment as label segment
705 firstSegment->markSegmentLabel();
706 // add to segments
707 segments.push_back(firstSegment);
708 // create last segment
709 Segment* lastSegment = new Segment(this, pathElement, edges.back()->getLaneByAllowedVClass(vClass), false, true);
710 // add to segments
711 segments.push_back(lastSegment);
712 // set previous and next segment for vinculating first and last segment with a red line
713 firstSegment->setNextSegment(lastSegment);
714 lastSegment->setPreviousSegment(firstSegment);
715 }
716 // add segment in path
717 myPaths[pathElement] = segments;
718 }
719}
720
721
722void
723GNEPathManager::calculatePathLanes(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNELane*> lanes) {
724 // declare edges
725 std::vector<GNEEdge*> edges;
726 // reserve edges
727 edges.reserve(lanes.size());
728 // get parent of every lane
729 for (const auto& lane : lanes) {
730 edges.push_back(lane->getParentEdge());
731 }
732 // calculate path edges
733 calculatePathEdges(pathElement, vClass, edges);
734}
735
736
737void
738GNEPathManager::calculatePathJunctions(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEJunction*> junctions) {
739 // first calculate edge path between both elements
740 const auto junctionPath = myPathCalculator->calculateDijkstraPath(vClass, junctions.front(), junctions.back());
741 // if exist, then calculate edgePath between the first edges
742 if (junctionPath.size() > 0) {
743 // calculate path edges
744 calculatePathEdges(pathElement, vClass, {junctionPath.front(), junctionPath.back()});
745 }
746}
747
748
749void
750GNEPathManager::calculateConsecutivePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
751 // declare lane vector
752 std::vector<GNELane*> lanes;
753 // reserve lanes
754 lanes.reserve(edges.size());
755 // get first allowed lane of every edge
756 for (const auto& edge : edges) {
757 lanes.push_back(edge->getLaneByAllowedVClass(vClass));
758 }
759 // calculate consecutive path lanes
760 calculateConsecutivePathLanes(pathElement, lanes);
761}
762
763
764void
765GNEPathManager::calculateConsecutivePathLanes(PathElement* pathElement, const std::vector<GNELane*> lanes) {
766 // check if path element exist already in myPaths
767 if (myPaths.find(pathElement) != myPaths.end()) {
768 // delete segments
769 for (const auto& segment : myPaths.at(pathElement)) {
770 delete segment;
771 }
772 // remove path element from myPaths
773 myPaths.erase(pathElement);
774 }
775 // continue depending of number of lanes
776 if (lanes.size() > 0) {
777 // declare segment vector
778 std::vector<Segment*> segments;
779 // declare lane segments
780 std::vector<Segment*> laneSegments;
781 // reserve
782 segments.reserve(2 * (int)lanes.size() - 1);
783 laneSegments.reserve(lanes.size());
784 // iterate over lanes
785 for (int i = 0; i < (int)lanes.size(); i++) {
786 // get first and last segment flags
787 const bool firstSegment = (i == 0);
788 const bool lastSegment = (i == ((int)lanes.size() - 1));
789 // create segments
790 Segment* laneSegment = new Segment(this, pathElement, lanes.at(i), firstSegment, lastSegment);
791 // add it into segment vector
792 segments.push_back(laneSegment);
793 laneSegments.push_back(laneSegment);
794 // continue if this isn't the last lane
795 if (!lastSegment) {
796 // obtain next lane
797 const GNELane* nextLane = lanes.at(i + 1);
798 // create junction segments
799 Segment* junctionSegment = new Segment(this, pathElement, lanes.at(i)->getParentEdge()->getParentJunctions().at(1), lanes.at(i), nextLane);
800 // add it into segment vector
801 segments.push_back(junctionSegment);
802 }
803 }
804 // get lane segment index
805 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
806 // mark middle label as label segment
807 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
808 // add segment in path
809 myPaths[pathElement] = segments;
810 }
811}
812
813
814void
816 // check if path element exist already in myPaths
817 if (myPaths.find(pathElement) != myPaths.end()) {
818 // delete segments
819 for (const auto& segment : myPaths.at(pathElement)) {
820 delete segment;
821 }
822 // remove path element from myPaths
823 myPaths.erase(pathElement);
824 }
825}
826
827
828void
830 if (myLaneSegments.count(lane) > 0) {
831 int numRoutes = 0;
832 for (const auto& segment : myLaneSegments.at(lane)) {
833 // draw segment
834 segment->getPathElement()->drawPartialGL(s, lane, segment, 0);
835 // check if path element is a route
836 if (segment->getPathElement()->isRoute()) {
837 numRoutes++;
838 }
839 }
840 // check if draw overlapped routes
841 if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
842 lane->drawOverlappedRoutes(numRoutes);
843 }
844 }
845}
846
847
848void
850 if (myJunctionSegments.count(junction) > 0) {
851 for (const auto& segment : myJunctionSegments.at(junction)) {
852 segment->getPathElement()->drawPartialGL(s, segment->getPreviousLane(), segment->getNextLane(), segment, 0);
853 }
854 }
855}
856
857
858void
860 // draw all lane segments
861 for (const auto& laneSegment : myLaneSegments) {
862 for (const auto& segment : laneSegment.second) {
863 if (segment->getPathElement() == pathElement) {
864 pathElement->drawPartialGL(s, laneSegment.first, segment, 0);
865 }
866 }
867 }
868 // draw all junction segments
869 for (const auto& junctionSegment : myJunctionSegments) {
870 for (const auto& segment : junctionSegment.second) {
871 if (segment->getPathElement() == pathElement) {
872 segment->getPathElement()->drawPartialGL(s, segment->getPreviousLane(), segment->getNextLane(), segment, 0);
873 }
874 }
875 }
876}
877
878
879void
881 // declare vector for path elements to compute
882 std::vector<PathElement*> pathElementsToCompute;
883 // check lane in laneSegments
884 if (myLaneSegments.count(lane) > 0) {
885 // obtain affected path elements
886 for (const auto& segment : myLaneSegments.at(lane)) {
887 pathElementsToCompute.push_back(segment->getPathElement());
888 }
889 }
890 // compute path elements
891 for (const auto& pathElement : pathElementsToCompute) {
892 pathElement->computePathElement();
893 }
894}
895
896
897void
899 // declare vector for path elements to compute
900 std::vector<PathElement*> pathElementsToCompute;
901 // check junction in junctionSegments
902 if (myJunctionSegments.count(junction) > 0) {
903 // obtain affected path elements
904 for (const auto& segment : myJunctionSegments.at(junction)) {
905 pathElementsToCompute.push_back(segment->getPathElement());
906 }
907 }
908 // compute path elements
909 for (const auto& pathElement : pathElementsToCompute) {
910 pathElement->computePathElement();
911 }
912}
913
914
915void
917 // declare iterator
918 auto it = myPaths.begin();
919 // iterate over paths
920 while (it != myPaths.end()) {
921 if (it->first->isDemandElement()) {
922 // delete all segments
923 for (const auto& segment : it->second) {
924 delete segment;
925 }
926 // remove path
927 it = myPaths.erase(it);
928 } else {
929 it++;
930 }
931 }
932}
933
934
935void
937 myLaneSegments[lane].insert(segment);
938}
939
940
941void
943 myJunctionSegments[junction].insert(segment);
944}
945
946
947void
949 // check if segment has a lane
950 if (segment->getLane()) {
951 // remove segment from segments associated with lane
952 if (myLaneSegments.at(segment->getLane()).find(segment) != myLaneSegments.at(segment->getLane()).end()) {
953 myLaneSegments.at(segment->getLane()).erase(segment);
954 }
955 // clear lane if doesn't have more segments
956 if (myLaneSegments.at(segment->getLane()).empty()) {
957 myLaneSegments.erase(segment->getLane());
958 }
959 }
960 if (segment->getJunction()) {
961 // remove segment from segments associated with junction
962 if (myJunctionSegments.at(segment->getJunction()).find(segment) != myJunctionSegments.at(segment->getJunction()).end()) {
963 myJunctionSegments.at(segment->getJunction()).erase(segment);
964 }
965 // clear junction if doesn't have more segments
966 if (myJunctionSegments.at(segment->getJunction()).empty()) {
967 myJunctionSegments.erase(segment->getJunction());
968 }
969 }
970}
971
972
973void
975 // first iterate over paths
976 for (const auto& path : myPaths) {
977 // delete all segments
978 for (const auto& segment : path.second) {
979 delete segment;
980 }
981 }
982 // clear paths
983 myPaths.clear();
984}
985
986
987bool
988GNEPathManager::connectedLanes(const GNELane* fromLane, const GNELane* toLane) const {
989 // get from and to NBEdges
990 NBEdge* fromNBEdge = fromLane->getParentEdge()->getNBEdge();
991 NBEdge* toNBEdge = toLane->getParentEdge()->getNBEdge();
992 // get connections vinculated with from Lane
993 const std::vector<NBEdge::Connection> connections = fromNBEdge->getConnectionsFromLane(fromLane->getIndex());
994 // find connection
995 std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
996 connections.begin(), connections.end(),
997 NBEdge::connections_finder(fromLane->getIndex(), toNBEdge, toLane->getIndex()));
998 // check if connection was found
999 return (con_it != connections.end());
1000}
1001
1002/****************************************************************************/
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:71
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:48
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:481
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:839
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:845
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:82
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:876
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition: GNELane.cpp:1492
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:124
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:1394
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:132
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1987
class used to calculate paths in nets
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...
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &partialEdges) const
calculate Dijkstra path between a list of partial edges
const GNENet * myNet
pointer to net
class used to mark path draw
bool drawPathGeometry(const bool dottedElement, 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
bool isDataElement() const
check if pathElement is a data element
bool isDemandElement() const
check if pathElement is a demand element
virtual void drawPartialGL(const GUIVisualizationSettings &s, const GNELane *lane, const GNEPathManager::Segment *segment, const double offsetFront) const =0
Draws partial object (lane)
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
PathElement * getPathElement() const
get path element
Segment * getPreviousSegment() const
get previous segment
void setNextSegment(Segment *nexSegment)
set next segment
void setPreviousSegment(Segment *nexSegment)
set previous segment
GNEPathManager * myPathManager
path manager
const GNEJunction * getJunction() const
get junction associated with this segment
const GNELane * getNextLane() const
get next lane
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
void addSegmentInJunctionSegments(Segment *segment, const GNEJunction *junction)
add segments int junctionSegments (called by Segment constructor)
std::map< const GNEJunction *, std::set< Segment * > > myJunctionSegments
map with junction segments
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
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
void calculatePathJunctions(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEJunction * > junctions)
calculate path junctions (using dijkstra, require path calculator updated)
std::map< const PathElement *, std::vector< Segment * > > myPaths
map with path element and their associated segments
void drawLanePathElements(const GUIVisualizationSettings &s, const GNELane *lane)
draw lane path elements
void removePath(PathElement *pathElement)
remove path
std::map< const GNELane *, std::set< Segment * > > myLaneSegments
map with lane segments
void clearSegmentFromJunctionAndLaneSegments(Segment *segment)
clear segments from junction and lane Segments (called by Segment destructor)
PathDraw * myPathDraw
PathDraw instance.
void calculatePathEdges(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > edges)
calculate path edges (using dijkstra, require path calculator updated)
void drawJunctionPathElements(const GUIVisualizationSettings &s, const GNEJunction *junction)
draw junction path elements
void forceDrawPath(const GUIVisualizationSettings &s, const PathElement *pathElement) const
force draw path (used carefully, ONLY when we're inspecting a path element, due slowdowns)
~GNEPathManager()
destructor
const GNELane * getFirstLane(const PathElement *pathElement) const
get first lane associated with path element
void calculatePathLanes(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNELane * > lanes)
calculate path lanes (using dijkstra, require path calculator updated)
GNEPathManager(const GNENet *net)
constructor
bool isPathValid(const PathElement *pathElement) const
check if path element is valid
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:650
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
Stores the information about how to visualize structures.
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
bool drawForPositionSelection
whether drawing is performed for the purpose of selecting objects with a single click
RouterEdgeVector getAllRouterEdges() const
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:599
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1426
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:625
std::vector< Connection > getConnectionsFromLane(int lane, NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1241
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)