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-2025 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/GNESegment.h>
25#include <netedit/GNEViewNet.h>
28
29#include "GNEPathManager.h"
30
31// ===========================================================================
32// member method definitions
33// ===========================================================================
34
35// ---------------------------------------------------------------------------
36// GNEPathManager::PathCalculator - methods
37// ---------------------------------------------------------------------------
38
40 myNet(net),
41 myPathCalculatorUpdated(false),
42 myDijkstraRouter(nullptr) {
43 // create myDijkstraRouter
46 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
47}
48
49
51 delete myDijkstraRouter;
52}
53
54
55void
57 // simply delete and create myDijkstraRouter again
58 if (myDijkstraRouter) {
59 delete myDijkstraRouter;
60 }
61 myDijkstraRouter = new DijkstraRouter<NBRouterEdge, NBVehicle>(
62 myNet->getNetBuilder()->getEdgeCont().getAllRouterEdges(),
63 true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
64 // update flag
65 myPathCalculatorUpdated = true;
66}
67
68
69std::vector<GNEEdge*>
70GNEPathManager::PathCalculator::calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) const {
71 // declare a solution vector
72 std::vector<GNEEdge*> solution;
73 // check if path calculator is updated
74 if (!myPathCalculatorUpdated) {
75 // use partialEdges as solution
76 solution = edges;
77 return solution;
78 }
79 // calculate route depending of number of partial edges
80 if (edges.size() == 0) {
81 // partial edges empty, then return a empty vector
82 return solution;
83 } else if (edges.size() == 1) {
84 // if there is only one partialEdges, path has only one edge
85 solution.push_back(edges.front());
86 return solution;
87 } else if ((edges.size() == 2) && (edges.front() == edges.back())) {
88 // typical case for stops. Used to avoid unnecesary calls to compute
89 solution.push_back(edges.front());
90 return solution;
91 } else {
92 // declare temporal vehicle
93 NBVehicle tmpVehicle("temporalNBVehicle", vClass);
94 // obtain pointer to GNENet
95 GNENet* net = edges.front()->getNet();
96 // iterate over every selected myEdges
97 for (int i = 1; i < (int)edges.size(); i++) {
98 // ignore consecutive edges
99 if (edges.at(i - 1)->getNBEdge() != edges.at(i)->getNBEdge()) {
100 // declare a temporal route in which save route between two last myEdges
101 std::vector<const NBRouterEdge*> partialRoute;
102 myDijkstraRouter->compute(edges.at(i - 1)->getNBEdge(), edges.at(i)->getNBEdge(), &tmpVehicle, 10, partialRoute);
103 // if partial route is empty, return empty route
104 if (partialRoute.empty()) {
105 return {};
106 } else {
107 // save partial route in solution
108 for (const auto& edgeID : partialRoute) {
109 solution.push_back(net->getAttributeCarriers()->retrieveEdge(edgeID->getID()));
110 }
111 }
112 }
113 }
114 }
115 // filter solution
116 auto solutionIt = solution.begin();
117 // iterate over solution
118 while (solutionIt != solution.end()) {
119 if ((solutionIt + 1) != solution.end()) {
120 // if next edge is the same of current edge, remove it
121 if (*solutionIt == *(solutionIt + 1)) {
122 solutionIt = solution.erase(solutionIt);
123 } else {
124 solutionIt++;
125 }
126 } else {
127 solutionIt++;
128 }
129 }
130 return solution;
131}
132
133
134std::vector<GNEEdge*>
136 return calculateDijkstraPath(vClass, {fromEdge, toEdge});
137}
138
139
140std::vector<GNEEdge*>
142 std::vector<GNEEdge*> edges;
143 // get from and to edges
144 const auto toEdges = toJunction->getGNEIncomingEdges();
145 // try to find a path
146 for (const auto& toEdge : toEdges) {
147 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
148 // if a path was found, clean it
149 if (edges.size() > 0) {
150 return optimizeJunctionPath(edges);
151 }
152 }
153 return {};
154}
155
156
157std::vector<GNEEdge*>
159 std::vector<GNEEdge*> edges;
160 // get from and to edges
161 const auto fromEdges = fromJunction->getGNEOutgoingEdges();
162 // try to find a path
163 for (const auto& fromEdge : fromEdges) {
164 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
165 // if a path was found, clean it
166 if (edges.size() > 0) {
167 return optimizeJunctionPath(edges);
168 }
169 }
170 return {};
171}
172
173
174std::vector<GNEEdge*>
176 std::vector<GNEEdge*> edges;
177 // get from and to edges
178 const auto fromEdges = fromJunction->getGNEOutgoingEdges();
179 const auto toEdges = toJunction->getGNEIncomingEdges();
180 // try to find a path
181 for (const auto& fromEdge : fromEdges) {
182 for (const auto& toEdge : toEdges) {
183 edges = calculateDijkstraPath(vClass, fromEdge, toEdge);
184 // if a path was found, clean it
185 if (edges.size() > 0) {
186 return optimizeJunctionPath(edges);
187 }
188 }
189 }
190 return {};
191}
192
193
194void
196 // first reset reachability of all lanes
197 for (const auto& edge : originEdge->getNet()->getAttributeCarriers()->getEdges()) {
198 for (const auto& lane : edge.second->getChildLanes()) {
199 lane->resetReachability();
200 }
201 }
202 // get max speed
203 const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(vClass).maxSpeed;
204 // declare map for reachable edges
205 std::map<GNEEdge*, double> reachableEdges;
206 // init first edge
207 reachableEdges[originEdge] = 0;
208 // declare a vector for checked edges
209 std::vector<GNEEdge*> check;
210 // add first edge
211 check.push_back(originEdge);
212 // continue while there is edges to check
213 while (check.size() > 0) {
214 GNEEdge* edge = check.front();
215 check.erase(check.begin());
216 double traveltime = reachableEdges[edge];
217 for (const auto& lane : edge->getChildLanes()) {
218 if ((edge->getNBEdge()->getLaneStruct(lane->getIndex()).permissions & vClass) == vClass) {
219 lane->setReachability(traveltime);
220 }
221 }
222 // update traveltime
223 traveltime += edge->getNBEdge()->getLength() / MIN2(edge->getNBEdge()->getSpeed(), defaultMaxSpeed);
224 std::vector<GNEEdge*> sucessors;
225 // get successor edges
226 for (const auto& sucessorEdge : edge->getToJunction()->getGNEOutgoingEdges()) {
227 // check if edge is connected with successor edge
228 if (consecutiveEdgesConnected(vClass, edge, sucessorEdge)) {
229 sucessors.push_back(sucessorEdge);
230 }
231 }
232 // add successors to check vector
233 for (const auto& nextEdge : sucessors) {
234 // revisit edge via faster path
235 if ((reachableEdges.count(nextEdge) == 0) || (reachableEdges[nextEdge] > traveltime)) {
236 reachableEdges[nextEdge] = traveltime;
237 check.push_back(nextEdge);
238 }
239 }
240 }
241}
242
243
244bool
246 // check conditions
247 if ((from == nullptr) || (to == nullptr)) {
248 // myEdges cannot be null
249 return false;
250 } else if (from == to) {
251 // the same edge cannot be consecutive of itself
252 return false;
253 } else if (vClass == SVC_PEDESTRIAN) {
254 // for pedestrians consecutive myEdges are always connected
255 return true;
256 } else {
257 // iterate over connections of from edge
258 for (const auto& fromLane : from->getChildLanes()) {
259 for (const auto& fromConnection : from->getGNEConnections()) {
260 // within from loop, iterate ove to lanes
261 for (const auto& toLane : to->getChildLanes()) {
262 if (fromConnection->getLaneTo() == toLane) {
263 // get lane structs for both lanes
264 const NBEdge::Lane NBFromLane = from->getNBEdge()->getLaneStruct(fromLane->getIndex());
265 const NBEdge::Lane NBToLane = to->getNBEdge()->getLaneStruct(toLane->getIndex());
266 // check vClass
267 if (((NBFromLane.permissions & vClass) == vClass) &&
268 ((NBToLane.permissions & vClass) == vClass)) {
269 return true;
270 }
271 }
272 }
273 }
274 }
275 return false;
276 }
277}
278
279
280bool
282 if (busStop->getTagProperty()->getTag() != SUMO_TAG_BUS_STOP) {
283 return false;
284 }
285 // check if busstop is placed over a pedestrian lane
286 if ((busStop->getParentLanes().front()->getParentEdge() == edge) &&
287 (edge->getNBEdge()->getLaneStruct(busStop->getParentLanes().front()->getIndex()).permissions & SVC_PEDESTRIAN) != 0) {
288 // busStop is placed over an lane that supports pedestrians, then return true
289 return true;
290 }
291 // obtain a list with all edge lanes that supports pedestrians
292 std::vector<GNELane*> pedestrianLanes;
293 for (int laneIndex = 0; laneIndex < (int)edge->getChildLanes().size(); laneIndex++) {
294 if ((edge->getNBEdge()->getLaneStruct(laneIndex).permissions & SVC_PEDESTRIAN) != 0) {
295 pedestrianLanes.push_back(edge->getChildLanes().at(laneIndex));
296 }
297 }
298 // check if exist an access between busStop and pedestrian lanes
299 for (const auto& access : busStop->getChildAdditionals()) {
300 // check that child is an access
301 if (access->getTagProperty()->getTag() == SUMO_TAG_ACCESS) {
302 for (const auto& lane : pedestrianLanes) {
303 if (access->getParentLanes().front() == lane) {
304 // found, then return true
305 return true;
306 }
307 }
308 }
309 }
310 // There isn't a valid access, then return false
311 return false;
312}
313
314
315bool
317 return myPathCalculatorUpdated;
318}
319
320
321void
323 myPathCalculatorUpdated = false;
324}
325
326
327std::vector<GNEEdge*>
328GNEPathManager::PathCalculator::optimizeJunctionPath(const std::vector<GNEEdge*>& edges) const {
329 bool stop = false;
330 std::vector<GNEEdge*> solutionA, solutionB;
331 // get from and to junctions
332 const auto fromJunction = edges.front()->getFromJunction();
333 const auto toJunction = edges.back()->getToJunction();
334 // first optimize from Junction
335 for (auto it = edges.rbegin(); (it != edges.rend()) && !stop; it++) {
336 solutionA.insert(solutionA.begin(), *it);
337 if ((*it)->getFromJunction() == fromJunction) {
338 stop = true;
339 }
340 }
341 // optimize to edge
342 stop = false;
343 for (auto it = solutionA.begin(); (it != solutionA.end()) && !stop; it++) {
344 solutionB.push_back(*it);
345 if ((*it)->getToJunction() == toJunction) {
346 stop = true;
347 }
348 }
349 return solutionB;
350}
351
352// ---------------------------------------------------------------------------
353// GNEPathManager::PathDraw - methods
354// ---------------------------------------------------------------------------
355
357
358
360
361
362void
364 // just clear myDrawedElements
365 myLaneDrawedElements.clear();
366 myLane2laneDrawedElements.clear();
367}
368
369
370bool
372 const SumoXMLTag tag, const bool isPlan) {
373 // check conditions
375 return true;
376 } else if (myLaneDrawedElements.count(lane) > 0) {
377 // check tag
378 if (!isPlan && myLaneDrawedElements.at(lane).count(tag) > 0) {
379 // element type was already inserted, then don't draw geometry
380 return false;
381 } else {
382 // insert tag for the given lane
383 myLaneDrawedElements.at(lane).insert(tag);
384 // draw geometry
385 return true;
386 }
387 } else {
388 // insert lane and tag
389 myLaneDrawedElements[lane].insert(tag);
390 // draw geometry
391 return true;
392 }
393}
394
395
396bool
398 const SumoXMLTag tag, const bool isPlan) {
399 // check conditions
401 return true;
402 } else {
403 // declare lane2lane
404 const std::pair<const GNELane*, const GNELane*> lane2lane(segment->getPreviousLane(), segment->getNextLane());
405 // check lane2lane
406 if (myLane2laneDrawedElements.count(lane2lane) > 0) {
407 // check tag
408 if (!isPlan && myLane2laneDrawedElements.at(lane2lane).count(tag) > 0) {
409 // element type was already inserted, then don't draw geometry
410 return false;
411 } else {
412 // insert tag for the given lane2lane
413 myLane2laneDrawedElements.at(lane2lane).insert(tag);
414 // draw geometry
415 return true;
416 }
417 } else {
418 // insert lane2lane and tag
419 myLane2laneDrawedElements[lane2lane].insert(tag);
420 // draw geometry
421 return true;
422 }
423 }
424}
425
426// ---------------------------------------------------------------------------
427// GNEPathManager - methods
428// ---------------------------------------------------------------------------
429
434
435
437 // clear paths
439 // delete route calculator Instance
440 delete myPathCalculator;
441 // delete path draw
442 delete myPathDraw;
443}
444
445
450
451
452const GNEPathElement*
454 // first parse pathElement
455 const auto pathElement = dynamic_cast<const GNEPathElement*>(GLObject);
456 if (pathElement == nullptr) {
457 return nullptr;
458 } else {
459 // find it in paths
460 auto it = myPaths.find(pathElement);
461 if (it == myPaths.end()) {
462 return nullptr;
463 } else {
464 return it->first;
465 }
466 }
467}
468
469
470const std::vector<GNESegment*>&
472 if (myPaths.count(pathElement) > 0) {
473 return myPaths.at(pathElement);
474 } else {
475 return myEmptySegments;
476 }
477}
478
479
484
485
486bool
488 // first check if path element exist
489 if (myPaths.count(pathElement) > 0) {
490 // iterate over all segments
491 for (const auto& segment : myPaths.at(pathElement)) {
492 // if we have two consecutive lane segments, then path isn't valid
493 if (segment->getLane() && segment->getNextLane()) {
494 return false;
495 }
496 }
497 // all ok, then return true
498 return true;
499 } else {
500 return false;
501 }
502}
503
504
505const GNELane*
507 if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
508 return myPaths.at(pathElement).front()->getLane();
509 } else {
510 return nullptr;
511 }
512}
513
514
515
516void
518 // build path
519 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toLane->getParentEdge()),
520 fromLane, nullptr, toLane, nullptr);
521}
522
523
524void
526 // build path
527 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toJunction),
528 fromLane, nullptr, nullptr, toJunction);
529}
530
531
532void
534 // build path
535 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toLane->getParentEdge()),
536 nullptr, fromJunction, toLane, nullptr);
537}
538
539
540void
542 // build path
543 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toJunction), nullptr, fromJunction, nullptr, toJunction);
544}
545
546
547void
548GNEPathManager::calculatePath(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
549 // build path
550 if (edges.size() > 0) {
551 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, edges),
552 edges.front()->getLaneByAllowedVClass(vClass), nullptr, edges.back()->getLaneByAllowedVClass(vClass), nullptr);
553 } else {
554 removePath(pathElement);
555 }
556}
557
558
559void
560GNEPathManager::calculateConsecutivePathEdges(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges,
561 const int firstLaneIndex, const int lastLaneIndex) {
562 // declare lane vector
563 std::vector<GNELane*> lanes;
564 if (edges.size() > 0) {
565 lanes.reserve(edges.size());
566 // add first lane
567 if ((firstLaneIndex >= 0) && (firstLaneIndex < (int)edges.front()->getChildLanes().size())) {
568 lanes.push_back(edges.front()->getChildLanes().at(firstLaneIndex));
569 } else {
570 lanes.push_back(edges.front()->getLaneByAllowedVClass(vClass));
571 }
572 // add rest of lanes
573 if (edges.size() > 1) {
574 // add middle lanes
575 for (int i = 1; i < ((int)edges.size() - 1); i++) {
576 lanes.push_back(edges[i]->getLaneByAllowedVClass(vClass));
577 }
578 // add last lane
579 if ((lastLaneIndex >= 0) && (lastLaneIndex < (int)edges.back()->getChildLanes().size())) {
580 lanes.push_back(edges.back()->getChildLanes().at(lastLaneIndex));
581 } else {
582 lanes.push_back(edges.back()->getLaneByAllowedVClass(vClass));
583 }
584 }
585 }
586 // calculate consecutive path lanes
587 calculateConsecutivePathLanes(pathElement, lanes);
588}
589
590
591void
592GNEPathManager::calculateConsecutivePathLanes(GNEPathElement* pathElement, const std::vector<GNELane*>& lanes) {
593 // first remove path element from paths
594 removePath(pathElement);
595 // continue depending of number of lanes
596 if (lanes.size() > 0) {
597 // declare segment vector
598 std::vector<GNESegment*> segments;
599 // declare last index
600 const int lastIndex = ((int)lanes.size() - 1);
601 // reserve segments
602 segments.reserve(2 * lanes.size());
603 // iterate over lanes
604 for (int i = 0; i < (int)lanes.size(); i++) {
605 // create lane segment
606 new GNESegment(this, pathElement, lanes.at(i), segments);
607 // continue if this isn't the last lane
608 if (i != lastIndex) {
609 // create junction segments
610 new GNESegment(this, pathElement, lanes.at(i)->getParentEdge()->getToJunction(), segments);
611 }
612 }
613 // mark label segment
614 markLabelSegment(segments);
615 // add segments in paths
616 myPaths[pathElement] = segments;
617 }
618}
619
620
621void
623 // check if path element exist already in myPaths
624 if (myPaths.find(pathElement) != myPaths.end()) {
625 // delete segments
626 for (const auto& segment : myPaths.at(pathElement)) {
627 delete segment;
628 }
629 // remove path element from myPaths
630 myPaths.erase(pathElement);
631 }
632}
633
634
635void
637 // check detail level and lane segments
638 if (myLaneSegments.count(lane) > 0) {
639 int numRoutes = 0;
640 // first draw the elements marked for redraw
641 for (const auto& segment : myLaneSegments.at(lane)) {
642 if (gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
643 segment->getPathElement()->drawLanePartialGL(s, segment, 2);
644 // check if path element is a route
645 if (segment->getPathElement()->isRoute()) {
646 numRoutes++;
647 }
648 }
649 }
650 // now draw the rest of segments
651 for (const auto& segment : myLaneSegments.at(lane)) {
652 if (!gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
653 segment->getPathElement()->drawLanePartialGL(s, segment, 0);
654 // check if path element is a route
655 if (segment->getPathElement()->isRoute()) {
656 numRoutes++;
657 }
658 }
659 }
660 // check if draw overlapped routes
661 if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
662 lane->drawOverlappedRoutes(numRoutes);
663 }
664 }
665}
666
667
668void
670 // check detail level and junction segments
671 if (myJunctionSegments.count(junction) > 0) {
672 // first draw the elements marked for redraw
673 for (const auto& segment : myJunctionSegments.at(junction)) {
674 if (gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
675 segment->getPathElement()->drawJunctionPartialGL(s, segment, 2);
676 }
677 }
678 // now draw the rest of segments
679 for (const auto& segment : myJunctionSegments.at(junction)) {
680 if (!gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
681 segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
682 }
683 }
684 }
685}
686
687
688void
690 // draw every segment partial
691 for (const auto& pathElementToRedraw : gViewObjectsHandler.getRedrawPathElements()) {
692 const auto it = myPaths.find(pathElementToRedraw);
693 if (it != myPaths.end()) {
694 for (const auto& segment : it->second) {
695 if (segment->getLane()) {
696 // draw with high offset
697 it->first->drawLanePartialGL(s, segment, 3);
698 } else if (segment->getJunction()) {
699 // draw with high offset
700 it->first->drawJunctionPartialGL(s, segment, 3);
701 }
702 }
703 }
704 }
705}
706
707
708void
710 // declare vector for path elements to compute
711 std::vector<GNEPathElement*> pathElementsToCompute;
712 // check lane in laneSegments
713 if (myLaneSegments.count(lane) > 0) {
714 // obtain affected path elements
715 for (const auto& segment : myLaneSegments.at(lane)) {
716 pathElementsToCompute.push_back(segment->getPathElement());
717 }
718 }
719 // compute path elements
720 for (const auto& pathElement : pathElementsToCompute) {
721 pathElement->computePathElement();
722 }
723}
724
725
726void
728 // declare vector for path elements to compute
729 std::vector<GNEPathElement*> pathElementsToCompute;
730 // check junction in junctionSegments
731 if (myJunctionSegments.count(junction) > 0) {
732 // obtain affected path elements
733 for (const auto& segment : myJunctionSegments.at(junction)) {
734 pathElementsToCompute.push_back(segment->getPathElement());
735 }
736 }
737 // compute path elements
738 for (const auto& pathElement : pathElementsToCompute) {
739 pathElement->computePathElement();
740 }
741}
742
743
744void
746 // clear segments quickly
747 myCleaningSegments = true;
748 // clear all segments
749 for (const auto& path : myPaths) {
750 // delete all segments
751 for (const auto& segment : path.second) {
752 delete segment;
753 }
754 }
755 // clear containers
756 myPaths.clear();
757 myJunctionSegments.clear();
758 myLaneSegments.clear();
759 // restore flag
760 myCleaningSegments = false;
761}
762
763
764void
766 myLaneSegments[lane].insert(segment);
767}
768
769
770void
772 myJunctionSegments[junction].insert(segment);
773}
774
775
776void
778 // check if segment has a lane
779 if (segment->getLane()) {
780 auto lane = segment->getLane();
781 myLaneSegments[lane].erase(segment);
782 // clear lane if doesn't have more segments
783 if (myLaneSegments.at(lane).empty()) {
784 myLaneSegments.erase(lane);
785 }
786 }
787 if (segment->getJunction()) {
788 auto junction = segment->getJunction();
789 myJunctionSegments[junction].erase(segment);
790 // clear junction if doesn't have more segments
791 if (myJunctionSegments.at(junction).empty()) {
792 myJunctionSegments.erase(junction);
793 }
794 }
795}
796
797
798bool
799GNEPathManager::connectedLanes(const GNELane* fromLane, const GNELane* toLane) const {
800 // get from and to NBEdges
801 NBEdge* fromNBEdge = fromLane->getParentEdge()->getNBEdge();
802 NBEdge* toNBEdge = toLane->getParentEdge()->getNBEdge();
803 // get connections vinculated with from Lane
804 const std::vector<NBEdge::Connection> connections = fromNBEdge->getConnectionsFromLane(fromLane->getIndex());
805 // find connection
806 std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
807 connections.begin(), connections.end(),
808 NBEdge::connections_finder(fromLane->getIndex(), toNBEdge, toLane->getIndex()));
809 // check if connection was found
810 return (con_it != connections.end());
811}
812
813
814void
815GNEPathManager::buildPath(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> path,
816 GNELane* fromLane, GNEJunction* fromJunction, GNELane* toLane, GNEJunction* toJunction) {
817 // first remove path element from paths
818 removePath(pathElement);
819 // declare segment vector
820 std::vector<GNESegment*> segments;
821 // continue if path isn't empty
822 if (path.size() > 0) {
823 // declare last index
824 const int lastIndex = ((int)path.size() - 1);
825 // reserve segments
826 segments.reserve(2 * path.size());
827 if (fromJunction) {
828 // create lane segment using fromJunction
829 new GNESegment(this, pathElement, fromJunction, segments);
830 }
831 // iterate over path
832 for (int i = 0; i < (int)path.size(); i++) {
833 if ((i == 0) && fromLane) {
834 // create lane segment using fromLane
835 new GNESegment(this, pathElement, fromLane, segments);
836 // continue if this isn't the last path edge
837 if (i != lastIndex) {
838 // create junction segment using to junction
839 new GNESegment(this, pathElement, path.at(i)->getToJunction(), segments);
840 }
841 } else if ((i == lastIndex) && toLane) {
842 // create lane segment using toLane
843 new GNESegment(this, pathElement, toLane, segments);
844 } else {
845 // get first allowed lane
846 const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
847 // create lane segment
848 new GNESegment(this, pathElement, lane, segments);
849 // continue if this isn't the last path edge
850 if (i != lastIndex) {
851 // create junction segment using to junction
852 new GNESegment(this, pathElement, path.at(i)->getToJunction(), segments);
853 }
854 }
855 }
856 if (toJunction) {
857 // create lane segment using toJunction
858 new GNESegment(this, pathElement, toJunction, segments);
859 }
860 // mark label segment
861 markLabelSegment(segments);
862 // add segments in paths
863 myPaths[pathElement] = segments;
864 } else {
865 // create first segment
866 GNESegment* firstSegment = nullptr;
867 GNESegment* lastSegment = nullptr;
868 // continue depending of from-to elements
869 if (fromLane) {
870 firstSegment = new GNESegment(this, pathElement, fromLane, segments);
871 } else if (fromJunction) {
872 firstSegment = new GNESegment(this, pathElement, fromJunction, segments);
873 }
874 if (toLane) {
875 lastSegment = new GNESegment(this, pathElement, toLane, segments);
876 } else if (toJunction) {
877 lastSegment = new GNESegment(this, pathElement, toJunction, segments);
878 }
879 // continue depending of segments
880 if (firstSegment && lastSegment) {
881 // mark segment as label segment
882 firstSegment->markSegmentLabel();
883 // add segments in path
884 myPaths[pathElement] = segments;
885 } else {
886 delete firstSegment;
887 delete lastSegment;
888 }
889 }
890}
891
892
893void
894GNEPathManager::markLabelSegment(const std::vector<GNESegment*>& segments) const {
895 // separate junction segments and lane segments
896 std::vector<GNESegment*> laneSegments;
897 laneSegments.reserve(segments.size());
898 for (const auto& segment : segments) {
899 if (segment->getLane()) {
900 laneSegments.push_back(segment);
901 }
902 }
903 // get lane segment index
904 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
905 // mark middle label as label segment
906 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
907}
908
909/****************************************************************************/
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:80
Computes the shortest path through a network using the Dijkstra algorithm.
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:829
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1163
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:79
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
const GNEHierarchicalContainerChildren< GNEAdditional * > & getChildAdditionals() const
return child additionals
const GNEHierarchicalContainerParents< GNELane * > & getParentLanes() const
get parent lanes
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:651
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1703
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:203
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:1616
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
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, const SumoXMLTag tag, const bool isPlan)
check if path element geometry must be drawn in the given lane
void clearPathDraw()
clear path draw
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void buildPath(GNEPathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > path, GNELane *fromLane, GNEJunction *fromJunction, GNELane *toLane, GNEJunction *toJunction)
build path
void calculatePath(GNEPathElement *pathElement, SUMOVehicleClass vClass, GNELane *fromLane, GNELane *toLane)
calculate path between from-to edges (using dijkstra, require path calculator updated)
void invalidateJunctionPath(const GNEJunction *junction)
invalidate junction path
const std::vector< GNESegment * > & getPathElementSegments(GNEPathElement *pathElement) const
get path segments
const GNEPathElement * getPathElement(const GUIGlObject *GLObject) const
get path element
PathDraw * getPathDraw()
obtain instance of PathDraw
void clearSegments()
clear segments
void addSegmentInLaneSegments(GNESegment *segment, const GNELane *lane)
add segments int laneSegments (called by GNESegment constructor)
PathCalculator * myPathCalculator
PathCalculator instance.
void invalidateLanePath(const GNELane *lane)
invalidate lane path
friend class GNESegment
friend class declaration
void markLabelSegment(const std::vector< GNESegment * > &segments) const
mark label segment
void calculateConsecutivePathLanes(GNEPathElement *pathElement, const std::vector< GNELane * > &lanes)
calculate consecutive path lanes
bool connectedLanes(const GNELane *fromLane, const GNELane *toLane) const
check if given lanes are connected
void drawLanePathElements(const GUIVisualizationSettings &s, const GNELane *lane) const
draw lane path elements
bool isPathValid(const GNEPathElement *pathElement) const
check if path element is valid
std::map< const GNEJunction *, std::set< GNESegment * > > myJunctionSegments
map with junction segments
void removePath(GNEPathElement *pathElement)
remove path
void drawJunctionPathElements(const GUIVisualizationSettings &s, const GNEJunction *junction) const
draw junction path elements
const GNELane * getFirstLane(const GNEPathElement *pathElement) const
get first lane associated with path element
bool myCleaningSegments
flag for clear segments quickly
PathDraw * myPathDraw
PathDraw instance.
void clearSegmentFromJunctionAndLaneSegments(GNESegment *segment)
clear segments from junction and lane Segments (called by GNESegment destructor)
std::map< const GNELane *, std::set< GNESegment * > > myLaneSegments
map with lane segments
~GNEPathManager()
destructor
void addSegmentInJunctionSegments(GNESegment *segment, const GNEJunction *junction)
add segments int junctionSegments (called by GNESegment constructor)
GNEPathManager(const GNENet *net)
constructor
void calculateConsecutivePathEdges(GNEPathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges, const int firstLaneIndex=-1, const int lastLaneIndex=-1)
calculate consecutive path edges
void redrawPathElements(const GUIVisualizationSettings &s) const
redraw path elements saved in gViewObjectsHandler buffer
std::map< const GNEPathElement *, std::vector< GNESegment * > > myPaths
map with path element and their associated segments
const std::vector< GNESegment * > myEmptySegments
empty segments (used in getPathElementSegments)
const GNELane * getLane() const
get lane associated with this segment
void markSegmentLabel()
mark segment as middle segment
const GNEJunction * getJunction() const
get junction associated with this segment
const GNELane * getNextLane() const
get next lane
const GNELane * getPreviousLane() const
get previous lane
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
bool isPathElementMarkForRedraw(const GNEPathElement *pathElement) const
check if the given path element has to be redraw again
const std::set< const GNEPathElement * > & getRedrawPathElements() const
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:599
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1440
double getSpeed() const
Returns the speed allowed on this edge.
Definition NBEdge.h:625
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition NBEdge.cpp:1308
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)