Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/jtrrouter/ROJTRTurnDefLoader.cpp
169665 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 ROJTRTurnDefLoader.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Tue, 20 Jan 2004
19
///
20
// Loader for the of turning percentages and source/sink definitions
21
/****************************************************************************/
22
#include <config.h>
23
24
#include <set>
25
#include <string>
26
#include <utils/common/FileHelpers.h>
27
#include <utils/xml/XMLSubSys.h>
28
#include <utils/common/UtilExceptions.h>
29
#include <utils/common/MsgHandler.h>
30
#include <utils/common/StringUtils.h>
31
#include <utils/common/ToString.h>
32
#include <utils/options/OptionsCont.h>
33
#include <utils/xml/SUMOXMLDefinitions.h>
34
#include <utils/vehicle/SUMOVehicleParserHelper.h>
35
#include <router/RONet.h>
36
#include "ROJTREdge.h"
37
#include "ROJTRTurnDefLoader.h"
38
39
40
// ===========================================================================
41
// method definitions
42
// ===========================================================================
43
ROJTRTurnDefLoader::ROJTRTurnDefLoader(RONet& net) :
44
SUMOSAXHandler("turn-ratio-file"), myNet(net),
45
myIntervalBegin(0), myIntervalEnd(STEPS2TIME(SUMOTime_MAX)),
46
myEdge(nullptr),
47
mySourcesAreSinks(OptionsCont::getOptions().getBool("sources-are-sinks")),
48
myDiscountSources(OptionsCont::getOptions().getBool("discount-sources")),
49
myHaveWarnedAboutDeprecatedFormat(false)
50
{}
51
52
53
ROJTRTurnDefLoader::~ROJTRTurnDefLoader() {}
54
55
56
void
57
ROJTRTurnDefLoader::myStartElement(int element,
58
const SUMOSAXAttributes& attrs) {
59
bool ok = true;
60
switch (element) {
61
case SUMO_TAG_INTERVAL:
62
myIntervalBegin = attrs.get<double>(SUMO_ATTR_BEGIN, nullptr, ok);
63
myIntervalEnd = attrs.get<double>(SUMO_ATTR_END, nullptr, ok);
64
break;
65
case SUMO_TAG_FROMEDGE:
66
if (!myHaveWarnedAboutDeprecatedFormat) {
67
myHaveWarnedAboutDeprecatedFormat = true;
68
WRITE_WARNINGF(TL("The turn-file format with elements %, % is deprecated, please use % instead."),
69
toString(SUMO_TAG_FROMEDGE), toString(SUMO_TAG_TOEDGE), toString(SUMO_TAG_EDGEREL));
70
}
71
beginFromEdge(attrs);
72
break;
73
case SUMO_TAG_TOEDGE:
74
addToEdge(attrs);
75
break;
76
case SUMO_TAG_EDGEREL:
77
addEdgeRel(attrs);
78
break;
79
case SUMO_TAG_SINK:
80
if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
81
std::string edges = attrs.get<std::string>(SUMO_ATTR_EDGES, nullptr, ok);
82
StringTokenizer st(edges, StringTokenizer::WHITECHARS);
83
while (st.hasNext()) {
84
std::string id = st.next();
85
ROEdge* edge = myNet.getEdge(id);
86
if (edge == nullptr) {
87
throw ProcessError(TLF("The edge '%' declared as a sink is not known.", id));
88
}
89
edge->setSink();
90
}
91
}
92
break;
93
case SUMO_TAG_FLOW: {
94
const std::string flowID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
95
if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
96
const std::string edgeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
97
ROEdge* edge = myNet.getEdge(edgeID);
98
if (edge == nullptr) {
99
throw ProcessError(TLF("The from-edge '%' in flow '%' is not known.", edgeID, flowID));
100
}
101
if (mySourcesAreSinks) {
102
edge->setSink();
103
}
104
if (myDiscountSources) {
105
SUMOVehicleParameter* pars = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, true, true, 0, TIME2STEPS(3600 * 24));
106
int numVehs = 0;
107
if (pars->repetitionProbability > 0) {
108
numVehs = int(STEPS2TIME(pars->repetitionEnd - pars->depart) * pars->repetitionProbability);
109
} else {
110
numVehs = pars->repetitionNumber;
111
}
112
delete pars;
113
static_cast<ROJTREdge*>(edge)->changeSourceFlow(numVehs);
114
}
115
} else {
116
WRITE_WARNINGF(TL("Ignoring flow '%' without 'from'"), flowID);
117
}
118
break;
119
}
120
case SUMO_TAG_SOURCE:
121
if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
122
std::string edges = attrs.get<std::string>(SUMO_ATTR_EDGES, nullptr, ok);
123
StringTokenizer st(edges, StringTokenizer::WHITECHARS);
124
while (st.hasNext()) {
125
std::string id = st.next();
126
ROEdge* edge = myNet.getEdge(id);
127
if (edge == nullptr) {
128
throw ProcessError(TLF("The edge '%' declared as a source is not known.", id));
129
}
130
edge->setSource();
131
}
132
}
133
break;
134
default:
135
break;
136
}
137
}
138
139
140
void
141
ROJTRTurnDefLoader::beginFromEdge(const SUMOSAXAttributes& attrs) {
142
myEdge = nullptr;
143
bool ok = true;
144
// get the id, report an error if not given or empty...
145
std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
146
if (!ok) {
147
return;
148
}
149
//
150
myEdge = static_cast<ROJTREdge*>(myNet.getEdge(id));
151
if (myEdge == nullptr) {
152
WRITE_ERRORF(TL("The edge '%' is not known within the network (within a 'from-edge' tag)."), id);
153
return;
154
}
155
}
156
157
158
void
159
ROJTRTurnDefLoader::addToEdge(const SUMOSAXAttributes& attrs) {
160
if (myEdge == nullptr) {
161
return;
162
}
163
bool ok = true;
164
// get the id, report an error if not given or empty...
165
std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
166
if (!ok) {
167
return;
168
}
169
//
170
ROJTREdge* edge = static_cast<ROJTREdge*>(myNet.getEdge(id));
171
if (edge == nullptr) {
172
WRITE_ERRORF(TL("The edge '%' is not known within the network (within a 'to-edge' tag)."), id);
173
return;
174
}
175
const double probability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
176
if (ok) {
177
if (probability < 0) {
178
WRITE_ERRORF(TL("'probability' must be positive (in definition of to-edge '%')."), id);
179
} else {
180
myEdge->addFollowerProbability(edge, myIntervalBegin, myIntervalEnd, probability);
181
}
182
}
183
}
184
185
186
void
187
ROJTRTurnDefLoader::addEdgeRel(const SUMOSAXAttributes& attrs) {
188
bool ok = true;
189
// get the id, report an error if not given or empty...
190
std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
191
std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
192
double probability = attrs.get<double>(
193
attrs.hasAttribute(SUMO_ATTR_COUNT) && !attrs.hasAttribute(SUMO_ATTR_PROB) ? SUMO_ATTR_COUNT : SUMO_ATTR_PROB,
194
(fromID + "->" + toID).c_str(), ok);
195
if (!ok) {
196
return;
197
}
198
//
199
ROJTREdge* from = static_cast<ROJTREdge*>(myNet.getEdge(fromID));
200
if (from == nullptr) {
201
WRITE_ERRORF(TL("The edge '%' is not known."), fromID);
202
return;
203
}
204
ROJTREdge* to = static_cast<ROJTREdge*>(myNet.getEdge(toID));
205
if (to == nullptr) {
206
WRITE_ERRORF(TL("The edge '%' is not known."), toID);
207
return;
208
}
209
if (probability < 0) {
210
WRITE_ERRORF(TL("'probability' must be positive (in edgeRelation from '%' to '%'."), fromID, toID);
211
} else {
212
from->addFollowerProbability(to, myIntervalBegin, myIntervalEnd, probability);
213
}
214
}
215
216
217
/****************************************************************************/
218
219