Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/router/CarEdge.h
169678 views
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 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
CarEdge(int numericalID, const E* edge, const double pos = -1.) :
40
_IntermodalEdge(edge->getID() + "_car" + toString(pos), numericalID, edge, "!car"),
41
myStartPos(pos >= 0 ? pos : 0.) { }
42
43
bool includeInRoute(bool /* allEdges */) const {
44
return true;
45
}
46
47
const std::vector<_IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const {
48
if (vClass == SVC_IGNORING) {
49
return this->myFollowingEdges;
50
}
51
#ifdef HAVE_FOX
52
FXMutexLock locker(myLock);
53
#endif
54
typename std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> >::const_iterator i = myClassesSuccessorMap.find(vClass);
55
if (i != myClassesSuccessorMap.end()) {
56
// can use cached value
57
return i->second;
58
} else {
59
// this vClass is requested for the first time. rebuild all successors
60
const std::set<const E*> classedCarFollowers = std::set<const E*>(this->getEdge()->getSuccessors(vClass).begin(), this->getEdge()->getSuccessors(vClass).end());
61
for (_IntermodalEdge* const e : this->myFollowingEdges) {
62
if (!e->includeInRoute(false) || e->getEdge() == this->getEdge() || classedCarFollowers.count(e->getEdge()) > 0) {
63
myClassesSuccessorMap[vClass].push_back(e);
64
}
65
}
66
return myClassesSuccessorMap[vClass];
67
}
68
}
69
70
virtual const std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
71
if (vClass == SVC_IGNORING) {
72
return this->myFollowingViaEdges;
73
}
74
#ifdef HAVE_FOX
75
FXMutexLock locker(myLock);
76
#endif
77
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
if (i != viaMap.end()) {
80
// can use cached value
81
return i->second;
82
} else {
83
// this vClass is requested for the first time. rebuild all successors
84
std::set<const E*> classedCarFollowers;
85
for (const auto& pair : this->getEdge()->getViaSuccessors(vClass)) {
86
classedCarFollowers.insert(pair.first);
87
}
88
for (const std::pair<const _IntermodalEdge*, const _IntermodalEdge*>& e : this->myFollowingViaEdges) {
89
if (!e.first->includeInRoute(false) || e.first->getEdge() == this->getEdge() || classedCarFollowers.count(e.first->getEdge()) > 0) {
90
viaMap[vClass].push_back(e);
91
}
92
}
93
return viaMap[vClass];
94
}
95
}
96
97
bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
98
return trip->vehicle == 0 || this->getEdge()->prohibits(trip->vehicle);
99
}
100
101
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
if (this->getEdge() == trip->to && trip->arrivalPos >= myStartPos && trip->arrivalPos < myStartPos + this->getLength()) {
105
length = trip->arrivalPos - myStartPos;
106
}
107
if (this->getEdge() == trip->from && trip->departPos >= myStartPos && trip->departPos < myStartPos + this->getLength()) {
108
length -= trip->departPos - myStartPos;
109
}
110
return length;
111
}
112
113
double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const {
114
assert(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time) >= 0.);
115
return getPartialTravelTime(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time), trip);
116
}
117
118
double getTravelTimeAggregated(const IntermodalTrip<E, N, V>* const trip, double time) const {
119
assert(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time) >= 0.);
120
return getPartialTravelTime(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time), trip);
121
}
122
123
double getStartPos() const {
124
return myStartPos;
125
}
126
127
double getEndPos() const {
128
return myStartPos + this->getLength();
129
}
130
131
private:
132
133
inline double getPartialTravelTime(double fullTravelTime, const IntermodalTrip<E, N, V>* const trip) const {
134
const double distTravelled = getPartialLength(trip);
135
assert(fullTravelTime * distTravelled / this->getEdge()->getLength() >= 0.);
136
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
};
155
156