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/GNESegment.h>
24#include <netedit/GNEViewNet.h>
27
28#include "GNEPathManager.h"
29
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->getLanes()) {
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->getLanes()) {
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->getLanes()) {
259 for (const auto& fromConnection : from->getGNEConnections()) {
260 // within from loop, iterate ove to lanes
261 for (const auto& toLane : to->getLanes()) {
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->getLanes().size(); laneIndex++) {
294 if ((edge->getNBEdge()->getLaneStruct(laneIndex).permissions & SVC_PEDESTRIAN) != 0) {
295 pedestrianLanes.push_back(edge->getLanes().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 // check conditions
374 return true;
375 } else if (myLaneDrawedElements.count(lane) > 0) {
376 // check tag
377 if (myLaneDrawedElements.at(lane).count(tag) > 0) {
378 // element type was already inserted, then don't draw geometry
379 return false;
380 } else {
381 // insert tag for the given lane
382 myLaneDrawedElements.at(lane).insert(tag);
383 // draw geometry
384 return true;
385 }
386 } else {
387 // insert lane and tag
388 myLaneDrawedElements[lane].insert(tag);
389 // draw geometry
390 return true;
391 }
392}
393
394
395bool
397 // check conditions
399 return true;
400 } else {
401 // declare lane2lane
402 const std::pair<const GNELane*, const GNELane*> lane2lane(segment->getPreviousLane(), segment->getNextLane());
403 // check lane2lane
404 if (myLane2laneDrawedElements.count(lane2lane) > 0) {
405 // check tag
406 if (myLane2laneDrawedElements.at(lane2lane).count(tag) > 0) {
407 // element type was already inserted, then don't draw geometry
408 return false;
409 } else {
410 // insert tag for the given lane2lane
411 myLane2laneDrawedElements.at(lane2lane).insert(tag);
412 // draw geometry
413 return true;
414 }
415 } else {
416 // insert lane2lane and tag
417 myLane2laneDrawedElements[lane2lane].insert(tag);
418 // draw geometry
419 return true;
420 }
421 }
422}
423
424// ---------------------------------------------------------------------------
425// GNEPathManager - methods
426// ---------------------------------------------------------------------------
427
432
433
435 // clear paths
437 // delete route calculator Instance
438 delete myPathCalculator;
439 // delete path draw
440 delete myPathDraw;
441}
442
443
448
449
450const GNEPathElement*
452 // first parse pathElement
453 const auto pathElement = dynamic_cast<const GNEPathElement*>(GLObject);
454 if (pathElement == nullptr) {
455 return nullptr;
456 } else {
457 // find it in paths
458 auto it = myPaths.find(pathElement);
459 if (it == myPaths.end()) {
460 return nullptr;
461 } else {
462 return it->first;
463 }
464 }
465}
466
467
468const std::vector<GNESegment*>&
470 if (myPaths.count(pathElement) > 0) {
471 return myPaths.at(pathElement);
472 } else {
473 return myEmptySegments;
474 }
475}
476
477
482
483
484bool
486 // first check if path element exist
487 if (myPaths.count(pathElement) > 0) {
488 // iterate over all segments
489 for (const auto& segment : myPaths.at(pathElement)) {
490 // if we have two consecutive lane segments, then path isn't valid
491 if (segment->getLane() && segment->getNextLane()) {
492 return false;
493 }
494 }
495 // all ok, then return true
496 return true;
497 } else {
498 return false;
499 }
500}
501
502
503const GNELane*
505 if ((myPaths.count(pathElement) > 0) && (myPaths.at(pathElement).size() > 0)) {
506 return myPaths.at(pathElement).front()->getLane();
507 } else {
508 return nullptr;
509 }
510}
511
512
513
514void
516 // build path
517 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toLane->getParentEdge()),
518 fromLane, nullptr, toLane, nullptr);
519}
520
521
522void
524 // build path
525 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromLane->getParentEdge(), toJunction),
526 fromLane, nullptr, nullptr, toJunction);
527}
528
529
530void
532 // build path
533 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toLane->getParentEdge()),
534 nullptr, fromJunction, toLane, nullptr);
535}
536
537
538void
540 // build path
541 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, fromJunction, toJunction), nullptr, fromJunction, nullptr, toJunction);
542}
543
544
545void
546GNEPathManager::calculatePath(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
547 // build path
548 if (edges.size() > 0) {
549 buildPath(pathElement, vClass, myPathCalculator->calculateDijkstraPath(vClass, edges),
550 edges.front()->getLaneByAllowedVClass(vClass), nullptr, edges.back()->getLaneByAllowedVClass(vClass), nullptr);
551 } else {
552 removePath(pathElement);
553 }
554}
555
556
557void
558GNEPathManager::calculateConsecutivePathEdges(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges,
559 const int firstLaneIndex, const int lastLaneIndex) {
560 // declare lane vector
561 std::vector<GNELane*> lanes;
562 if (edges.size() > 0) {
563 lanes.reserve(edges.size());
564 // add first lane
565 if ((firstLaneIndex >= 0) && (firstLaneIndex < (int)edges.front()->getLanes().size())) {
566 lanes.push_back(edges.front()->getLanes().at(firstLaneIndex));
567 } else {
568 lanes.push_back(edges.front()->getLaneByAllowedVClass(vClass));
569 }
570 // add rest of lanes
571 if (edges.size() > 1) {
572 // add middle lanes
573 for (int i = 1; i < ((int)edges.size() - 1); i++) {
574 lanes.push_back(edges[i]->getLaneByAllowedVClass(vClass));
575 }
576 // add last lane
577 if ((lastLaneIndex >= 0) && (lastLaneIndex < (int)edges.back()->getLanes().size())) {
578 lanes.push_back(edges.back()->getLanes().at(lastLaneIndex));
579 } else {
580 lanes.push_back(edges.back()->getLaneByAllowedVClass(vClass));
581 }
582 }
583 }
584 // calculate consecutive path lanes
585 calculateConsecutivePathLanes(pathElement, lanes);
586}
587
588
589void
590GNEPathManager::calculateConsecutivePathLanes(GNEPathElement* pathElement, const std::vector<GNELane*>& lanes) {
591 // first remove path element from paths
592 removePath(pathElement);
593 // continue depending of number of lanes
594 if (lanes.size() > 0) {
595 // declare segment vector
596 std::vector<GNESegment*> segments;
597 // declare last index
598 const int lastIndex = ((int)lanes.size() - 1);
599 // reserve segments
600 segments.reserve(2 * lanes.size());
601 // iterate over lanes
602 for (int i = 0; i < (int)lanes.size(); i++) {
603 // create lane segment
604 new GNESegment(this, pathElement, lanes.at(i), segments);
605 // continue if this isn't the last lane
606 if (i != lastIndex) {
607 // create junction segments
608 new GNESegment(this, pathElement, lanes.at(i)->getParentEdge()->getToJunction(), segments);
609 }
610 }
611 // mark label segment
612 markLabelSegment(segments);
613 // add segments in paths
614 myPaths[pathElement] = segments;
615 }
616}
617
618
619void
621 // check if path element exist already in myPaths
622 if (myPaths.find(pathElement) != myPaths.end()) {
623 // delete segments
624 for (const auto& segment : myPaths.at(pathElement)) {
625 delete segment;
626 }
627 // remove path element from myPaths
628 myPaths.erase(pathElement);
629 }
630}
631
632
633void
635 // check detail level and lane segments
636 if (myLaneSegments.count(lane) > 0) {
637 int numRoutes = 0;
638 // first draw the elements marked for redraw
639 for (const auto& segment : myLaneSegments.at(lane)) {
640 if (gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
641 segment->getPathElement()->drawLanePartialGL(s, segment, 2);
642 // check if path element is a route
643 if (segment->getPathElement()->isRoute()) {
644 numRoutes++;
645 }
646 }
647 }
648 // now draw the rest of segments
649 for (const auto& segment : myLaneSegments.at(lane)) {
650 if (!gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
651 segment->getPathElement()->drawLanePartialGL(s, segment, 0);
652 // check if path element is a route
653 if (segment->getPathElement()->isRoute()) {
654 numRoutes++;
655 }
656 }
657 }
658 // check if draw overlapped routes
659 if ((numRoutes > 1) && lane->getNet()->getViewNet()->getDemandViewOptions().showOverlappedRoutes()) {
660 lane->drawOverlappedRoutes(numRoutes);
661 }
662 }
663}
664
665
666void
668 // check detail level and junction segments
669 if (myJunctionSegments.count(junction) > 0) {
670 // first draw the elements marked for redraw
671 for (const auto& segment : myJunctionSegments.at(junction)) {
672 if (gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
673 segment->getPathElement()->drawJunctionPartialGL(s, segment, 2);
674 }
675 }
676 // now draw the rest of segments
677 for (const auto& segment : myJunctionSegments.at(junction)) {
678 if (!gViewObjectsHandler.isPathElementMarkForRedraw(segment->getPathElement())) {
679 segment->getPathElement()->drawJunctionPartialGL(s, segment, 0);
680 }
681 }
682 }
683}
684
685
686void
688 // draw every segment partial
689 for (const auto& pathElementToRedraw : gViewObjectsHandler.getRedrawPathElements()) {
690 const auto it = myPaths.find(pathElementToRedraw);
691 if (it != myPaths.end()) {
692 for (const auto& segment : it->second) {
693 if (segment->getLane()) {
694 // draw with high offset
695 it->first->drawLanePartialGL(s, segment, 3);
696 } else if (segment->getJunction()) {
697 // draw with high offset
698 it->first->drawJunctionPartialGL(s, segment, 3);
699 }
700 }
701 }
702 }
703}
704
705
706void
708 // declare vector for path elements to compute
709 std::vector<GNEPathElement*> pathElementsToCompute;
710 // check lane in laneSegments
711 if (myLaneSegments.count(lane) > 0) {
712 // obtain affected path elements
713 for (const auto& segment : myLaneSegments.at(lane)) {
714 pathElementsToCompute.push_back(segment->getPathElement());
715 }
716 }
717 // compute path elements
718 for (const auto& pathElement : pathElementsToCompute) {
719 pathElement->computePathElement();
720 }
721}
722
723
724void
726 // declare vector for path elements to compute
727 std::vector<GNEPathElement*> pathElementsToCompute;
728 // check junction in junctionSegments
729 if (myJunctionSegments.count(junction) > 0) {
730 // obtain affected path elements
731 for (const auto& segment : myJunctionSegments.at(junction)) {
732 pathElementsToCompute.push_back(segment->getPathElement());
733 }
734 }
735 // compute path elements
736 for (const auto& pathElement : pathElementsToCompute) {
737 pathElement->computePathElement();
738 }
739}
740
741
742void
744 // clear segments quickly
745 myCleaningSegments = true;
746 // clear all segments
747 for (const auto& path : myPaths) {
748 // delete all segments
749 for (const auto& segment : path.second) {
750 delete segment;
751 }
752 }
753 // clear containers
754 myPaths.clear();
755 myJunctionSegments.clear();
756 myLaneSegments.clear();
757 // restore flag
758 myCleaningSegments = false;
759}
760
761
762void
764 myLaneSegments[lane].insert(segment);
765}
766
767
768void
770 myJunctionSegments[junction].insert(segment);
771}
772
773
774void
776 // check if segment has a lane
777 if (segment->getLane()) {
778 auto lane = segment->getLane();
779 myLaneSegments[lane].erase(segment);
780 // clear lane if doesn't have more segments
781 if (myLaneSegments.at(lane).empty()) {
782 myLaneSegments.erase(lane);
783 }
784 }
785 if (segment->getJunction()) {
786 auto junction = segment->getJunction();
787 myJunctionSegments[junction].erase(segment);
788 // clear junction if doesn't have more segments
789 if (myJunctionSegments.at(junction).empty()) {
790 myJunctionSegments.erase(junction);
791 }
792 }
793}
794
795
796bool
797GNEPathManager::connectedLanes(const GNELane* fromLane, const GNELane* toLane) const {
798 // get from and to NBEdges
799 NBEdge* fromNBEdge = fromLane->getParentEdge()->getNBEdge();
800 NBEdge* toNBEdge = toLane->getParentEdge()->getNBEdge();
801 // get connections vinculated with from Lane
802 const std::vector<NBEdge::Connection> connections = fromNBEdge->getConnectionsFromLane(fromLane->getIndex());
803 // find connection
804 std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
805 connections.begin(), connections.end(),
806 NBEdge::connections_finder(fromLane->getIndex(), toNBEdge, toLane->getIndex()));
807 // check if connection was found
808 return (con_it != connections.end());
809}
810
811
812void
813GNEPathManager::buildPath(GNEPathElement* pathElement, SUMOVehicleClass vClass, const std::vector<GNEEdge*> path,
814 GNELane* fromLane, GNEJunction* fromJunction, GNELane* toLane, GNEJunction* toJunction) {
815 // first remove path element from paths
816 removePath(pathElement);
817 // declare segment vector
818 std::vector<GNESegment*> segments;
819 // continue if path isn't empty
820 if (path.size() > 0) {
821 // declare last index
822 const int lastIndex = ((int)path.size() - 1);
823 // reserve segments
824 segments.reserve(2 * path.size());
825 if (fromJunction) {
826 // create lane segment using fromJunction
827 new GNESegment(this, pathElement, fromJunction, segments);
828 }
829 // iterate over path
830 for (int i = 0; i < (int)path.size(); i++) {
831 if ((i == 0) && fromLane) {
832 // create lane segment using fromLane
833 new GNESegment(this, pathElement, fromLane, segments);
834 // continue if this isn't the last path edge
835 if (i != lastIndex) {
836 // create junction segment using to junction
837 new GNESegment(this, pathElement, path.at(i)->getToJunction(), segments);
838 }
839 } else if ((i == lastIndex) && toLane) {
840 // create lane segment using toLane
841 new GNESegment(this, pathElement, toLane, segments);
842 } else {
843 // get first allowed lane
844 const GNELane* lane = path.at(i)->getLaneByAllowedVClass(vClass);
845 // create lane segment
846 new GNESegment(this, pathElement, lane, segments);
847 // continue if this isn't the last path edge
848 if (i != lastIndex) {
849 // create junction segment using to junction
850 new GNESegment(this, pathElement, path.at(i)->getToJunction(), segments);
851 }
852 }
853 }
854 if (toJunction) {
855 // create lane segment using toJunction
856 new GNESegment(this, pathElement, toJunction, segments);
857 }
858 // mark label segment
859 markLabelSegment(segments);
860 // add segments in paths
861 myPaths[pathElement] = segments;
862 } else {
863 // create first segment
864 GNESegment* firstSegment = nullptr;
865 GNESegment* lastSegment = nullptr;
866 // continue depending of from-to elements
867 if (fromLane) {
868 firstSegment = new GNESegment(this, pathElement, fromLane, segments);
869 } else if (fromJunction) {
870 firstSegment = new GNESegment(this, pathElement, fromJunction, segments);
871 }
872 if (toLane) {
873 lastSegment = new GNESegment(this, pathElement, toLane, segments);
874 } else if (toJunction) {
875 lastSegment = new GNESegment(this, pathElement, toJunction, segments);
876 }
877 // continue depending of segments
878 if (firstSegment && lastSegment) {
879 // mark segment as label segment
880 firstSegment->markSegmentLabel();
881 // add segments in path
882 myPaths[pathElement] = segments;
883 } else {
884 delete firstSegment;
885 delete lastSegment;
886 }
887 }
888}
889
890
891void
892GNEPathManager::markLabelSegment(const std::vector<GNESegment*>& segments) const {
893 // separate junction segments and lane segments
894 std::vector<GNESegment*> laneSegments;
895 laneSegments.reserve(segments.size());
896 for (const auto& segment : segments) {
897 if (segment->getLane()) {
898 laneSegments.push_back(segment);
899 }
900 }
901 // get lane segment index
902 const int laneSegmentIndex = (int)((double)laneSegments.size() * 0.5);
903 // mark middle label as label segment
904 laneSegments.at(laneSegmentIndex)->markSegmentLabel();
905}
906
907/****************************************************************************/
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:781
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:1118
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1124
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:620
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1675
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:1563
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:127
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2163
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
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: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:1287
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)