Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2023 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
205
206
207bool
211
212
213bool
217
218
219bool
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
582
583
585 // clear paths
587 // delete route calculator Instance
588 delete myPathCalculator;
589 // delete path draw
590 delete myPathDraw;
591}
592
593
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
618const std::vector<GNEPathManager::Segment*>&
620 if (myPaths.count(pathElement) > 0) {
621 return myPaths.at(pathElement);
622 } else {
623 return myEmptySegments;
624 }
625}
626
627
632
633
634bool
635GNEPathManager::isPathValid(const PathElement* pathElement) const {
636 // first check if path element exist
637 if (myPaths.count(pathElement) > 0) {
638 // check if path hat more than one element
639 if (myPaths.at(pathElement).size() > 0) {
640 // if there is a next segment, then is invalid
641 return (myPaths.at(pathElement).front()->getNextSegment() == nullptr);
642 } else {
643 return false;
644 }
645 } else {
646 return false;
647 }
648}
649
650
651const GNELane*
652GNEPathManager::getFirstLane(const PathElement* pathElement) const {
653 if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
654 return myPaths.at(pathElement).front()->getLane();
655 } else {
656 return nullptr;
657 }
658}
659
660
661void
662GNEPathManager::calculatePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
663 // check if path element exist already in myPaths
664 if (myPaths.find(pathElement) != myPaths.end()) {
665 // delete segments
666 for (const auto& segment : myPaths.at(pathElement)) {
667 delete segment;
668 }
669 // remove path element from myPaths
670 myPaths.erase(pathElement);
671 }
672 // continue depending of number of edges
673 if (edges.size() > 0) {
674 // declare segment vector
675 std::vector<Segment*> segments;
676 // declare lane segments
677 std::vector<Segment*> laneSegments;
678 // calculate Dijkstra path
679 const std::vector<GNEEdge*> path = myPathCalculator->calculateDijkstraPath(vClass, edges);
680 // continue if path isn't empty
681 if (path.size() > 0) {
682 // reserve
683 segments.reserve(2 * (int)path.size() - 1);
684 laneSegments.reserve(path.size());
685 // iterate over path
686 for (int i = 0; i < (int)path.size(); i++) {
687 // get first and last segment flags
688 const bool firstSegment = (i == 0);
689 const bool lastSegment = (i == ((int)path.size() - 1));
690 // get first allowed lane
691 const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
692 // create segments
693 Segment* laneSegment = new Segment(this, pathElement, lane, firstSegment, lastSegment);
694 // add it into segment and laneSegment vectors
695 segments.push_back(laneSegment);
696 laneSegments.push_back(laneSegment);
697 // continue if this isn't the last edge
698 if (!lastSegment) {
699 // obtain next lane
700 const GNELane* nextLane = path.at(i + 1)->getLaneByAllowedVClass(vClass);
701 // create junction segments
702 Segment* junctionSegment = new Segment(this, pathElement, path.at(i)->getParentJunctions().at(1), lane, nextLane);
703 // add it into segment vector
704 segments.push_back(junctionSegment);
705 }
706 }
707 // get lane segment index
708 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
709 // mark middle label as label segment
710 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
711 } else {
712 // create first segment
713 Segment* firstSegment = new Segment(this, pathElement, edges.front()->getLaneByAllowedVClass(vClass), true, false);
714 // mark segment as label segment
715 firstSegment->markSegmentLabel();
716 // add to segments
717 segments.push_back(firstSegment);
718 // create last segment
719 Segment* lastSegment = new Segment(this, pathElement, edges.back()->getLaneByAllowedVClass(vClass), false, true);
720 // add to segments
721 segments.push_back(lastSegment);
722 // set previous and next segment for vinculating first and last segment with a red line
723 firstSegment->setNextSegment(lastSegment);
724 lastSegment->setPreviousSegment(firstSegment);
725 }
726 // add segment in path
727 myPaths[pathElement] = segments;
728 }
729}
730
731
732void
733GNEPathManager::calculatePathLanes(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNELane*> lanes) {
734 // declare edges
735 std::vector<GNEEdge*> edges;
736 // reserve edges
737 edges.reserve(lanes.size());
738 // get parent of every lane
739 for (const auto& lane : lanes) {
740 edges.push_back(lane->getParentEdge());
741 }
742 // calculate path edges
743 calculatePathEdges(pathElement, vClass, edges);
744}
745
746
747void
748GNEPathManager::calculatePathJunctions(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEJunction*> junctions) {
749 // first calculate edge path between both elements
750 const auto junctionPath = myPathCalculator->calculateDijkstraPath(vClass, junctions.front(), junctions.back());
751 // if exist, then calculate edgePath between the first edges
752 if (junctionPath.size() > 0) {
753 // calculate path edges
754 calculatePathEdges(pathElement, vClass, {junctionPath.front(), junctionPath.back()});
755 }
756}
757
758
759void
760GNEPathManager::calculateConsecutivePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> edges) {
761 // declare lane vector
762 std::vector<GNELane*> lanes;
763 // reserve lanes
764 lanes.reserve(edges.size());
765 // get first allowed lane of every edge
766 for (const auto& edge : edges) {
767 lanes.push_back(edge->getLaneByAllowedVClass(vClass));
768 }
769 // calculate consecutive path lanes
770 calculateConsecutivePathLanes(pathElement, lanes);
771}
772
773
774void
775GNEPathManager::calculateConsecutivePathLanes(PathElement* pathElement, const std::vector<GNELane*> lanes) {
776 // check if path element exist already in myPaths
777 if (myPaths.find(pathElement) != myPaths.end()) {
778 // delete segments
779 for (const auto& segment : myPaths.at(pathElement)) {
780 delete segment;
781 }
782 // remove path element from myPaths
783 myPaths.erase(pathElement);
784 }
785 // continue depending of number of lanes
786 if (lanes.size() > 0) {
787 // declare segment vector
788 std::vector<Segment*> segments;
789 // declare lane segments
790 std::vector<Segment*> laneSegments;
791 // reserve
792 segments.reserve(2 * (int)lanes.size() - 1);
793 laneSegments.reserve(lanes.size());
794 // iterate over lanes
795 for (int i = 0; i < (int)lanes.size(); i++) {
796 // get first and last segment flags
797 const bool firstSegment = (i == 0);
798 const bool lastSegment = (i == ((int)lanes.size() - 1));
799 // create segments
800 Segment* laneSegment = new Segment(this, pathElement, lanes.at(i), firstSegment, lastSegment);
801 // add it into segment vector
802 segments.push_back(laneSegment);
803 laneSegments.push_back(laneSegment);
804 // continue if this isn't the last lane
805 if (!lastSegment) {
806 // obtain next lane
807 const GNELane* nextLane = lanes.at(i + 1);
808 // create junction segments
809 Segment* junctionSegment = new Segment(this, pathElement, lanes.at(i)->getParentEdge()->getParentJunctions().at(1), lanes.at(i), nextLane);
810 // add it into segment vector
811 segments.push_back(junctionSegment);
812 }
813 }
814 // get lane segment index
815 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
816 // mark middle label as label segment
817 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
818 // add segment in path
819 myPaths[pathElement] = segments;
820 }
821}
822
823
824void
826 // check if path element exist already in myPaths
827 if (myPaths.find(pathElement) != myPaths.end()) {
828 // delete segments
829 for (const auto& segment : myPaths.at(pathElement)) {
830 delete segment;
831 }
832 // remove path element from myPaths
833 myPaths.erase(pathElement);
834 }
835}
836
837
838void
840 if (myLaneSegments.count(lane) > 0) {
841 int numRoutes = 0;
842 // first draw selected elements (for drawing over other elements)
843 for (const auto& segment : myLaneSegments.at(lane)) {
844 if (segment->getPathElement()->isPathElementSelected()) {
845 // draw segment
846 segment->getPathElement()->drawPartialGL(s, lane, segment, 2);
847 // check if path element is a route
848 if (segment->getPathElement()->isRoute()) {
849 numRoutes++;
850 }
851 }
852 }
853 // now draw non selected elements
854 for (const auto& segment : myLaneSegments.at(lane)) {
855 if (!segment->getPathElement()->isPathElementSelected()) {
856 // draw segment
857 segment->getPathElement()->drawPartialGL(s, lane, segment, 0);
858 // check if path element is a route
859 if (segment->getPathElement()->isRoute()) {
860 numRoutes++;
861 }
862 }
863 }
864 // check if draw overlapped routes
865 if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
866 lane->drawOverlappedRoutes(numRoutes);
867 }
868 }
869}
870
871
872void
874 if (myJunctionSegments.count(junction) > 0) {
875 // first draw selected elements (for drawing over other elements)
876 for (const auto& segment : myJunctionSegments.at(junction)) {
877 if (segment->getPathElement()->isPathElementSelected()) {
878 segment->getPathElement()->drawPartialGL(s, segment->getPreviousLane(), segment->getNextLane(), segment, 0);
879 }
880 }
881 // now draw non selected elements
882 for (const auto& segment : myJunctionSegments.at(junction)) {
883 if (!segment->getPathElement()->isPathElementSelected()) {
884 segment->getPathElement()->drawPartialGL(s, segment->getPreviousLane(), segment->getNextLane(), segment, 0);
885 }
886 }
887 }
888}
889
890
891void
893 // draw all lane segments
894 for (const auto& laneSegment : myLaneSegments) {
895 for (const auto& segment : laneSegment.second) {
896 if (segment->getPathElement() == pathElement) {
897 pathElement->drawPartialGL(s, laneSegment.first, segment, 0);
898 }
899 }
900 }
901 // draw all junction segments
902 for (const auto& junctionSegment : myJunctionSegments) {
903 for (const auto& segment : junctionSegment.second) {
904 if (segment->getPathElement() == pathElement) {
905 segment->getPathElement()->drawPartialGL(s, segment->getPreviousLane(), segment->getNextLane(), segment, 0);
906 }
907 }
908 }
909}
910
911
912void
914 // declare vector for path elements to compute
915 std::vector<PathElement*> pathElementsToCompute;
916 // check lane in laneSegments
917 if (myLaneSegments.count(lane) > 0) {
918 // obtain affected path elements
919 for (const auto& segment : myLaneSegments.at(lane)) {
920 pathElementsToCompute.push_back(segment->getPathElement());
921 }
922 }
923 // compute path elements
924 for (const auto& pathElement : pathElementsToCompute) {
925 pathElement->computePathElement();
926 }
927}
928
929
930void
932 // declare vector for path elements to compute
933 std::vector<PathElement*> pathElementsToCompute;
934 // check junction in junctionSegments
935 if (myJunctionSegments.count(junction) > 0) {
936 // obtain affected path elements
937 for (const auto& segment : myJunctionSegments.at(junction)) {
938 pathElementsToCompute.push_back(segment->getPathElement());
939 }
940 }
941 // compute path elements
942 for (const auto& pathElement : pathElementsToCompute) {
943 pathElement->computePathElement();
944 }
945}
946
947
948void
950 // declare iterator
951 auto it = myPaths.begin();
952 // iterate over paths
953 while (it != myPaths.end()) {
954 if (it->first->isDemandElement()) {
955 // delete all segments
956 for (const auto& segment : it->second) {
957 delete segment;
958 }
959 // remove path
960 it = myPaths.erase(it);
961 } else {
962 it++;
963 }
964 }
965}
966
967
968void
970 myLaneSegments[lane].insert(segment);
971}
972
973
974void
976 myJunctionSegments[junction].insert(segment);
977}
978
979
980void
982 // check if segment has a lane
983 if (segment->getLane()) {
984 // remove segment from segments associated with lane
985 if (myLaneSegments.at(segment->getLane()).find(segment) != myLaneSegments.at(segment->getLane()).end()) {
986 myLaneSegments.at(segment->getLane()).erase(segment);
987 }
988 // clear lane if doesn't have more segments
989 if (myLaneSegments.at(segment->getLane()).empty()) {
990 myLaneSegments.erase(segment->getLane());
991 }
992 }
993 if (segment->getJunction()) {
994 // remove segment from segments associated with junction
995 if (myJunctionSegments.at(segment->getJunction()).find(segment) != myJunctionSegments.at(segment->getJunction()).end()) {
996 myJunctionSegments.at(segment->getJunction()).erase(segment);
997 }
998 // clear junction if doesn't have more segments
999 if (myJunctionSegments.at(segment->getJunction()).empty()) {
1000 myJunctionSegments.erase(segment->getJunction());
1001 }
1002 }
1003}
1004
1005
1006void
1008 // first iterate over paths
1009 for (const auto& path : myPaths) {
1010 // delete all segments
1011 for (const auto& segment : path.second) {
1012 delete segment;
1013 }
1014 }
1015 // clear paths
1016 myPaths.clear();
1017}
1018
1019
1020bool
1021GNEPathManager::connectedLanes(const GNELane* fromLane, const GNELane* toLane) const {
1022 // get from and to NBEdges
1023 NBEdge* fromNBEdge = fromLane->getParentEdge()->getNBEdge();
1024 NBEdge* toNBEdge = toLane->getParentEdge()->getNBEdge();
1025 // get connections vinculated with from Lane
1026 const std::vector<NBEdge::Connection> connections = fromNBEdge->getConnectionsFromLane(fromLane->getIndex());
1027 // find connection
1028 std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
1029 connections.begin(), connections.end(),
1030 NBEdge::connections_finder(fromLane->getIndex(), toNBEdge, toLane->getIndex()));
1031 // check if connection was found
1032 return (con_it != connections.end());
1033}
1034
1035/****************************************************************************/
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.
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:480
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:840
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:846
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:788
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1509
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:118
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:1424
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:120
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2030
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
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)
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
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
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:583
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1415
double getSpeed() const
Returns the speed allowed on this edge.
Definition NBEdge.h:609
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition NBEdge.cpp:1221
NBEdgeCont & getEdgeCont()
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)