Line data Source code
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 : /****************************************************************************/
14 : /// @file CarEdge.h
15 : /// @author Michael Behrisch
16 : /// @date Mon, 03 March 2014
17 : ///
18 : // The CarEdge is a special intermodal edge representing the SUMO network edge
19 : /****************************************************************************/
20 : #pragma once
21 : #include <config.h>
22 :
23 : #ifdef HAVE_FOX
24 : #include <utils/foxtools/fxheader.h>
25 : #endif
26 : #include "IntermodalEdge.h"
27 :
28 :
29 : // ===========================================================================
30 : // class definitions
31 : // ===========================================================================
32 : /// @brief the car edge type that is given to the internal router (SUMOAbstractRouter)
33 : template<class E, class L, class N, class V>
34 : class CarEdge : public IntermodalEdge<E, L, N, V> {
35 : private:
36 : typedef IntermodalEdge<E, L, N, V> _IntermodalEdge;
37 :
38 : public:
39 285862 : CarEdge(int numericalID, const E* edge, const double pos = -1.) :
40 : _IntermodalEdge(edge->getID() + "_car" + toString(pos), numericalID, edge, "!car"),
41 595379 : myStartPos(pos >= 0 ? pos : 0.) { }
42 :
43 33156 : bool includeInRoute(bool /* allEdges */) const {
44 33156 : return true;
45 : }
46 :
47 236 : const std::vector<_IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const {
48 236 : if (vClass == SVC_IGNORING) {
49 236 : return this->myFollowingEdges;
50 : }
51 : #ifdef HAVE_FOX
52 0 : FXMutexLock locker(myLock);
53 : #endif
54 : typename std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> >::const_iterator i = myClassesSuccessorMap.find(vClass);
55 0 : if (i != myClassesSuccessorMap.end()) {
56 : // can use cached value
57 0 : return i->second;
58 : } else {
59 : // this vClass is requested for the first time. rebuild all successors
60 0 : const std::set<const E*> classedCarFollowers = std::set<const E*>(this->getEdge()->getSuccessors(vClass).begin(), this->getEdge()->getSuccessors(vClass).end());
61 0 : for (_IntermodalEdge* const e : this->myFollowingEdges) {
62 0 : if (!e->includeInRoute(false) || e->getEdge() == this->getEdge() || classedCarFollowers.count(e->getEdge()) > 0) {
63 0 : myClassesSuccessorMap[vClass].push_back(e);
64 : }
65 : }
66 0 : return myClassesSuccessorMap[vClass];
67 : }
68 : }
69 :
70 62130 : virtual const std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
71 62130 : if (vClass == SVC_IGNORING) {
72 42255 : return this->myFollowingViaEdges;
73 : }
74 : #ifdef HAVE_FOX
75 19875 : FXMutexLock locker(myLock);
76 : #endif
77 19875 : auto& viaMap = ignoreTransientPermissions ? myOrigClassesViaSuccessorMap : myClassesViaSuccessorMap;
78 : typename std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > >::const_iterator i = viaMap.find(vClass);
79 19875 : if (i != viaMap.end()) {
80 : // can use cached value
81 9001 : return i->second;
82 : } else {
83 : // this vClass is requested for the first time. rebuild all successors
84 : std::set<const E*> classedCarFollowers;
85 38678 : for (const auto& pair : this->getEdge()->getViaSuccessors(vClass)) {
86 27804 : classedCarFollowers.insert(pair.first);
87 : }
88 68227 : for (const std::pair<const _IntermodalEdge*, const _IntermodalEdge*>& e : this->myFollowingViaEdges) {
89 57353 : if (!e.first->includeInRoute(false) || e.first->getEdge() == this->getEdge() || classedCarFollowers.count(e.first->getEdge()) > 0) {
90 57019 : viaMap[vClass].push_back(e);
91 : }
92 : }
93 10874 : return viaMap[vClass];
94 : }
95 : }
96 :
97 57356 : bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
98 59282 : return trip->vehicle == 0 || this->getEdge()->prohibits(trip->vehicle);
99 : }
100 :
101 68067 : double getPartialLength(const IntermodalTrip<E, N, V>* const trip) const {
102 : double length = this->getLength();
103 : // checking arrivalPos first to have it correct for identical depart and arrival edge
104 68067 : if (this->getEdge() == trip->to && trip->arrivalPos >= myStartPos && trip->arrivalPos < myStartPos + this->getLength()) {
105 5472 : length = trip->arrivalPos - myStartPos;
106 : }
107 68067 : if (this->getEdge() == trip->from && trip->departPos >= myStartPos && trip->departPos < myStartPos + this->getLength()) {
108 6149 : length -= trip->departPos - myStartPos;
109 : }
110 68067 : return length;
111 : }
112 :
113 58002 : double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const {
114 : assert(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time) >= 0.);
115 58002 : return getPartialTravelTime(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time), trip);
116 : }
117 :
118 4240 : double getTravelTimeAggregated(const IntermodalTrip<E, N, V>* const trip, double time) const {
119 : assert(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time) >= 0.);
120 4240 : return getPartialTravelTime(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time), trip);
121 : }
122 :
123 2048 : double getStartPos() const {
124 2048 : return myStartPos;
125 : }
126 :
127 5195 : double getEndPos() const {
128 5195 : return myStartPos + this->getLength();
129 : }
130 :
131 : private:
132 :
133 : inline double getPartialTravelTime(double fullTravelTime, const IntermodalTrip<E, N, V>* const trip) const {
134 62242 : const double distTravelled = getPartialLength(trip);
135 : assert(fullTravelTime * distTravelled / this->getEdge()->getLength() >= 0.);
136 62242 : return fullTravelTime * distTravelled / this->getEdge()->getLength();
137 : }
138 :
139 : private:
140 : /// @brief the starting position for split edges
141 : const double myStartPos;
142 :
143 : /// @brief The successors available for a given vClass
144 : mutable std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> > myClassesSuccessorMap;
145 :
146 : /// @brief The successors available for a given vClass
147 : mutable std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > > myClassesViaSuccessorMap;
148 : mutable std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > > myOrigClassesViaSuccessorMap;
149 :
150 : #ifdef HAVE_FOX
151 : /// The mutex used to avoid concurrent updates of myClassesSuccessorMap
152 : mutable FXMutex myLock;
153 : #endif
154 : };
|