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 FlippedEdge.h
15 : /// @author Ruediger Ebendt
16 : /// @date 01.12.2023
17 : ///
18 : // Extension of ReversedEdge, which is a wrapper around a ROEdge
19 : // or an MSEdge used for backward search. In contrast to reversed
20 : // edges, flipped edges have flipped nodes instead of standard nodes.
21 : // Introduced for the arc flag router.
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 : #include <utils/common/SUMOVehicleClass.h>
26 : #ifdef HAVE_FOX
27 : #include <utils/foxtools/MsgHandlerSynchronized.h>
28 : #endif
29 : #include "ReversedEdge.h"
30 :
31 :
32 : // ===========================================================================
33 : // class declarations
34 : // ===========================================================================
35 : template<class E, class N, class V>
36 : class FlippedNode;
37 :
38 : // ===========================================================================
39 : // class definitions
40 : // ===========================================================================
41 : /// @brief The edge type representing backward edges with flipped nodes
42 : template<class E, class N, class V>
43 : class FlippedEdge : public ReversedEdge<E, V> {
44 : public:
45 :
46 : typedef std::vector<std::pair<const FlippedEdge<E, N, V>*, const FlippedEdge<E, N, V>*> > ConstFlippedEdgePairVector;
47 :
48 : /** @brief Constructor
49 : * @param[in] originalEdge The original (forward) edge
50 : */
51 : FlippedEdge(const E* originalEdge) :
52 : ReversedEdge<E, V>(originalEdge),
53 : myFromJunction(this->getOriginalEdge()->getToJunction()->getFlippedRoutingNode()),
54 : myToJunction(this->getOriginalEdge()->getFromJunction()->getFlippedRoutingNode())
55 : {}
56 :
57 : /// @brief Destructor
58 0 : ~FlippedEdge() {}
59 :
60 : /// @brief Initialize the flipped edge
61 : void init();
62 : /// @brief Returns the from-junction
63 : const FlippedNode<E, N, V>* getFromJunction() const {
64 : return myFromJunction;
65 : }
66 : /// @brief Returns the to-junction
67 : const FlippedNode<E, N, V>* getToJunction() const {
68 : return myToJunction;
69 : }
70 : /** @brief Returns the time for travelling on the given edge with the given vehicle at the given time
71 : * @param[in] edge The edge
72 : * @param[in] veh The vehicle
73 : * @param[in] time The time
74 : * @return The time for travelling on the given edge with the given vehicle at the given time
75 : */
76 : static double getTravelTimeStatic(const FlippedEdge<E, N, V>* const edge, const V* const veh, double time) {
77 : return edge->getOriginalEdge()->getTravelTime(veh, time);
78 : }
79 : /** @brief Returns the randomized time for travelling on the given edge with the given vehicle at the given time
80 : * @param[in] edge The edge
81 : * @param[in] veh The vehicle
82 : * @param[in] time The time
83 : * @return The randomized time for travelling on the given edge with the given vehicle at the given time
84 : */
85 : static double getTravelTimeStaticRandomized(const FlippedEdge<E, N, V>* const edge, const V* const veh, double time) {
86 : return edge->getOriginalEdge()->getTravelTimeStaticRandomized(edge->getOriginalEdge(), veh, time);
87 : }
88 :
89 : /** @brief Returns the via successors
90 : * @param[in] vClass The vehicle class
91 : * @param[in] ignoreTransientPermissions Unused parameter
92 : * @return The via successors
93 : */
94 : const ConstFlippedEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
95 : UNUSED_PARAMETER(ignoreTransientPermissions); // @todo this should be changed (somewhat hidden by #14756)
96 : if (vClass == SVC_IGNORING || this->getOriginalEdge()->isTazConnector()) { // || !MSNet::getInstance()->hasPermissions()) {
97 : return myViaSuccessors;
98 : }
99 : #ifdef HAVE_FOX
100 : FXMutexLock lock(mySuccessorMutex);
101 : #endif
102 : auto i = myClassesViaSuccessorMap.find(vClass);
103 : if (i != myClassesViaSuccessorMap.end()) {
104 : // can use cached value
105 : return i->second;
106 : }
107 : // instantiate vector
108 : ConstFlippedEdgePairVector& result = myClassesViaSuccessorMap[vClass];
109 : // this vClass is requested for the first time. rebuild all successors
110 : for (const auto& viaPair : myViaSuccessors) {
111 : if (viaPair.first->getOriginalEdge()->isTazConnector()
112 : || viaPair.first->getOriginalEdge()->isConnectedTo(*(this->getOriginalEdge()), vClass)) {
113 : result.push_back(viaPair);
114 : }
115 : }
116 : return result;
117 : }
118 :
119 : /** @brief Returns the bidirectional edge
120 : * @return The bidirectional edge
121 : */
122 : const FlippedEdge<E, N, V>* getBidiEdge() const {
123 : return this->getOriginalEdge()->getBidiEdge()->getFlippedRoutingEdge();
124 : }
125 : /** @brief Returns the distance to another flipped edge
126 : * param[in] other The other flipped edge
127 : * param[in] doBoundaryEstimate The boolean flag indicating whether the distance is estimated using both boundaries or not
128 : * @return The distance to another flipped edge
129 : */
130 : double getDistanceTo(const FlippedEdge<E, N, V>* other, const bool doBoundaryEstimate = false) const {
131 : return this->getOriginalEdge()->getDistanceTo(other->getOriginalEdge(), doBoundaryEstimate);
132 : }
133 : /** @brief Returns the minimum travel time
134 : * @param[in] veh The vehicle
135 : * @return The minimum travel time
136 : */
137 : double getMinimumTravelTime(const V* const veh) const {
138 : return this->getOriginalEdge()->getMinimumTravelTime(veh);
139 : }
140 : /** @brief Returns the time penalty
141 : * @return The time penalty
142 : */
143 : double getTimePenalty() const {
144 : return this->getOriginalEdge()->getTimePenalty();
145 : }
146 : /** @brief Returns a boolean flag indicating whether this edge has loaded travel times or not
147 : * @return true iff this edge has loaded travel times
148 : */
149 : bool hasLoadedTravelTimes() const {
150 : return this->getOriginalEdge()->hasLoadedTravelTimes();
151 : }
152 : /** @brief Returns the speed allowed on this edge
153 : * @return The speed allowed on this edge
154 : */
155 : double getSpeedLimit() const {
156 : return this->getOriginalEdge()->getSpeedLimit();
157 : }
158 : /** @brief Returns a lower bound on shape.length() / myLength
159 : * @note The bound is sufficient for the astar air-distance heuristic
160 : * @return A lower bound on shape.length() / myLength
161 : */
162 : double getLengthGeometryFactor() const {
163 : return this->getOriginalEdge()->getLengthGeometryFactor();
164 : }
165 : /** @brief Returns the edge priority (road class)
166 : * @return The edge priority (road class)
167 : */
168 : int getPriority() const {
169 : return this->getOriginalEdge()->getPriority();
170 : }
171 :
172 : protected:
173 : /// @brief The junctions for this edge
174 : FlippedNode<E, N, V>* myFromJunction;
175 : FlippedNode<E, N, V>* myToJunction;
176 :
177 : private:
178 : /// @brief The successors available for a given vClass
179 : mutable std::map<SUMOVehicleClass, ConstFlippedEdgePairVector> myClassesViaSuccessorMap;
180 : mutable ConstFlippedEdgePairVector myViaSuccessors;
181 :
182 : #ifdef HAVE_FOX
183 : /// @brief Mutex for accessing successor edges
184 : mutable FXMutex mySuccessorMutex;
185 : #endif
186 : };
187 :
188 : // ===========================================================================
189 : // method definitions
190 : // ===========================================================================
191 :
192 : template<class E, class N, class V>
193 : void FlippedEdge<E, N, V>::init() {
194 : if (!this->getOriginalEdge()->isInternal()) {
195 : for (const auto& viaPair : this->getOriginalEdge()->getViaSuccessors()) {
196 : const FlippedEdge<E, N, V>* revSource = viaPair.first->getFlippedRoutingEdge();
197 : const E* via = viaPair.second;
198 : const FlippedEdge<E, N, V>* preVia = nullptr;
199 : while (via != nullptr && via->isInternal()) {
200 : via->getFlippedRoutingEdge()->myViaSuccessors.push_back(std::make_pair(this, preVia));
201 : preVia = via->getFlippedRoutingEdge();
202 : via = via->getViaSuccessors().front().second;
203 : }
204 : revSource->myViaSuccessors.push_back(std::make_pair(this, preVia));
205 : }
206 : }
207 : }
|