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 ReversedEdge.h
15 : /// @author Michael Behrisch
16 : /// @author Ruediger Ebendt
17 : /// @date 29.01.2020
18 : ///
19 : // The ReversedEdge is a wrapper around a ROEdge or a MSEdge used for
20 : // backward search
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #ifdef HAVE_FOX
26 : #include <utils/foxtools/fxheader.h>
27 : #include <FXThread.h>
28 : #endif
29 :
30 : // ===========================================================================
31 : // class definitions
32 : // ===========================================================================
33 : /// @brief the edge type representing backward edges
34 : template<class E, class V>
35 : class ReversedEdge {
36 : public:
37 : typedef std::vector<std::pair<const ReversedEdge<E, V>*, const ReversedEdge<E, V>*> > ConstEdgePairVector;
38 :
39 33544 : ReversedEdge(const E* orig) : myOriginal(orig) {
40 33544 : }
41 :
42 33544 : void init() {
43 33544 : if (!myOriginal->isInternal()) {
44 29440 : for (const auto& viaPair : myOriginal->getViaSuccessors()) {
45 22904 : const ReversedEdge<E, V>* revSource = viaPair.first->getReversedRoutingEdge();
46 22904 : const E* via = viaPair.second;
47 : const ReversedEdge<E, V>* preVia = nullptr;
48 49912 : while (via != nullptr && via->isInternal()) {
49 27008 : via->getReversedRoutingEdge()->myViaSuccessors.push_back(std::make_pair(this, preVia));
50 27008 : preVia = via->getReversedRoutingEdge();
51 27008 : via = via->getViaSuccessors().front().second;
52 : }
53 22904 : revSource->myViaSuccessors.push_back(std::make_pair(this, preVia));
54 : }
55 : }
56 33544 : }
57 :
58 : /// @brief Returns the original edge
59 : const E* getOriginalEdge() const {
60 0 : return myOriginal;
61 : }
62 :
63 : /** @brief Returns the index (numeric id) of the edge
64 : * @return The original edge's numerical id
65 : */
66 : int getNumericalID() const {
67 13654 : return myOriginal->getNumericalID();
68 : }
69 :
70 : /** @brief Returns the id of the edge
71 : * @return The original edge's id
72 : */
73 : const std::string& getID() const {
74 0 : return myOriginal->getID();
75 : }
76 :
77 : /** @brief Returns the length of the edge
78 : * @return The original edge's length
79 : */
80 : double getLength() const {
81 17066 : return myOriginal->getLength();
82 : }
83 :
84 : const ReversedEdge* getBidiEdge() const {
85 : return myOriginal->getBidiEdge()->getReversedRoutingEdge();
86 : }
87 :
88 : bool isInternal() const {
89 17066 : return myOriginal->isInternal();
90 : }
91 :
92 : inline bool prohibits(const V* const vehicle) const {
93 0 : return myOriginal->prohibits(vehicle);
94 : }
95 :
96 : inline bool restricts(const V* const vehicle) const {
97 0 : return myOriginal->restricts(vehicle);
98 : }
99 :
100 34292 : static inline double getTravelTimeStatic(const ReversedEdge<E, V>* const edge, const V* const veh, double time) {
101 34292 : return edge->myOriginal->getTravelTime(veh, time);
102 : }
103 :
104 1974 : const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
105 : UNUSED_PARAMETER(ignoreTransientPermissions); // @todo this should be changed (somewhat hidden by #14756)
106 1974 : if (vClass == SVC_IGNORING || myOriginal->isTazConnector()) { // || !MSNet::getInstance()->hasPermissions()) {
107 0 : return myViaSuccessors;
108 : }
109 : #ifdef HAVE_FOX
110 1974 : FXMutexLock lock(mySuccessorMutex);
111 : #endif
112 : auto i = myClassesViaSuccessorMap.find(vClass);
113 1974 : if (i != myClassesViaSuccessorMap.end()) {
114 : // can use cached value
115 984 : return i->second;
116 : }
117 : // instantiate vector
118 990 : ConstEdgePairVector& result = myClassesViaSuccessorMap[vClass];
119 : // this vClass is requested for the first time. rebuild all successors
120 4290 : for (const auto& viaPair : myViaSuccessors) {
121 3300 : if (viaPair.first->myOriginal->isTazConnector() || viaPair.first->myOriginal->isConnectedTo(*myOriginal, vClass)) {
122 3272 : result.push_back(viaPair);
123 : }
124 : }
125 : return result;
126 : }
127 :
128 : private:
129 : const E* const myOriginal;
130 : /// @brief The successors available for a given vClass
131 : mutable std::map<SUMOVehicleClass, ConstEdgePairVector> myClassesViaSuccessorMap;
132 :
133 : mutable ConstEdgePairVector myViaSuccessors;
134 :
135 : #ifdef HAVE_FOX
136 : /// @brief Mutex for accessing successor edges
137 : mutable FXMutex mySuccessorMutex;
138 : #endif
139 :
140 : };
|