Line data Source code
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 : /****************************************************************************/
14 : /// @file IntermodalEdge.h
15 : /// @author Jakob Erdmann
16 : /// @author Michael Behrisch
17 : /// @author Robert Hilbrich
18 : /// @date Mon, 03 March 2014
19 : ///
20 : // The Edge definition for the Intermodal Router
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <string>
26 : #include <vector>
27 : #include <utils/common/SUMOVehicleClass.h>
28 : #include <utils/common/ValueTimeLine.h>
29 : #include <utils/common/RandHelper.h>
30 : #include <utils/common/Named.h>
31 : #include "IntermodalTrip.h"
32 :
33 : // ===========================================================================
34 : // function definitions
35 : // ===========================================================================
36 : template <class E, class L>
37 8266605 : inline const L* getSidewalk(const E* edge, SUMOVehicleClass svc = SVC_PEDESTRIAN) {
38 8493776 : if (edge == nullptr) {
39 : return nullptr;
40 : }
41 : // prefer lanes that are exclusive to pedestrians
42 : const std::vector<L*>& lanes = edge->getLanes();
43 11458798 : for (const L* const lane : lanes) {
44 9597659 : if (lane->getPermissions() == svc) {
45 : return lane;
46 : }
47 : }
48 2542438 : for (const L* const lane : lanes) {
49 1985660 : if (lane->allowsVehicleClass(svc)) {
50 : return lane;
51 : }
52 : }
53 337482 : if (svc != SVC_PEDESTRIAN) {
54 : // persons should always be able to use the sidewalk
55 0 : for (const L* const lane : lanes) {
56 0 : if (lane->getPermissions() == SVC_PEDESTRIAN) {
57 : return lane;
58 : }
59 : }
60 0 : for (const L* const lane : lanes) {
61 0 : if (lane->allowsVehicleClass(SVC_PEDESTRIAN)) {
62 : return lane;
63 : }
64 : }
65 : }
66 : return nullptr;
67 : }
68 :
69 :
70 :
71 : // ===========================================================================
72 : // class definitions
73 : // ===========================================================================
74 : /// @brief the base edge type that is given to the internal router (SUMOAbstractRouter)
75 : template<class E, class L, class N, class V>
76 : class IntermodalEdge : public Named {
77 : public:
78 3591086 : IntermodalEdge(const std::string id, int numericalID, const E* edge, const std::string& line, const double length = -1) :
79 : Named(id),
80 3591086 : myNumericalID(numericalID),
81 3591086 : myEdge(edge),
82 3591086 : myLine(line),
83 3591086 : myLength(edge == nullptr || length >= 0. ? MAX2(0.0, length) : edge->getLength()),
84 7182172 : myEfforts(nullptr) { }
85 :
86 5074660 : virtual ~IntermodalEdge() {}
87 :
88 1384493 : virtual bool includeInRoute(bool /* allEdges */) const {
89 1384493 : return false;
90 : }
91 :
92 : inline const std::string& getLine() const {
93 1119220 : return myLine;
94 : }
95 :
96 : inline const E* getEdge() const {
97 46810592 : return myEdge;
98 : }
99 :
100 : int getNumericalID() const {
101 112583388 : return myNumericalID;
102 : }
103 :
104 : void addSuccessor(IntermodalEdge* const s, IntermodalEdge* const via = nullptr) {
105 5629747 : myFollowingEdges.push_back(s);
106 4171720 : myFollowingViaEdges.push_back(std::make_pair(s, via));
107 : }
108 :
109 75651 : void transferSuccessors(IntermodalEdge* to) {
110 75651 : to->myFollowingEdges = myFollowingEdges;
111 75651 : to->myFollowingViaEdges = myFollowingViaEdges;
112 : myFollowingEdges.clear();
113 : myFollowingViaEdges.clear();
114 75651 : }
115 :
116 97082 : bool removeSuccessor(const IntermodalEdge* const edge) {
117 97082 : auto it = std::find(myFollowingEdges.begin(), myFollowingEdges.end(), edge);
118 97082 : if (it != myFollowingEdges.end()) {
119 75030 : myFollowingEdges.erase(it);
120 : } else {
121 : return false;
122 : }
123 279675 : for (auto viaIt = myFollowingViaEdges.begin(); viaIt != myFollowingViaEdges.end();) {
124 204645 : if (viaIt->first == edge) {
125 : viaIt = myFollowingViaEdges.erase(viaIt);
126 : } else {
127 : ++viaIt;
128 : }
129 : }
130 : return true;
131 : }
132 :
133 1836 : virtual const std::vector<IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const {
134 : UNUSED_PARAMETER(vClass);
135 : // the network is already tailored. No need to check for permissions here
136 1836 : return myFollowingEdges;
137 : }
138 :
139 30349176 : virtual const std::vector<std::pair<const IntermodalEdge*, const IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
140 : UNUSED_PARAMETER(vClass);
141 : UNUSED_PARAMETER(ignoreTransientPermissions);
142 : // the network is already tailored. No need to check for permissions here
143 30349176 : return myFollowingViaEdges;
144 : }
145 :
146 16922137 : virtual bool prohibits(const IntermodalTrip<E, N, V>* const /* trip */) const {
147 16922137 : return false;
148 : }
149 :
150 0 : virtual bool restricts(const IntermodalTrip<E, N, V>* const /* trip */) const {
151 0 : return false;
152 : }
153 :
154 523640 : virtual inline double getPartialLength(const IntermodalTrip<E, N, V>* const /*trip*/) const {
155 523640 : return myLength;
156 : }
157 :
158 :
159 7538374 : virtual inline double getTravelTime(const IntermodalTrip<E, N, V>* const /* trip */, double /* time */) const {
160 7538374 : return 0.;
161 : }
162 :
163 19880 : virtual inline double getTravelTimeAggregated(const IntermodalTrip<E, N, V>* const trip, double time) const {
164 19880 : return getTravelTime(trip, time);
165 : }
166 :
167 : /// @brief get intended vehicle id and departure time of next public transport ride
168 0 : virtual inline double getIntended(const double /* time */, std::string& /* intended */) const {
169 0 : return 0.;
170 : }
171 :
172 34329931 : static inline double getTravelTimeStatic(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
173 34329931 : return edge == nullptr ? 0. : edge->getTravelTime(trip, time) * getRoutingFactor(edge, trip);
174 : }
175 :
176 89684 : static inline double getTravelTimeStaticRandomized(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
177 89684 : return edge == nullptr ? 0. : edge->getTravelTime(trip, time) * RandHelper::rand(1., gWeightsRandomFactor) * getRoutingFactor(edge, trip);
178 : }
179 :
180 24120 : static inline double getTravelTimeAggregated(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
181 24120 : return edge == nullptr ? 0. : edge->getTravelTimeAggregated(trip, time) * getRoutingFactor(edge, trip);
182 : }
183 :
184 34443735 : static inline double getRoutingFactor(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip) {
185 34446302 : return (!gRoutingPreferences || edge == nullptr || edge->myEdge == nullptr || trip == nullptr) ? 1 : 1 / edge->myEdge->getPreference(trip->getVTypeParameter());
186 : }
187 :
188 1032 : virtual double getEffort(const IntermodalTrip<E, N, V>* const /* trip */, double /* time */) const {
189 1032 : return 0.;
190 : }
191 :
192 0 : static inline double getEffortStatic(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
193 0 : return edge == nullptr || !edge->hasEffort() ? 0. : edge->getEffort(trip, time);
194 : }
195 :
196 : /// @brief required by DijkstraRouter et al for external effort computation
197 : inline double getLength() const {
198 31439960 : return myLength;
199 : }
200 :
201 : inline void setLength(const double length) {
202 : assert(length >= 0);
203 150060 : myLength = length;
204 50641 : }
205 :
206 : inline bool isInternal() const {
207 100684 : return myEdge != nullptr && myEdge->isInternal();
208 : }
209 :
210 0 : virtual bool hasEffort() const {
211 0 : return myEfforts != nullptr;
212 : }
213 :
214 4237 : virtual double getStartPos() const {
215 4237 : return 0.;
216 : }
217 :
218 7994 : virtual double getEndPos() const {
219 7994 : return myLength;
220 : }
221 :
222 : // only used by AStar
223 : inline double getSpeedLimit() const {
224 539316 : return myEdge != nullptr ? myEdge->getSpeedLimit() : 200. / 3.6;
225 : }
226 :
227 : // only used by AStar
228 : inline double getLengthGeometryFactor() const {
229 539316 : return myEdge != nullptr ? myEdge->getLengthGeometryFactor() : 1;
230 : }
231 :
232 : // only used by AStar
233 35906 : inline double getDistanceTo(const IntermodalEdge* other) const {
234 35906 : return myEdge != nullptr && other->myEdge != nullptr && myEdge != other->myEdge ? myEdge->getDistanceTo(other->myEdge, true) : 0.;
235 : }
236 :
237 : // only used by AStar
238 : inline double getMinimumTravelTime(const IntermodalTrip<E, N, V>* const trip) const {
239 0 : return myLength / trip->getMaxSpeed();
240 : }
241 :
242 : /// @brief only used by mono-modal routing
243 : IntermodalEdge* getBidiEdge() const {
244 : return nullptr;
245 : }
246 :
247 : protected:
248 : /// @brief List of edges that may be approached from this edge
249 : std::vector<IntermodalEdge*> myFollowingEdges;
250 :
251 : /// @brief List of edges that may be approached from this edge with optional internal vias
252 : std::vector<std::pair<const IntermodalEdge*, const IntermodalEdge*> > myFollowingViaEdges;
253 :
254 : private:
255 : /// @brief the index in myEdges
256 : const int myNumericalID;
257 :
258 : /// @brief the original edge
259 : const E* const myEdge;
260 :
261 : /// @brief public transport line or ped vs car
262 : const std::string myLine;
263 :
264 : /// @brief adaptable length (for splitted edges)
265 : double myLength;
266 :
267 : /// @brief Container for passing effort varying over time for the edge
268 : ValueTimeLine<double>* myEfforts;
269 :
270 : private:
271 : /// @brief Invalidated copy constructor
272 : IntermodalEdge(const IntermodalEdge& src);
273 :
274 : /// @brief Invalidated assignment operator
275 : IntermodalEdge& operator=(const IntermodalEdge& src);
276 :
277 : };
|