Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/router/PublicTransportEdge.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 PublicTransportEdge.h
15
/// @author Michael Behrisch
16
/// @date Mon, 03 March 2014
17
///
18
// The PublicTransportEdge is a special intermodal edge connecting the stop edges with scheduled traffic
19
/****************************************************************************/
20
#pragma once
21
#include <config.h>
22
23
#include "IntermodalEdge.h"
24
25
26
// ===========================================================================
27
// class definitions
28
// ===========================================================================
29
/// @brief the public transport edge type connecting the stop edges
30
template<class E, class L, class N, class V>
31
class PublicTransportEdge : public IntermodalEdge<E, L, N, V> {
32
private:
33
struct Schedule {
34
Schedule(const std::string& _id, const SUMOTime _begin, const int _repetitionNumber, const SUMOTime _period, const SUMOTime _travelTime)
35
: ids({
36
_id
37
}), begin(_begin), repetitionNumber(_repetitionNumber), period(_period), travelTime(_travelTime) {}
38
// the id of the vehicle or flow from which this schedule is generated
39
std::vector<std::string> ids;
40
const SUMOTime begin;
41
int repetitionNumber;
42
// the repetition period for a flow or -1 for a vehicle
43
SUMOTime period;
44
const SUMOTime travelTime;
45
};
46
47
public:
48
PublicTransportEdge(const std::string id, int numericalID, const IntermodalEdge<E, L, N, V>* entryStop, const E* endEdge, const std::string& line, const double length) :
49
IntermodalEdge<E, L, N, V>(line + ":" + (id != "" ? id : endEdge->getID()), numericalID, endEdge, line, length), myEntryStop(entryStop) { }
50
51
bool includeInRoute(bool /* allEdges */) const {
52
return true;
53
}
54
55
bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
56
return (trip->modeSet & SVC_BUS) == 0;
57
}
58
59
const IntermodalEdge<E, L, N, V>* getEntryStop() const {
60
return myEntryStop;
61
}
62
63
bool hasSchedule(const SUMOTime begin) const {
64
return mySchedules.find(begin) != mySchedules.end();
65
}
66
67
void addSchedule(const std::string id, const SUMOTime begin, const int repetitionNumber, const SUMOTime period, const SUMOTime travelTime) {
68
// try to merge with existing vehicle or flow
69
bool found = false;
70
for (auto& it : mySchedules) {
71
Schedule& s = it.second;
72
if (travelTime == s.travelTime) {
73
if (repetitionNumber == -1 && s.repetitionNumber == 1) {
74
if (begin > s.begin) {
75
s.period = begin - s.begin;
76
found = true;
77
}
78
} else if (begin == s.begin + s.repetitionNumber * s.period) {
79
found = true;
80
}
81
if (found) {
82
s.repetitionNumber += MAX2(repetitionNumber, 1);
83
s.ids.push_back(id);
84
break;
85
}
86
}
87
}
88
if (!found) {
89
mySchedules.insert(std::make_pair(begin, Schedule(id, begin, MAX2(repetitionNumber, 1), MAX2<SUMOTime>(period, 1), travelTime)));
90
}
91
}
92
93
double getTravelTime(const IntermodalTrip<E, N, V>* const /* trip */, double time) const {
94
SUMOTime minArrival = SUMOTime_MAX;
95
const SUMOTime step = TIME2STEPS(time);
96
for (typename std::multimap<SUMOTime, Schedule>::const_iterator it = mySchedules.begin(); it != mySchedules.end(); ++it) {
97
const Schedule& s = it->second;
98
if (it->first > minArrival) {
99
break;
100
}
101
const SUMOTime offset = MAX2<SUMOTime>(0, step - s.begin);
102
int running = (int)(offset / s.period);
103
if (offset % s.period != 0) {
104
running++;
105
}
106
if (running < s.repetitionNumber) {
107
const SUMOTime nextDepart = s.begin + running * s.period;
108
minArrival = MIN2(nextDepart + s.travelTime, minArrival);
109
//std::cout << " edge=" << myEntryStop->getID() << "->" << this->getID() << " beg=" << s.begin << " end=" << s.end
110
// << " atTime=" << time
111
// << " running=" << running << " nextDepart=" << nextDepart
112
// << " minASec=" << minArrivalSec << " travelTime=" << minArrivalSec - time << "\n";
113
}
114
}
115
if (minArrival != SUMOTime_MAX) {
116
return STEPS2TIME(minArrival - step);
117
} else {
118
// indicate failure
119
return std::numeric_limits<double>::max();
120
}
121
}
122
123
double getIntended(const double time, std::string& intended) const {
124
/// @note: duplicates some code of getTravelTime()
125
SUMOTime minArrival = SUMOTime_MAX;
126
double bestDepartTime = std::numeric_limits<double>::max();
127
const SUMOTime step = TIME2STEPS(time);
128
for (typename std::multimap<SUMOTime, Schedule>::const_iterator it = mySchedules.begin(); it != mySchedules.end(); ++it) {
129
const Schedule& s = it->second;
130
if (it->first > minArrival) {
131
break;
132
}
133
const SUMOTime offset = MAX2<SUMOTime>(0, step - s.begin);
134
int running = (int)(offset / s.period);
135
if (offset % s.period != 0) {
136
running++;
137
}
138
if (running < s.repetitionNumber) {
139
const SUMOTime nextDepart = s.begin + running * s.period;
140
if (nextDepart + s.travelTime < minArrival) {
141
minArrival = nextDepart + s.travelTime;
142
bestDepartTime = STEPS2TIME(nextDepart);
143
// see naming scheme inMSInsertionControl::determineCandidates()
144
if (s.ids.size() == 1 || running >= (int)s.ids.size()) {
145
intended = s.repetitionNumber == 1 ? s.ids[0] : s.ids[0] + "." + toString(running);
146
} else {
147
intended = s.ids[running];
148
}
149
}
150
}
151
}
152
return bestDepartTime;
153
}
154
155
private:
156
std::multimap<SUMOTime, Schedule> mySchedules;
157
const IntermodalEdge<E, L, N, V>* const myEntryStop;
158
159
};
160
161