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-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
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
38GNEPathManager::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
60GNEPathManager::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 // check if we're cleaning all segments
84 if (!myPathManager->myCleaningSegments) {
85 // clear segment from LaneSegments
86 myPathManager->clearSegmentFromJunctionAndLaneSegments(this);
87 // remove references in previous and next segment
88 if (myPreviousSegment) {
89 myPreviousSegment->myNextSegment = nullptr;
90 }
91 if (myNextSegment) {
92 myNextSegment->myPreviousSegment = nullptr;
93 }
94 }
95 // delete contour
96 delete myContour;
97}
98
99
102 return myContour;
103}
104
105
106bool
108 return (myPreviousSegment == nullptr);
109}
110
111
112bool
114 return (myNextSegment == nullptr);
115}
116
117
120 return myPathElement;
121}
122
123
124const GNELane*
126 return myLane;
127}
128
129
130const GNELane*
132 if (myPreviousSegment) {
133 return myPreviousSegment->getLane();
134 } else {
135 return nullptr;
136 }
137}
138
139
140const GNELane*
142 if (myNextSegment) {
143 return myNextSegment->getLane();
144 } else {
145 return nullptr;
146 }
147}
148
149
150const GNEJunction*
152 return myJunction;
153}
154
155
158 return myNextSegment;
159}
160
161
164 return myPreviousSegment;
165}
166
167
168bool
170 return myLabelSegment;
171}
172
173
174void
176 myLabelSegment = true;
177}
178
179
181 myPathManager(nullptr),
182 myPathElement(nullptr),
183 myLane(nullptr),
184 myJunction(nullptr),
185 myNextSegment(nullptr),
186 myPreviousSegment(nullptr),
187 myLabelSegment(false) {
188}
189
190// ---------------------------------------------------------------------------
191// GNEPathManager::PathElement - methods
192// ---------------------------------------------------------------------------
193
194GNEPathManager::PathElement::PathElement(GUIGlObjectType type, const std::string& microsimID, FXIcon* icon, const int options) :
195 GUIGlObject(type, microsimID, icon),
196 myOption(options) {
197}
198
199
201
202
203bool
207
208
209bool
213
214
215bool
219
220
221bool
225
226
227bool
229 return (myOption & PathElement::Options::ROUTE) != 0;
230}
231
232// ---------------------------------------------------------------------------
233// GNEPathManager::PathCalculator - methods
234// ---------------------------------------------------------------------------
235
237 myNet(net),
238 myPathCalculatorUpdated(false),
239 myDijkstraRouter(nullptr) {
240 // create myDijkstraRouter
243 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
244}
245
246
248 delete myDijkstraRouter;
249}
250
251
252void
254 // simply delete and create myDijkstraRouter again
255 if (myDijkstraRouter) {
256 delete myDijkstraRouter;
257 }
258 myDijkstraRouter = new DijkstraRouter<NBRouterEdge, NBVehicle>(
259 myNet->getNetBuilder()->getEdgeCont().getAllRouterEdges(),
260 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
261 // update flag
262 myPathCalculatorUpdated = true;
263}
264
265
266std::vector<GNEEdge*>
267GNEPathManager::PathCalculator::calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) const {
268 // declare a solution vector
269 std::vector<GNEEdge*> solution;
270 // check if path calculator is updated
271 if (!myPathCalculatorUpdated) {
272 // use partialEdges as solution
273 solution = edges;
274 return solution;
275 }
276 // calculate route depending of number of partial edges
277 if (edges.size() == 0) {
278 // partial edges empty, then return a empty vector
279 return solution;
280 } else if (edges.size() == 1) {
281 // if there is only one partialEdges, path has only one edge
282 solution.push_back(edges.front());
283 return solution;
284 } else if ((edges.size() == 2) && (edges.front() == edges.back())) {
285 // typical case for stops. Used to avoid unnecesary calls to compute
286 solution.push_back(edges.front());
287 return solution;
288 } else {
289 // declare temporal vehicle
290 NBVehicle tmpVehicle("temporalNBVehicle", vClass);
291 // obtain pointer to GNENet
292 GNENet* net = edges.front()->getNet();
293 // iterate over every selected myEdges
294 for (int i = 1; i < (int)edges.size(); i++) {
295 // ignore consecutive edges
296 if (edges.at(i - 1)->getNBEdge() != edges.at(i)->getNBEdge()) {
297 // declare a temporal route in which save route between two last myEdges
298 std::vector<const NBRouterEdge*> partialRoute;
299 myDijkstraRouter->compute(edges.at(i - 1)->getNBEdge(), edges.at(i)->getNBEdge(), &tmpVehicle, 10, partialRoute);
300 // if partial route is empty, return empty route
301 if (partialRoute.empty()) {
302 return {};
303 } else {
304 // save partial route in solution
305 for (const auto& edgeID : partialRoute) {
306 solution.push_back(net->getAttributeCarriers()->retrieveEdge(edgeID->getID()));
307 }
308 }
309 }
310 }
311 }
312 // filter solution
313 auto solutionIt = solution.begin();
314 // iterate over solution
315 while (solutionIt != solution.end()) {
316 if ((solutionIt + 1) != solution.end()) {
317 // if next edge is the same of current edge, remove it
318 if (*solutionIt == *(solutionIt + 1)) {
319 solutionIt = solution.erase(solutionIt);
320 } else {
321 solutionIt++;
322 }
323 } else {
324 solutionIt++;
325 }
326 }
327 return solution;
328}
329
330
331std::vector<GNEEdge*>
333 return calculateDijkstraPath(vClass, {fromEdge, toEdge});
334}
335
336
337std::vector<GNEEdge*>
339 std::vector<GNEEdge*> edges;
340 // get from and to edges
341 const auto toEdges = toJunction->getGNEIncomingEdges();
342 // try to find a path
343 for (const auto& toEdge : toEdges) {
344 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
345 // if a path was found, clean it
346 if (edges.size() > 0) {
347 return optimizeJunctionPath(edges);
348 }
349 }
350 return {};
351}
352
353
354std::vector<GNEEdge*>
356 std::vector<GNEEdge*> edges;
357 // get from and to edges
358 const auto fromEdges = fromJunction->getGNEOutgoingEdges();
359 // try to find a path
360 for (const auto& fromEdge : fromEdges) {
361 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
362 // if a path was found, clean it
363 if (edges.size() > 0) {
364 return optimizeJunctionPath(edges);
365 }
366 }
367 return {};
368}
369
370
371std::vector<GNEEdge*>
373 std::vector<GNEEdge*> edges;
374 // get from and to edges
375 const auto fromEdges = fromJunction->getGNEOutgoingEdges();
376 const auto toEdges = toJunction->getGNEIncomingEdges();
377 // try to find a path
378 for (const auto& fromEdge : fromEdges) {
379 for (const auto& toEdge : toEdges) {
380 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
381 // if a path was found, clean it
382 if (edges.size() > 0) {
383 return optimizeJunctionPath(edges);
384 }
385 }
386 }
387 return {};
388}
389
390
391void
393 // first reset reachability of all lanes
394 for (const auto& edge : originEdge->getNet()->getAttributeCarriers()->getEdges()) {
395 for (const auto& lane : edge.second->getLanes()) {
396 lane->resetReachability();
397 }
398 }
399 // get max speed
400 const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(vClass).maxSpeed;
401 // declare map for reachable edges
402 std::map<GNEEdge*, double> reachableEdges;
403 // init first edge
404 reachableEdges[originEdge] = 0;
405 // declare a vector for checked edges
406 std::vector<GNEEdge*> check;
407 // add first edge
408 check.push_back(originEdge);
409 // continue while there is edges to check
410 while (check.size() > 0) {
411 GNEEdge* edge = check.front();
412 check.erase(check.begin());
413 double traveltime = reachableEdges[edge];
414 for (const auto& lane : edge->getLanes()) {
415 if ((edge->getNBEdge()->getLaneStruct(lane->getIndex()).permissions & vClass) == vClass) {
416 lane->setReachability(traveltime);
417 }
418 }
419 // update traveltime
420 traveltime += edge->getNBEdge()->getLength() / MIN2(edge->getNBEdge()->getSpeed(), defaultMaxSpeed);
421 std::vector<GNEEdge*> sucessors;
422 // get successor edges
423 for (const auto& sucessorEdge : edge->getToJunction()->getGNEOutgoingEdges()) {
424 // check if edge is connected with successor edge
425 if (consecutiveEdgesConnected(vClass, edge, sucessorEdge)) {
426 sucessors.push_back(sucessorEdge);
427 }
428 }
429 // add successors to check vector
430 for (const auto& nextEdge : sucessors) {
431 // revisit edge via faster path
432 if ((reachableEdges.count(nextEdge) == 0) || (reachableEdges[nextEdge] > traveltime)) {
433 reachableEdges[nextEdge] = traveltime;
434 check.push_back(nextEdge);
435 }
436 }
437 }
438}
439
440
441bool
443 // check conditions
444 if ((from == nullptr) || (to == nullptr)) {
445 // myEdges cannot be null
446 return false;
447 } else if (from == to) {
448 // the same edge cannot be consecutive of itself
449 return false;
450 } else if (vClass == SVC_PEDESTRIAN) {
451 // for pedestrians consecutive myEdges are always connected
452 return true;
453 } else {
454 // iterate over connections of from edge
455 for (const auto& fromLane : from->getLanes()) {
456 for (const auto& fromConnection : from->getGNEConnections()) {
457 // within from loop, iterate ove to lanes
458 for (const auto& toLane : to->getLanes()) {
459 if (fromConnection->getLaneTo() == toLane) {
460 // get lane structs for both lanes
461 const NBEdge::Lane NBFromLane = from->getNBEdge()->getLaneStruct(fromLane->getIndex());
462 const NBEdge::Lane NBToLane = to->getNBEdge()->getLaneStruct(toLane->getIndex());
463 // check vClass
464 if (((NBFromLane.permissions & vClass) == vClass) &&
465 ((NBToLane.permissions & vClass) == vClass)) {
466 return true;
467 }
468 }
469 }
470 }
471 }
472 return false;
473 }
474}
475
476
477bool
479 if (busStop->getTagProperty().getTag() != SUMO_TAG_BUS_STOP) {
480 return false;
481 }
482 // check if busstop is placed over a pedestrian lane
483 if ((busStop->getParentLanes().front()->getParentEdge() == edge) &&
484 (edge->getNBEdge()->getLaneStruct(busStop->getParentLanes().front()->getIndex()).permissions & SVC_PEDESTRIAN) != 0) {
485 // busStop is placed over an lane that supports pedestrians, then return true
486 return true;
487 }
488 // obtain a list with all edge lanes that supports pedestrians
489 std::vector<GNELane*> pedestrianLanes;
490 for (int laneIndex = 0; laneIndex < (int)edge->getLanes().size(); laneIndex++) {
491 if ((edge->getNBEdge()->getLaneStruct(laneIndex).permissions & SVC_PEDESTRIAN) != 0) {
492 pedestrianLanes.push_back(edge->getLanes().at(laneIndex));
493 }
494 }
495 // check if exist an access between busStop and pedestrian lanes
496 for (const auto& access : busStop->getChildAdditionals()) {
497 // check that child is an access
498 if (access->getTagProperty().getTag() == SUMO_TAG_ACCESS) {
499 for (const auto& lane : pedestrianLanes) {
500 if (access->getParentLanes().front() == lane) {
501 // found, then return true
502 return true;
503 }
504 }
505 }
506 }
507 // There isn't a valid access, then return false
508 return false;
509}
510
511
512bool
514 return myPathCalculatorUpdated;
515}
516
517
518void
520 myPathCalculatorUpdated = false;
521}
522
523
524std::vector<GNEEdge*>
525GNEPathManager::PathCalculator::optimizeJunctionPath(const std::vector<GNEEdge*>& edges) const {
526 bool stop = false;
527 std::vector<GNEEdge*> solutionA, solutionB;
528 // get from and to junctions
529 const auto fromJunction = edges.front()->getFromJunction();
530 const auto toJunction = edges.back()->getToJunction();
531 // first optimize from Junction
532 for (auto it = edges.rbegin(); (it != edges.rend()) && !stop; it++) {
533 solutionA.insert(solutionA.begin(), *it);
534 if ((*it)->getFromJunction() == fromJunction) {
535 stop = true;
536 }
537 }
538 // optimize to edge
539 stop = false;
540 for (auto it = solutionA.begin(); (it != solutionA.end()) && !stop; it++) {
541 solutionB.push_back(*it);
542 if ((*it)->getToJunction() == toJunction) {
543 stop = true;
544 }
545 }
546 return solutionB;
547}
548
549// ---------------------------------------------------------------------------
550// GNEPathManager::PathDraw - methods
551// ---------------------------------------------------------------------------
552
554
555
557
558
559void
561 // just clear myDrawedElements
562 myLaneDrawedElements.clear();
563 myLane2laneDrawedElements.clear();
564}
565
566
567bool
569 // check conditions
571 return true;
572 } else if (myLaneDrawedElements.count(lane) > 0) {
573 // check tag
574 if (myLaneDrawedElements.at(lane).count(tag) > 0) {
575 // element type was already inserted, then don't draw geometry
576 return false;
577 } else {
578 // insert tag for the given lane
579 myLaneDrawedElements.at(lane).insert(tag);
580 // draw geometry
581 return true;
582 }
583 } else {
584 // insert lane and tag
585 myLaneDrawedElements[lane].insert(tag);
586 // draw geometry
587 return true;
588 }
589}
590
591
592bool
594 // check conditions
596 return true;
597 } else {
598 // declare lane2lane
599 const std::pair<const GNELane*, const GNELane*> lane2lane(segment->getPreviousLane(), segment->getNextLane());
600 // check lane2lane
601 if (myLane2laneDrawedElements.count(lane2lane) > 0) {
602 // check tag
603 if (myLane2laneDrawedElements.at(lane2lane).count(tag) > 0) {
604 // element type was already inserted, then don't draw geometry
605 return false;
606 } else {
607 // insert tag for the given lane2lane
608 myLane2laneDrawedElements.at(lane2lane).insert(tag);
609 // draw geometry
610 return true;
611 }
612 } else {
613 // insert lane2lane and tag
614 myLane2laneDrawedElements[lane2lane].insert(tag);
615 // draw geometry
616 return true;
617 }
618 }
619}
620
621// ---------------------------------------------------------------------------
622// GNEPathManager - methods
623// ---------------------------------------------------------------------------
624
629
630
632 // clear paths
634 // delete route calculator Instance
635 delete myPathCalculator;
636 // delete path draw
637 delete myPathDraw;
638}
639
640
645
646
649 // first parse pathElement
650 const auto pathElement = dynamic_cast<const GNEPathManager::PathElement*>(GLObject);
651 if (pathElement == nullptr) {
652 return nullptr;
653 } else {
654 // find it in paths
655 auto it = myPaths.find(pathElement);
656 if (it == myPaths.end()) {
657 return nullptr;
658 } else {
659 return it->first;
660 }
661 }
662}
663
664
665const std::vector<GNEPathManager::Segment*>&
667 if (myPaths.count(pathElement) > 0) {
668 return myPaths.at(pathElement);
669 } else {
670 return myEmptySegments;
671 }
672}
673
674
679
680
681bool
682GNEPathManager::isPathValid(const PathElement* pathElement) const {
683 // first check if path element exist
684 if (myPaths.count(pathElement) > 0) {
685 // iterate over all segments
686 for (const auto& segment : myPaths.at(pathElement)) {
687 // if we have two consecutive lane segments, then path isn't valid
688 if (segment->getLane() && segment->getNextLane()) {
689 return false;
690 }
691 }
692 // all ok, then return true
693 return true;
694 } else {
695 return false;
696 }
697}
698
699
700const GNELane*
701GNEPathManager::getFirstLane(const PathElement* pathElement) const {
702 if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
703 return myPaths.at(pathElement).front()->getLane();
704 } else {
705 return nullptr;
706 }
707}
708
709
710
711void
713 // build path
714 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toLane->getParentEdge()),
715 fromLane, nullptr, toLane, nullptr);
716}
717
718
719void
720GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNELane* fromLane, GNEJunction* toJunction) {
721 // build path
722 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toJunction),
723 fromLane, nullptr, nullptr, toJunction);
724}
725
726
727void
728GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNEJunction* fromJunction, GNELane* toLane) {
729 // build path
730 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toLane->getParentEdge()),
731 nullptr, fromJunction, toLane, nullptr);
732}
733
734
735void
736GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEJunction* toJunction) {
737 // build path
738 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toJunction), nullptr, fromJunction, nullptr, toJunction);
739}
740
741
742void
743GNEPathManager::calculatePath(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
744 // build path
745 if (edges.size() > 0) {
746 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, edges),
747 edges.front()->getLaneByAllowedVClass(vClass), nullptr, edges.back()->getLaneByAllowedVClass(vClass), nullptr);
748 } else {
749 removePath(pathElement);
750 }
751}
752
753
754void
755GNEPathManager::calculateConsecutivePathEdges(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges,
756 const int firstLaneIndex, const int lastLaneIndex) {
757 // declare lane vector
758 std::vector<GNELane*> lanes;
759 if (edges.size() > 0) {
760 lanes.reserve(edges.size());
761 // add first lane
762 if ((firstLaneIndex >= 0) && (firstLaneIndex < (int)edges.front()->getLanes().size())) {
763 lanes.push_back(edges.front()->getLanes().at(firstLaneIndex));
764 } else {
765 lanes.push_back(edges.front()->getLaneByAllowedVClass(vClass));
766 }
767 // add rest of lanes
768 if (edges.size() > 1) {
769 // add middle lanes
770 for (int i = 1; i < ((int)edges.size() - 1); i++) {
771 lanes.push_back(edges[i]->getLaneByAllowedVClass(vClass));
772 }
773 // add last lane
774 if ((lastLaneIndex >= 0) && (lastLaneIndex < (int)edges.back()->getLanes().size())) {
775 lanes.push_back(edges.back()->getLanes().at(lastLaneIndex));
776 } else {
777 lanes.push_back(edges.back()->getLaneByAllowedVClass(vClass));
778 }
779 }
780 }
781 // calculate consecutive path lanes
782 calculateConsecutivePathLanes(pathElement, lanes);
783}
784
785
786void
787GNEPathManager::calculateConsecutivePathLanes(PathElement* pathElement, const std::vector<GNELane*>& lanes) {
788 // first remove path element from paths
789 removePath(pathElement);
790 // continue depending of number of lanes
791 if (lanes.size() > 0) {
792 // declare segment vector
793 std::vector<Segment*> segments;
794 // declare last index
795 const int lastIndex = ((int)lanes.size() - 1);
796 // reserve segments
797 segments.reserve(2 * lanes.size());
798 // iterate over lanes
799 for (int i = 0; i < (int)lanes.size(); i++) {
800 // create lane segment
801 new Segment(this, pathElement, lanes.at(i), segments);
802 // continue if this isn't the last lane
803 if (i != lastIndex) {
804 // create junction segments
805 new Segment(this, pathElement, lanes.at(i)->getParentEdge()->getToJunction(), segments);
806 }
807 }
808 // mark label segment
809 markLabelSegment(segments);
810 // add segments in paths
811 myPaths[pathElement] = segments;
812 }
813}
814
815
816void
818 // check if path element exist already in myPaths
819 if (myPaths.find(pathElement) != myPaths.end()) {
820 // delete segments
821 for (const auto& segment : myPaths.at(pathElement)) {
822 delete segment;
823 }
824 // remove path element from myPaths
825 myPaths.erase(pathElement);
826 }
827}
828
829
830void
832 // check detail level and lane segments
833 if (myLaneSegments.count(lane) > 0) {
834 int numRoutes = 0;
835 // first draw selected elements (for drawing over other elements)
836 for (const auto& segment : myLaneSegments.at(lane)) {
837 if (segment->getPathElement()->isPathElementSelected()) {
838 // draw segment
839 segment->getPathElement()->drawLanePartialGL(s, segment, 2);
840 // check if path element is a route
841 if (segment->getPathElement()->isRoute()) {
842 numRoutes++;
843 }
844 }
845 }
846 // now draw non selected elements
847 for (const auto& segment : myLaneSegments.at(lane)) {
848 if (!segment->getPathElement()->isPathElementSelected()) {
849 // draw segment
850 segment->getPathElement()->drawLanePartialGL(s, segment, 0);
851 // check if path element is a route
852 if (segment->getPathElement()->isRoute()) {
853 numRoutes++;
854 }
855 }
856 }
857 // check if draw overlapped routes
858 if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
859 lane->drawOverlappedRoutes(numRoutes);
860 }
861 }
862}
863
864
865void
867 // check detail level and junction segments
868 if (myJunctionSegments.count(junction) > 0) {
869 // first draw selected elements (for drawing over other elements)
870 for (const auto& segment : myJunctionSegments.at(junction)) {
871 if (segment->getPathElement()->isPathElementSelected()) {
872 segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
873 }
874 }
875 // now draw non selected elements
876 for (const auto& segment : myJunctionSegments.at(junction)) {
877 if (!segment->getPathElement()->isPathElementSelected()) {
878 segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
879 }
880 }
881 }
882}
883
884
885void
887 for (const auto& segment : myPaths.at(pathElement)) {
888 if (segment->getLane()) {
889 gViewObjectsHandler.addToRedrawObjects(segment->getLane());
890 } else if (segment->getJunction()) {
891 gViewObjectsHandler.addToRedrawObjects(segment->getJunction());
892 }
893 }
894}
895
896
897void
899 // declare vector for path elements to compute
900 std::vector<PathElement*> pathElementsToCompute;
901 // check lane in laneSegments
902 if (myLaneSegments.count(lane) > 0) {
903 // obtain affected path elements
904 for (const auto& segment : myLaneSegments.at(lane)) {
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 vector for path elements to compute
918 std::vector<PathElement*> pathElementsToCompute;
919 // check junction in junctionSegments
920 if (myJunctionSegments.count(junction) > 0) {
921 // obtain affected path elements
922 for (const auto& segment : myJunctionSegments.at(junction)) {
923 pathElementsToCompute.push_back(segment->getPathElement());
924 }
925 }
926 // compute path elements
927 for (const auto& pathElement : pathElementsToCompute) {
928 pathElement->computePathElement();
929 }
930}
931
932
933void
935 // clear segments quickly
936 myCleaningSegments = true;
937 // clear all segments
938 for (const auto& path : myPaths) {
939 // delete all segments
940 for (const auto& segment : path.second) {
941 delete segment;
942 }
943 }
944 // clear containers
945 myPaths.clear();
946 myJunctionSegments.clear();
947 myLaneSegments.clear();
948 // restore flag
949 myCleaningSegments = false;
950}
951
952
953void
955 myLaneSegments[lane].insert(segment);
956}
957
958
959void
961 myJunctionSegments[junction].insert(segment);
962}
963
964
965void
967 // check if segment has a lane
968 if (segment->getLane()) {
969 auto lane = segment->getLane();
970 myLaneSegments[lane].erase(segment);
971 // clear lane if doesn't have more segments
972 if (myLaneSegments.at(lane).empty()) {
973 myLaneSegments.erase(lane);
974 }
975 }
976 if (segment->getJunction()) {
977 auto junction = segment->getJunction();
978 myJunctionSegments[junction].erase(segment);
979 // clear junction if doesn't have more segments
980 if (myJunctionSegments.at(junction).empty()) {
981 myJunctionSegments.erase(junction);
982 }
983 }
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
1003void
1004GNEPathManager::buildPath(PathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> path,
1005 GNELane* fromLane, GNEJunction* fromJunction, GNELane* toLane, GNEJunction* toJunction) {
1006 // first remove path element from paths
1007 removePath(pathElement);
1008 // declare segment vector
1009 std::vector<Segment*> segments;
1010 // continue if path isn't empty
1011 if (path.size() > 0) {
1012 // declare last index
1013 const int lastIndex = ((int)path.size() - 1);
1014 // reserve segments
1015 segments.reserve(2 * path.size());
1016 if (fromJunction) {
1017 // create lane segment using fromJunction
1018 new Segment(this, pathElement, fromJunction, segments);
1019 }
1020 // iterate over path
1021 for (int i = 0; i < (int)path.size(); i++) {
1022 if ((i == 0) && fromLane) {
1023 // create lane segment using fromLane
1024 new Segment(this, pathElement, fromLane, segments);
1025 // continue if this isn't the last path edge
1026 if (i != lastIndex) {
1027 // create junction segment using to junction
1028 new Segment(this, pathElement, path.at(i)->getToJunction(), segments);
1029 }
1030 } else if ((i == lastIndex) && toLane) {
1031 // create lane segment using toLane
1032 new Segment(this, pathElement, toLane, segments);
1033 } else {
1034 // get first allowed lane
1035 const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
1036 // create lane segment
1037 new Segment(this, pathElement, lane, segments);
1038 // continue if this isn't the last path edge
1039 if (i != lastIndex) {
1040 // create junction segment using to junction
1041 new Segment(this, pathElement, path.at(i)->getToJunction(), segments);
1042 }
1043 }
1044 }
1045 if (toJunction) {
1046 // create lane segment using toJunction
1047 new Segment(this, pathElement, toJunction, segments);
1048 }
1049 // mark label segment
1050 markLabelSegment(segments);
1051 // add segments in paths
1052 myPaths[pathElement] = segments;
1053 } else {
1054 // create first segment
1055 Segment* firstSegment = nullptr;
1056 Segment* lastSegment = nullptr;
1057 // continue depending of from-to elements
1058 if (fromLane) {
1059 firstSegment = new Segment(this, pathElement, fromLane, segments);
1060 } else if (fromJunction) {
1061 firstSegment = new Segment(this, pathElement, fromJunction, segments);
1062 }
1063 if (toLane) {
1064 lastSegment = new Segment(this, pathElement, toLane, segments);
1065 } else if (toJunction) {
1066 lastSegment = new Segment(this, pathElement, toJunction, segments);
1067 }
1068 // continue depending of segments
1069 if (firstSegment && lastSegment) {
1070 // mark segment as label segment
1071 firstSegment->markSegmentLabel();
1072 // add segments in path
1073 myPaths[pathElement] = segments;
1074 } else {
1075 delete firstSegment;
1076 delete lastSegment;
1077 }
1078 }
1079}
1080
1081
1082void
1083GNEPathManager::markLabelSegment(const std::vector<Segment*>& segments) const {
1084 // separate junction segments and lane segments
1085 std::vector<Segment*> laneSegments;
1086 laneSegments.reserve(segments.size());
1087 for (const auto& segment : segments) {
1088 if (segment->getLane()) {
1089 laneSegments.push_back(segment);
1090 }
1091 }
1092 // get lane segment index
1093 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
1094 // mark middle label as label segment
1095 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
1096}
1097
1098/****************************************************************************/
GUIGlObjectType
GUIViewObjectsHandler gViewObjectsHandler
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:779
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:1116
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1122
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:622
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1686
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:1551
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:125
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2147
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 DijkstraRouter (needed a good calculation of dijkstra path after modifying network)
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
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)
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
void addPathElementToRedrawBuffer(const GNEPathManager::PathElement *pathElement) const
add path elements to redraw buffer
void markLabelSegment(const std::vector< Segment * > &segments) const
mark label segment
PathCalculator * myPathCalculator
PathCalculator instance.
void invalidateLanePath(const GNELane *lane)
invalidate lane path
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 GNELane *, std::set< Segment * > > myLaneSegments
map with lane 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)
bool myCleaningSegments
flag for clear segments quickly
void calculateConsecutivePathEdges(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges, const int firstLaneIndex=-1, const int lastLaneIndex=-1)
calculate consecutive path edges
PathDraw * myPathDraw
PathDraw instance.
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
void calculateConsecutivePathLanes(PathElement *pathElement, const std::vector< GNELane * > &lanes)
calculate consecutive path lanes
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)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
void addToRedrawObjects(const GUIGlObject *GLObject)
get redrawing objects
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:593
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1428
double getSpeed() const
Returns the speed allowed on this edge.
Definition NBEdge.h:619
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition NBEdge.cpp:1286
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)