Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/jtrrouter/jtrrouter_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 jtrrouter_main.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Tue, 20 Jan 2004
19
///
20
// Main for JTRROUTER
21
/****************************************************************************/
22
#include <config.h>
23
24
#ifdef HAVE_VERSION_H
25
#include <version.h>
26
#endif
27
28
#include <iostream>
29
#include <string>
30
#include <limits.h>
31
#include <ctime>
32
#include <set>
33
#include <xercesc/sax/SAXException.hpp>
34
#include <xercesc/sax/SAXParseException.hpp>
35
#include <utils/common/StringUtils.h>
36
#include <utils/common/MsgHandler.h>
37
#include <utils/common/UtilExceptions.h>
38
#include <utils/common/SystemFrame.h>
39
#include <utils/common/ToString.h>
40
#include <utils/common/RandHelper.h>
41
#include <utils/common/StringTokenizer.h>
42
#include <utils/iodevices/OutputDevice.h>
43
#include <utils/options/Option.h>
44
#include <utils/options/OptionsCont.h>
45
#include <utils/options/OptionsIO.h>
46
#include <utils/xml/XMLSubSys.h>
47
#include <router/ROFrame.h>
48
#include <router/ROLoader.h>
49
#include <router/RONet.h>
50
#include <router/RORouteDef.h>
51
#include "ROJTREdgeBuilder.h"
52
#include "ROJTRRouter.h"
53
#include "ROJTREdge.h"
54
#include "ROJTRTurnDefLoader.h"
55
#include "ROJTRFrame.h"
56
57
// ===========================================================================
58
// method declaration
59
// ===========================================================================
60
61
void initNet(RONet& net, ROLoader& loader, const std::vector<double>& turnDefs);
62
std::vector<double> getTurningDefaults(OptionsCont& oc);
63
void loadJTRDefinitions(RONet& net, OptionsCont& oc);
64
void computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc);
65
66
// ===========================================================================
67
// method implementation
68
// ===========================================================================
69
/* -------------------------------------------------------------------------
70
* data processing methods
71
* ----------------------------------------------------------------------- */
72
/**
73
* loads the net
74
* The net is in this meaning made up by the net itself and the dynamic
75
* weights which may be supplied in a separate file
76
*/
77
void
78
initNet(RONet& net, ROLoader& loader,
79
const std::vector<double>& turnDefs) {
80
// load the net
81
ROJTREdgeBuilder builder;
82
loader.loadNet(net, builder);
83
// set the turn defaults
84
for (const auto& i : net.getEdgeMap()) {
85
static_cast<ROJTREdge*>(i.second)->setTurnDefaults(turnDefs);
86
}
87
}
88
89
std::vector<double>
90
getTurningDefaults(OptionsCont& oc) {
91
std::vector<double> ret;
92
std::vector<std::string> defs = oc.getStringVector("turn-defaults");
93
if (defs.size() < 2) {
94
throw ProcessError(TL("The defaults for turnings must be a tuple of at least two numbers divided by ','."));
95
}
96
for (std::vector<std::string>::const_iterator i = defs.begin(); i != defs.end(); ++i) {
97
try {
98
double val = StringUtils::toDouble(*i);
99
ret.push_back(val);
100
} catch (NumberFormatException&) {
101
throw ProcessError(TL("A turn default is not numeric."));
102
}
103
}
104
return ret;
105
}
106
107
108
void
109
loadJTRDefinitions(RONet& net, OptionsCont& oc) {
110
// load the turning definitions (and possible sink definition)
111
if (oc.isSet("turn-ratio-files")) {
112
ROJTRTurnDefLoader loader(net);
113
std::vector<std::string> ratio_files = oc.getStringVector("turn-ratio-files");
114
for (std::vector<std::string>::const_iterator i = ratio_files.begin(); i != ratio_files.end(); ++i) {
115
if (!XMLSubSys::runParser(loader, *i)) {
116
throw ProcessError();
117
}
118
}
119
}
120
if (oc.getBool("sources-are-sinks") || oc.getBool("discount-sources")) {
121
// load all route-files and additional files to discover sink edges and flow discount values
122
ROJTRTurnDefLoader loader(net);
123
for (std::string fileOption : {
124
"route-files", "additional-files"
125
}) {
126
for (std::string file : oc.getStringVector(fileOption)) {
127
if (!XMLSubSys::runParser(loader, file)) {
128
throw ProcessError();
129
}
130
}
131
}
132
}
133
134
if (MsgHandler::getErrorInstance()->wasInformed() && oc.getBool("ignore-errors")) {
135
MsgHandler::getErrorInstance()->clear();
136
}
137
// parse sink edges specified at the input/within the configuration
138
if (oc.isSet("sink-edges")) {
139
std::vector<std::string> edges = oc.getStringVector("sink-edges");
140
for (std::vector<std::string>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
141
ROJTREdge* edge = static_cast<ROJTREdge*>(net.getEdge(*i));
142
if (edge == nullptr) {
143
throw ProcessError(TLF("The edge '%' declared as a sink is not known.", *i));
144
}
145
edge->setSink();
146
}
147
}
148
}
149
150
151
/**
152
* Computes the routes saving them
153
*/
154
void
155
computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) {
156
// initialise the loader
157
loader.openRoutes(net);
158
// prepare the output
159
net.openOutput(oc);
160
// build the router
161
ROJTRRouter* router = new ROJTRRouter(oc.getBool("ignore-errors"), oc.getBool("accept-all-destinations"),
162
(int)(((double) net.getEdgeNumber()) * OptionsCont::getOptions().getFloat("max-edges-factor")),
163
oc.getBool("ignore-vclasses"),
164
oc.getBool("allow-loops"),
165
oc.getBool("discount-sources"));
166
RORouteDef::setUsingJTRR();
167
RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(),
168
new ROIntermodalRouter(RONet::adaptIntermodalRouter, 0, 0, "dijkstra"), nullptr);
169
const SUMOTime end = oc.isDefault("end") ? SUMOTime_MAX : string2time(oc.getString("end"));
170
loader.processRoutes(string2time(oc.getString("begin")), end,
171
string2time(oc.getString("route-steps")), net, provider);
172
net.cleanup();
173
}
174
175
// -----------------------------------------------------------------------
176
// main
177
// -----------------------------------------------------------------------
178
179
int
180
main(int argc, char** argv) {
181
OptionsCont& oc = OptionsCont::getOptions();
182
oc.setApplicationDescription(TL("Router for the microscopic, multi-modal traffic simulation SUMO based on junction turning ratios."));
183
oc.setApplicationName("jtrrouter", "Eclipse SUMO jtrrouter " VERSION_STRING);
184
int ret = 0;
185
RONet* net = nullptr;
186
try {
187
// initialise the application system (messaging, xml, options)
188
XMLSubSys::init();
189
ROJTRFrame::fillOptions();
190
OptionsIO::setArgs(argc, argv);
191
OptionsIO::getOptions();
192
if (oc.processMetaOptions(argc < 2)) {
193
SystemFrame::close();
194
return 0;
195
}
196
SystemFrame::checkOptions(oc);
197
XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
198
MsgHandler::initOutputOptions();
199
if (!ROJTRFrame::checkOptions()) {
200
throw ProcessError();
201
}
202
RandHelper::initRandGlobal();
203
std::vector<double> defs = getTurningDefaults(oc);
204
// load data
205
ROLoader loader(oc, true, !oc.getBool("no-step-log"));
206
net = new RONet();
207
initNet(*net, loader, defs);
208
try {
209
// parse and set the turn defaults first
210
loadJTRDefinitions(*net, oc);
211
// build routes
212
computeRoutes(*net, loader, oc);
213
} catch (XERCES_CPP_NAMESPACE::SAXParseException& e) {
214
WRITE_ERROR(toString(e.getLineNumber()));
215
ret = 1;
216
} catch (XERCES_CPP_NAMESPACE::SAXException& e) {
217
WRITE_ERROR(StringUtils::transcode(e.getMessage()));
218
ret = 1;
219
}
220
if (MsgHandler::getErrorInstance()->wasInformed()) {
221
throw ProcessError();
222
}
223
} catch (const ProcessError& e) {
224
if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
225
WRITE_ERROR(e.what());
226
}
227
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
228
ret = 1;
229
#ifndef _DEBUG
230
} catch (const std::exception& e) {
231
if (std::string(e.what()) != std::string("")) {
232
WRITE_ERROR(e.what());
233
}
234
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
235
ret = 1;
236
} catch (...) {
237
MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
238
ret = 1;
239
#endif
240
}
241
delete net;
242
SystemFrame::close();
243
if (ret == 0) {
244
std::cout << "Success." << std::endl;
245
}
246
return ret;
247
}
248
249
250
/****************************************************************************/
251
252