Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/dfrouter/dfrouter_main.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 dfrouter_main.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Eric Nicolay
17
/// @author Jakob Erdmann
18
/// @author Sascha Krieg
19
/// @author Michael Behrisch
20
/// @author Laura Bieker
21
/// @date Thu, 16.03.2006
22
///
23
// Main for the DFROUTER
24
/****************************************************************************/
25
#include <config.h>
26
27
#ifdef HAVE_VERSION_H
28
#include <version.h>
29
#endif
30
31
#include <iostream>
32
#include <string>
33
#include <limits.h>
34
#include <ctime>
35
#include <xercesc/sax/SAXException.hpp>
36
#include <xercesc/sax/SAXParseException.hpp>
37
#include <utils/common/StringUtils.h>
38
#include <utils/common/MsgHandler.h>
39
#include <utils/common/UtilExceptions.h>
40
#include <utils/common/SystemFrame.h>
41
#include <utils/common/ToString.h>
42
#include <utils/common/FileHelpers.h>
43
#include <utils/options/Option.h>
44
#include <utils/options/OptionsCont.h>
45
#include <utils/options/OptionsIO.h>
46
#include <utils/iodevices/OutputDevice.h>
47
#include <utils/xml/XMLSubSys.h>
48
#include <router/ROLoader.h>
49
#include <router/RONet.h>
50
#include "RODFEdgeBuilder.h"
51
#include "RODFFrame.h"
52
#include "RODFNet.h"
53
#include "RODFEdge.h"
54
#include "RODFDetector.h"
55
#include "RODFDetectorHandler.h"
56
#include "RODFRouteCont.h"
57
#include "RODFDetectorFlow.h"
58
#include "RODFDetFlowLoader.h"
59
60
61
// ===========================================================================
62
// functions
63
// ===========================================================================
64
/* -------------------------------------------------------------------------
65
* data processing methods
66
* ----------------------------------------------------------------------- */
67
void
68
readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
69
if (!oc.isSet("detector-files")) {
70
throw ProcessError(TL("No detector file given (use --detector-files <FILE>)."));
71
}
72
// read definitions stored in XML-format
73
std::vector<std::string> files = oc.getStringVector("detector-files");
74
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
75
if (!FileHelpers::isReadable(*fileIt)) {
76
throw ProcessError(TLF("Could not open detector file '%'", *fileIt));
77
}
78
PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
79
RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
80
if (XMLSubSys::runParser(handler, *fileIt)) {
81
PROGRESS_DONE_MESSAGE();
82
} else {
83
PROGRESS_FAILED_MESSAGE();
84
throw ProcessError();
85
}
86
}
87
if (detectors.getDetectors().empty()) {
88
throw ProcessError(TL("No detectors found."));
89
}
90
}
91
92
93
void
94
readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) {
95
if (!oc.isSet("measure-files")) {
96
// ok, not given, return an empty container
97
return;
98
}
99
// check whether the file exists
100
std::vector<std::string> files = oc.getStringVector("measure-files");
101
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
102
if (!FileHelpers::isReadable(*fileIt)) {
103
throw ProcessError(TLF("The measure-file '%' can not be opened.", *fileIt));
104
}
105
// parse
106
PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
107
RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")),
108
string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor")));
109
dfl.read(*fileIt);
110
PROGRESS_DONE_MESSAGE();
111
}
112
}
113
114
115
void
116
startComputation(RODFNet* optNet, RODFDetectorFlows& flows, RODFDetectorCon& detectors, OptionsCont& oc) {
117
if (oc.getBool("print-absolute-flows")) {
118
flows.printAbsolute();
119
}
120
121
if (oc.getBool("remove-empty-detectors")) {
122
PROGRESS_BEGIN_MESSAGE(TL("Removing empty detectors"));
123
optNet->removeEmptyDetectors(detectors, flows);
124
PROGRESS_DONE_MESSAGE();
125
} else if (oc.getBool("report-empty-detectors")) {
126
PROGRESS_BEGIN_MESSAGE(TL("Scanning for empty detectors"));
127
optNet->reportEmptyDetectors(detectors, flows);
128
PROGRESS_DONE_MESSAGE();
129
}
130
// compute the detector types (optionally)
131
if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
132
optNet->computeTypes(detectors, oc.getBool("strict-sources"));
133
}
134
std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
135
for (; i != detectors.getDetectors().end(); ++i) {
136
if ((*i)->getType() == SOURCE_DETECTOR) {
137
break;
138
}
139
}
140
if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
141
throw ProcessError(TL("No source detectors found."));
142
}
143
// compute routes between the detectors (optionally)
144
if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
145
PROGRESS_BEGIN_MESSAGE(TL("Computing routes"));
146
optNet->buildRoutes(detectors,
147
oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
148
!oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
149
PROGRESS_DONE_MESSAGE();
150
}
151
152
// check
153
// whether the detectors are valid
154
if (!detectors.detectorsHaveCompleteTypes()) {
155
throw ProcessError(TL("The detector types are not defined; use in combination with a network"));
156
}
157
// whether the detectors have routes
158
if (!detectors.detectorsHaveRoutes()) {
159
throw ProcessError(TL("The emitters have no routes; use in combination with a network"));
160
}
161
162
// save the detectors if wished
163
if (oc.isSet("detector-output")) {
164
detectors.save(oc.getString("detector-output"));
165
}
166
// save their positions as POIs if wished
167
if (oc.isSet("detectors-poi-output")) {
168
detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
169
}
170
171
// save the routes file if it was changed or it's wished
172
if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
173
detectors.saveRoutes(oc.getString("routes-output"));
174
}
175
176
// guess flows if wished
177
if (oc.getBool("guess-empty-flows")) {
178
optNet->buildDetectorDependencies(detectors);
179
detectors.guessEmptyFlows(flows);
180
}
181
182
const SUMOTime begin = string2time(oc.getString("begin"));
183
const SUMOTime end = string2time(oc.getString("end"));
184
const SUMOTime step = string2time(oc.getString("time-step"));
185
186
// save emitters if wished
187
if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
188
optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!!
189
if (oc.getBool("revalidate-flows")) {
190
PROGRESS_BEGIN_MESSAGE(TL("Rechecking loaded flows"));
191
optNet->revalidateFlows(detectors, flows, begin, end, step);
192
PROGRESS_DONE_MESSAGE();
193
}
194
if (oc.isSet("emitters-output")) {
195
PROGRESS_BEGIN_MESSAGE(TL("Writing emitters"));
196
detectors.writeEmitters(oc.getString("emitters-output"), flows,
197
begin, end, step,
198
*optNet,
199
oc.getBool("calibrator-output"),
200
oc.getBool("include-unused-routes"),
201
oc.getFloat("scale"),
202
// oc.getInt("max-search-depth"),
203
oc.getBool("emissions-only"));
204
PROGRESS_DONE_MESSAGE();
205
}
206
if (oc.isSet("emitters-poi-output")) {
207
PROGRESS_BEGIN_MESSAGE(TL("Writing emitter pois"));
208
detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
209
PROGRESS_DONE_MESSAGE();
210
}
211
}
212
// save end speed trigger if wished
213
if (oc.isSet("variable-speed-sign-output")) {
214
PROGRESS_BEGIN_MESSAGE(TL("Writing speed triggers"));
215
detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
216
begin, end, step);
217
PROGRESS_DONE_MESSAGE();
218
}
219
// save checking detectors if wished
220
if (oc.isSet("validation-output")) {
221
PROGRESS_BEGIN_MESSAGE(TL("Writing validation detectors"));
222
detectors.writeValidationDetectors(oc.getString("validation-output"),
223
oc.getBool("validation-output.add-sources"), true, true); // !!!
224
PROGRESS_DONE_MESSAGE();
225
}
226
// build global rerouter on end if wished
227
if (oc.isSet("end-reroute-output")) {
228
PROGRESS_BEGIN_MESSAGE(TL("Writing highway end rerouter"));
229
detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!!
230
PROGRESS_DONE_MESSAGE();
231
}
232
/*
233
// save the insertion definitions
234
if(oc.isSet("flow-definitions")) {
235
buildVehicleEmissions(oc.getString("flow-definitions"));
236
}
237
*/
238
//
239
}
240
241
242
/* -------------------------------------------------------------------------
243
* main
244
* ----------------------------------------------------------------------- */
245
int
246
main(int argc, char** argv) {
247
OptionsCont& oc = OptionsCont::getOptions();
248
oc.setApplicationDescription(TL("Builds vehicle routes for SUMO using detector values."));
249
oc.setApplicationName("dfrouter", "Eclipse SUMO dfrouter " VERSION_STRING);
250
int ret = 0;
251
RODFNet* net = nullptr;
252
RODFDetectorCon* detectors = nullptr;
253
RODFDetectorFlows* flows = nullptr;
254
try {
255
// initialise the application system (messaging, xml, options)
256
XMLSubSys::init();
257
RODFFrame::fillOptions();
258
OptionsIO::setArgs(argc, argv);
259
OptionsIO::getOptions();
260
if (oc.processMetaOptions(argc < 2)) {
261
SystemFrame::close();
262
return 0;
263
}
264
SystemFrame::checkOptions(oc);
265
XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), "never");
266
MsgHandler::initOutputOptions();
267
if (!RODFFrame::checkOptions()) {
268
throw ProcessError();
269
}
270
RandHelper::initRandGlobal();
271
// load data
272
ROLoader loader(oc, false, !oc.getBool("no-step-log"));
273
net = new RODFNet(oc.getBool("highway-mode"));
274
RODFEdgeBuilder builder;
275
loader.loadNet(*net, builder);
276
net->buildApproachList();
277
// load detectors
278
detectors = new RODFDetectorCon();
279
readDetectors(*detectors, oc, net);
280
// load detector values
281
flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
282
string2time(oc.getString("time-step")));
283
readDetectorFlows(*flows, oc, *detectors);
284
// build routes
285
startComputation(net, *flows, *detectors, oc);
286
} catch (const ProcessError& e) {
287
if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
288
WRITE_ERROR(e.what());
289
}
290
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
291
ret = 1;
292
#ifndef _DEBUG
293
} catch (const std::exception& e) {
294
if (std::string(e.what()) != std::string("")) {
295
WRITE_ERROR(e.what());
296
}
297
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
298
ret = 1;
299
} catch (...) {
300
MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
301
ret = 1;
302
#endif
303
}
304
delete net;
305
delete flows;
306
delete detectors;
307
SystemFrame::close();
308
if (ret == 0) {
309
std::cout << "Success." << std::endl;
310
}
311
return ret;
312
}
313
314
315
/****************************************************************************/
316
317