Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/router/ROLoader.cpp
193675 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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 ROLoader.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Sascha Krieg
18
/// @author Michael Behrisch
19
/// @author Christian Roessel
20
/// @date Sept 2002
21
///
22
// Loader for networks and route imports
23
/****************************************************************************/
24
#include <config.h>
25
26
#include <iostream>
27
#include <string>
28
#include <iomanip>
29
#include <utils/options/OptionsCont.h>
30
#include <utils/common/ToString.h>
31
#include <utils/common/StringTokenizer.h>
32
#include <utils/common/MsgHandler.h>
33
#include <utils/common/UtilExceptions.h>
34
#include <utils/common/FileHelpers.h>
35
#include <utils/xml/XMLSubSys.h>
36
#include <utils/xml/SAXWeightsHandler.h>
37
#include <utils/vehicle/SUMORouteLoader.h>
38
#include <utils/vehicle/SUMORouteLoaderControl.h>
39
#include "RONet.h"
40
#include "RONetHandler.h"
41
#include "ROLoader.h"
42
#include "ROLane.h"
43
#include "ROEdge.h"
44
#include "RORouteHandler.h"
45
46
47
// ===========================================================================
48
// method definitions
49
// ===========================================================================
50
// ---------------------------------------------------------------------------
51
// ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
52
// ---------------------------------------------------------------------------
53
void
54
ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id,
55
double val, double beg, double end) const {
56
ROEdge* e = myNet.getEdge(id);
57
if (e != nullptr) {
58
e->addTravelTime(val, beg, end);
59
} else {
60
if (id[0] != ':') {
61
if (OptionsCont::getOptions().getBool("ignore-errors")) {
62
WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
63
} else {
64
WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
65
}
66
}
67
}
68
}
69
70
71
// ---------------------------------------------------------------------------
72
// ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight - methods
73
// ---------------------------------------------------------------------------
74
void
75
ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight::addEdgeWeight(const std::string& id,
76
double val, double beg, double end) const {
77
ROEdge* e = myNet.getEdge(id);
78
if (e != nullptr) {
79
e->addEffort(val, beg, end);
80
} else {
81
if (id[0] != ':') {
82
if (OptionsCont::getOptions().getBool("ignore-errors")) {
83
WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
84
} else {
85
WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
86
}
87
}
88
}
89
}
90
91
92
// ---------------------------------------------------------------------------
93
// ROLoader - methods
94
// ---------------------------------------------------------------------------
95
ROLoader::ROLoader(OptionsCont& oc, const bool emptyDestinationsAllowed, const bool logSteps) :
96
myOptions(oc),
97
myEmptyDestinationsAllowed(emptyDestinationsAllowed),
98
myLogSteps(logSteps),
99
myLoaders(oc.exists("unsorted-input") && oc.getBool("unsorted-input") ? 0 : DELTA_T) {
100
}
101
102
103
ROLoader::~ROLoader() {
104
}
105
106
107
void
108
ROLoader::loadNet(RONet& toFill, ROAbstractEdgeBuilder& eb) {
109
std::string file = myOptions.getString("net-file");
110
if (file == "") {
111
throw ProcessError(TL("Missing definition of network to load!"));
112
}
113
if (!FileHelpers::isReadable(file)) {
114
throw ProcessError(TLF("The network file '%' is not accessible.", file));
115
}
116
PROGRESS_BEGIN_MESSAGE(TL("Loading net"));
117
RONetHandler handler(toFill, eb, !myOptions.exists("no-internal-links") || myOptions.getBool("no-internal-links"),
118
myOptions.exists("weights.minor-penalty") ? myOptions.getFloat("weights.minor-penalty") : 0,
119
myOptions.exists("weights.tls-penalty") ? myOptions.getFloat("weights.tls-penalty") : 0,
120
myOptions.exists("weights.turnaround-penalty") ? myOptions.getFloat("weights.turnaround-penalty") : 0);
121
handler.setFileName(file);
122
if (!XMLSubSys::runParser(handler, file, true)) {
123
PROGRESS_FAILED_MESSAGE();
124
throw ProcessError();
125
} else {
126
PROGRESS_DONE_MESSAGE();
127
}
128
if (!deprecatedVehicleClassesSeen.empty()) {
129
WRITE_WARNINGF(TL("Deprecated vehicle classes '%' in input network."), toString(deprecatedVehicleClassesSeen));
130
deprecatedVehicleClassesSeen.clear();
131
}
132
if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
133
std::vector<std::string> files = myOptions.getStringVector("additional-files");
134
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
135
if (!FileHelpers::isReadable(*fileIt)) {
136
throw ProcessError(TLF("The additional file '%' is not accessible.", *fileIt));
137
}
138
PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
139
handler.setFileName(*fileIt);
140
if (!XMLSubSys::runParser(handler, *fileIt)) {
141
PROGRESS_FAILED_MESSAGE();
142
throw ProcessError();
143
} else {
144
PROGRESS_DONE_MESSAGE();
145
}
146
}
147
}
148
if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
149
// create a TAZ for every junction
150
toFill.addJunctionTaz(eb);
151
}
152
toFill.setBidiEdges(handler.getBidiMap());
153
if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
154
toFill.setParamRestrictions();
155
const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
156
for (auto& edgeIt : toFill.getEdgeMap()) {
157
edgeIt.second->cacheParamRestrictions(paramKeys);
158
}
159
}
160
if (toFill.hasSpeedRestrictions()) {
161
for (auto& edgeIt : toFill.getEdgeMap()) {
162
edgeIt.second->setSpeedRestrictions(toFill.getRestrictions(edgeIt.second->getType()));
163
}
164
}
165
}
166
167
168
void
169
ROLoader::openRoutes(RONet& net) {
170
// build loader
171
// load relevant elements from additional file
172
bool ok = openTypedRoutes("additional-files", net, true);
173
// load sumo routes, trips, and flows
174
ok &= openTypedRoutes("route-files", net);
175
// check
176
if (ok) {
177
myLoaders.loadNext(string2time(myOptions.getString("begin")));
178
if (!net.furtherStored()) {
179
if (MsgHandler::getErrorInstance()->wasInformed()) {
180
throw ProcessError();
181
} else {
182
const std::string error = "No route input specified or all routes were invalid.";
183
if (myOptions.getBool("ignore-errors")) {
184
WRITE_WARNING(error);
185
} else {
186
throw ProcessError(error);
187
}
188
}
189
}
190
// skip routes prior to the begin time
191
if (!myOptions.getBool("unsorted-input")) {
192
WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
193
}
194
}
195
}
196
197
198
void
199
ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
200
RONet& net, const RORouterProvider& provider) {
201
const SUMOTime absNo = end - start;
202
const bool endGiven = !OptionsCont::getOptions().isDefault("end");
203
// skip routes that begin before the simulation's begin
204
// loop till the end
205
const SUMOTime firstStep = myLoaders.getFirstLoadTime();
206
SUMOTime lastStep = firstStep;
207
SUMOTime time = MIN2(firstStep, end);
208
while (time <= end) {
209
writeStats(time, start, absNo, endGiven);
210
myLoaders.loadNext(time);
211
if (!net.furtherStored() || MsgHandler::getErrorInstance()->wasInformed()) {
212
break;
213
}
214
lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
215
if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
216
break;
217
}
218
if (time < end && time > end - increment) {
219
time = end;
220
} else {
221
time += increment;
222
}
223
}
224
if (myLogSteps) {
225
WRITE_MESSAGEF(TL("Routes found between time steps % and %."), time2string(firstStep), time2string(lastStep));
226
}
227
}
228
229
230
bool
231
ROLoader::openTypedRoutes(const std::string& optionName,
232
RONet& net, const bool readAll) {
233
// check whether the current loader is wished
234
// and the file(s) can be used
235
if (!myOptions.isUsableFileList(optionName)) {
236
return !myOptions.isSet(optionName);
237
}
238
for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
239
try {
240
RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
241
if (readAll) {
242
if (!XMLSubSys::runParser(*handler, fileIt)) {
243
WRITE_ERRORF(TL("Loading of % failed."), fileIt);
244
return false;
245
}
246
delete handler;
247
} else {
248
myLoaders.add(new SUMORouteLoader(handler));
249
}
250
} catch (ProcessError& e) {
251
WRITE_ERRORF(TL("The loader for % from file '%' could not be initialised (%)."), optionName, fileIt, e.what());
252
return false;
253
}
254
}
255
return true;
256
}
257
258
259
bool
260
ROLoader::loadWeights(RONet& net, const std::string& optionName,
261
const std::string& measure, const bool useLanes, const bool boundariesOverride) {
262
// check whether the file exists
263
if (!myOptions.isUsableFileList(optionName)) {
264
return false;
265
}
266
// build and prepare the weights handler
267
std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
268
// travel time, first (always used)
269
EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(net);
270
retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
271
// the measure to use, then
272
EdgeFloatTimeLineRetriever_EdgeWeight eRetriever(net);
273
if (measure != "traveltime") {
274
std::string umeasure = measure;
275
if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
276
umeasure = measure + "_perVeh";
277
}
278
retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
279
}
280
// set up handler
281
SAXWeightsHandler handler(retrieverDefs, "");
282
// go through files
283
std::vector<std::string> files = myOptions.getStringVector(optionName);
284
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
285
PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
286
if (XMLSubSys::runParser(handler, *fileIt)) {
287
PROGRESS_DONE_MESSAGE();
288
} else {
289
WRITE_MESSAGE(TL("failed."));
290
return false;
291
}
292
}
293
// build edge-internal time lines
294
for (const auto& i : net.getEdgeMap()) {
295
i.second->buildTimeLines(measure, boundariesOverride);
296
}
297
return true;
298
}
299
300
301
void
302
ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
303
if (myLogSteps) {
304
if (endGiven) {
305
const double perc = (double)(time - start) / (double) absNo;
306
std::cout << "Reading up to time step: " + time2string(time) + " (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done) \r";
307
} else {
308
std::cout << "Reading up to time step: " + time2string(time) + "\r";
309
}
310
}
311
}
312
313
SUMORouteHandler*
314
ROLoader::getRouteHandler() {
315
auto loader = myLoaders.getFirstLoader();
316
if (loader != nullptr) {
317
return loader->getRouteHandler();
318
} else {
319
return nullptr;
320
}
321
}
322
/****************************************************************************/
323
324