Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/od2trips_main.cpp
169649 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2002-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 od2trips_main.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Laura Bieker
19
/// @author Yun-Pang Floetteroed
20
/// @date Thu, 12 September 2002
21
///
22
// Main for OD2TRIPS
23
/****************************************************************************/
24
#include <config.h>
25
26
#ifdef HAVE_VERSION_H
27
#include <version.h>
28
#endif
29
30
#include <iostream>
31
#include <algorithm>
32
#include <cmath>
33
#include <cstdlib>
34
#include <string>
35
#include <utils/options/Option.h>
36
#include <utils/options/OptionsCont.h>
37
#include <utils/options/OptionsIO.h>
38
#include <utils/common/MsgHandler.h>
39
#include <utils/common/UtilExceptions.h>
40
#include <utils/common/SystemFrame.h>
41
#include <utils/common/RandHelper.h>
42
#include <utils/common/ToString.h>
43
#include <utils/xml/XMLSubSys.h>
44
#include <utils/common/StringUtils.h>
45
#include <od/ODDistrictCont.h>
46
#include <od/ODDistrictHandler.h>
47
#include <od/ODMatrix.h>
48
#include <utils/common/StringUtils.h>
49
#include <utils/common/SUMOTime.h>
50
#include <utils/common/StringTokenizer.h>
51
#include <utils/common/FileHelpers.h>
52
#include <utils/vehicle/SUMOVehicleParameter.h>
53
#include <utils/importio/LineReader.h>
54
#include <utils/iodevices/OutputDevice.h>
55
56
57
// ===========================================================================
58
// functions
59
// ===========================================================================
60
void
61
fillOptions() {
62
OptionsCont& oc = OptionsCont::getOptions();
63
oc.addCallExample("-c <CONFIGURATION>", "run with configuration file");
64
65
// insert options sub-topics
66
SystemFrame::addConfigurationOptions(oc); // fill this subtopic, too
67
oc.addOptionSubTopic("Input");
68
oc.addOptionSubTopic("Output");
69
oc.addOptionSubTopic("Time");
70
oc.addOptionSubTopic("Processing");
71
oc.addOptionSubTopic("Defaults");
72
SystemFrame::addReportOptions(oc); // fill this subtopic, too
73
74
75
// register the file input options
76
oc.doRegister("taz-files", 'n', new Option_FileName());
77
oc.addSynonyme("taz-files", "taz");
78
oc.addSynonyme("taz-files", "net-file");
79
oc.addSynonyme("taz-files", "net");
80
oc.addDescription("taz-files", "Input", TL("Loads TAZ (districts; also from networks) from FILE(s)"));
81
82
oc.doRegister("od-matrix-files", 'd', new Option_FileName());
83
oc.addSynonyme("od-matrix-files", "od-files");
84
oc.addSynonyme("od-matrix-files", "od");
85
oc.addDescription("od-matrix-files", "Input", TL("Loads O/D-files from FILE(s)"));
86
87
oc.doRegister("od-amitran-files", new Option_FileName());
88
oc.addSynonyme("od-amitran-files", "amitran-files");
89
oc.addSynonyme("od-amitran-files", "amitran");
90
oc.addDescription("od-amitran-files", "Input", TL("Loads O/D-matrix in Amitran format from FILE(s)"));
91
92
oc.doRegister("tazrelation-files", 'z', new Option_FileName());
93
oc.addDescription("tazrelation-files", "Input", TL("Loads O/D-matrix in tazRelation format from FILE(s)"));
94
95
oc.doRegister("tazrelation-attribute", new Option_String("count"));
96
oc.addSynonyme("tazrelation-attribute", "attribute");
97
oc.addDescription("tazrelation-attribute", "Input", TL("Define data attribute for loading counts (default 'count')"));
98
99
// register the file output options
100
oc.doRegister("output-file", 'o', new Option_FileName());
101
oc.addSynonyme("output-file", "output", true);
102
oc.addDescription("output-file", "Output", TL("Writes trip definitions into FILE"));
103
104
oc.doRegister("flow-output", new Option_FileName());
105
oc.addDescription("flow-output", "Output", TL("Writes flow definitions into FILE"));
106
107
oc.doRegister("flow-output.probability", new Option_Bool(false));
108
oc.addDescription("flow-output.probability", "Output", TL("Writes probabilistic flow instead of evenly spaced flow"));
109
110
oc.doRegister("pedestrians", new Option_Bool(false));
111
oc.addDescription("pedestrians", "Output", TL("Writes pedestrians instead of vehicles"));
112
113
oc.doRegister("persontrips", new Option_Bool(false));
114
oc.addDescription("persontrips", "Output", TL("Writes persontrips instead of vehicles"));
115
116
oc.doRegister("persontrips.modes", new Option_StringVector());
117
oc.addDescription("persontrips.modes", "Output", TL("Add modes attribute to personTrips"));
118
119
oc.doRegister("ignore-vehicle-type", new Option_Bool(false));
120
oc.addSynonyme("ignore-vehicle-type", "no-vtype", true);
121
oc.addDescription("ignore-vehicle-type", "Output", TL("Does not save vtype information"));
122
123
oc.doRegister("junctions", new Option_Bool(false));
124
oc.addDescription("junctions", "Output", TL("Writes trips between junctions"));
125
126
127
// register the time settings
128
oc.doRegister("begin", 'b', new Option_String("0", "TIME"));
129
oc.addDescription("begin", "Time", TL("Defines the begin time; Previous trips will be discarded"));
130
131
oc.doRegister("end", 'e', new Option_String("-1", "TIME"));
132
oc.addDescription("end", "Time", TL("Defines the end time; Later trips will be discarded; Defaults to the maximum time that SUMO can represent"));
133
134
135
// register the data processing options
136
oc.doRegister("scale", 's', new Option_Float(1));
137
oc.addDescription("scale", "Processing", TL("Scales the loaded flows by FLOAT"));
138
139
oc.doRegister("spread.uniform", new Option_Bool(false));
140
oc.addDescription("spread.uniform", "Processing", TL("Spreads trips uniformly over each time period"));
141
142
oc.doRegister("different-source-sink", new Option_Bool(false));
143
oc.addDescription("different-source-sink", "Processing", TL("Always choose source and sink edge which are not identical"));
144
145
oc.doRegister("vtype", new Option_String(""));
146
oc.addDescription("vtype", "Processing", TL("Defines the name of the vehicle type to use"));
147
148
oc.doRegister("prefix", new Option_String(""));
149
oc.addDescription("prefix", "Processing", TL("Defines the prefix for vehicle names"));
150
151
oc.doRegister("timeline", new Option_StringVector());
152
oc.addDescription("timeline", "Processing", TL("Uses STR[] as a timeline definition"));
153
154
oc.doRegister("timeline.day-in-hours", new Option_Bool(false));
155
oc.addDescription("timeline.day-in-hours", "Processing", TL("Uses STR as a 24h-timeline definition"));
156
157
oc.doRegister("ignore-errors", new Option_Bool(false)); // !!! describe, document
158
oc.addSynonyme("ignore-errors", "dismiss-loading-errors", true);
159
oc.addDescription("ignore-errors", "Report", TL("Continue on broken input"));
160
161
oc.doRegister("no-step-log", new Option_Bool(false));
162
oc.addDescription("no-step-log", "Processing", TL("Disable console output of current time step"));
163
164
165
// register defaults options
166
oc.doRegister("departlane", new Option_String("free"));
167
oc.addDescription("departlane", "Defaults", TL("Assigns a default depart lane"));
168
169
oc.doRegister("departpos", new Option_String());
170
oc.addDescription("departpos", "Defaults", TL("Assigns a default depart position"));
171
172
oc.doRegister("departspeed", new Option_String("max"));
173
oc.addDescription("departspeed", "Defaults", TL("Assigns a default depart speed"));
174
175
oc.doRegister("arrivallane", new Option_String());
176
oc.addDescription("arrivallane", "Defaults", TL("Assigns a default arrival lane"));
177
178
oc.doRegister("arrivalpos", new Option_String());
179
oc.addDescription("arrivalpos", "Defaults", TL("Assigns a default arrival position"));
180
181
oc.doRegister("arrivalspeed", new Option_String());
182
oc.addDescription("arrivalspeed", "Defaults", TL("Assigns a default arrival speed"));
183
184
// add rand options
185
RandHelper::insertRandOptions(oc);
186
}
187
188
bool
189
checkOptions() {
190
OptionsCont& oc = OptionsCont::getOptions();
191
bool ok = true;
192
if (!oc.isSet("taz-files")) {
193
WRITE_ERROR(TL("No TAZ input file (-n) specified."));
194
ok = false;
195
}
196
if (!oc.isSet("od-matrix-files") && !oc.isSet("od-amitran-files") && !oc.isSet("tazrelation-files")) {
197
WRITE_ERROR(TL("No input specified."));
198
ok = false;
199
}
200
if (!oc.isSet("output-file") && !oc.isSet("flow-output")) {
201
WRITE_ERROR(TL("No trip table output file (-o) or flow-output is specified."));
202
ok = false;
203
}
204
if (oc.getBool("pedestrians") && oc.getBool("persontrips")) {
205
WRITE_ERROR(TL("Only one of the Options 'pedestrians' and 'persontrips' may be set."));
206
ok = false;
207
}
208
//
209
SUMOVehicleParameter p;
210
std::string error;
211
if (oc.isSet("departlane") && !SUMOVehicleParameter::parseDepartLane(oc.getString("departlane"), "option", "departlane", p.departLane, p.departLaneProcedure, error)) {
212
WRITE_ERROR(error);
213
ok = false;
214
}
215
if (oc.isSet("departpos") && !SUMOVehicleParameter::parseDepartPos(oc.getString("departpos"), "option", "departpos", p.departPos, p.departPosProcedure, error)) {
216
WRITE_ERROR(error);
217
ok = false;
218
}
219
if (oc.isSet("departspeed") && !SUMOVehicleParameter::parseDepartSpeed(oc.getString("departspeed"), "option", "departspeed", p.departSpeed, p.departSpeedProcedure, error)) {
220
WRITE_ERROR(error);
221
ok = false;
222
}
223
if (oc.isSet("arrivallane") && !SUMOVehicleParameter::parseArrivalLane(oc.getString("arrivallane"), "option", "arrivallane", p.arrivalLane, p.arrivalLaneProcedure, error)) {
224
WRITE_ERROR(error);
225
ok = false;
226
}
227
if (oc.isSet("arrivalpos") && !SUMOVehicleParameter::parseArrivalPos(oc.getString("arrivalpos"), "option", "arrivalpos", p.arrivalPos, p.arrivalPosProcedure, error)) {
228
WRITE_ERROR(error);
229
ok = false;
230
}
231
if (oc.isSet("arrivalspeed") && !SUMOVehicleParameter::parseArrivalSpeed(oc.getString("arrivalspeed"), "option", "arrivalspeed", p.arrivalSpeed, p.arrivalSpeedProcedure, error)) {
232
WRITE_ERROR(error);
233
ok = false;
234
}
235
ok &= SystemFrame::checkOptions(oc);
236
return ok;
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("Importer of O/D-matrices for the microscopic, multi-modal traffic simulation SUMO."));
249
oc.setApplicationName("od2trips", "Eclipse SUMO od2trips " VERSION_STRING);
250
int ret = 0;
251
try {
252
// initialise subsystems
253
XMLSubSys::init();
254
fillOptions();
255
OptionsIO::setArgs(argc, argv);
256
OptionsIO::getOptions();
257
if (oc.processMetaOptions(argc < 2)) {
258
SystemFrame::close();
259
return 0;
260
}
261
XMLSubSys::setValidation(oc.getString("xml-validation"), "never", "never");
262
MsgHandler::initOutputOptions();
263
if (!checkOptions()) {
264
throw ProcessError();
265
}
266
RandHelper::initRandGlobal();
267
// load the districts
268
// check whether the user gave a net filename
269
if (!oc.isSet("taz-files")) {
270
throw ProcessError(TL("You must supply a TAZ, network or districts file ('-n')."));
271
}
272
// get the file name and set it
273
ODDistrictCont districts;
274
districts.loadDistricts(oc.getStringVector("taz-files"));
275
if (districts.size() == 0) {
276
throw ProcessError(TL("No districts loaded."));
277
}
278
// load the matrix
279
ODMatrix matrix(districts, oc.getFloat("scale"));
280
matrix.loadMatrix(oc);
281
if (matrix.getNumLoaded() == 0) {
282
throw ProcessError(TL("No vehicles loaded."));
283
}
284
if (MsgHandler::getErrorInstance()->wasInformed() && !oc.getBool("ignore-errors")) {
285
throw ProcessError(TL("Loading failed."));
286
}
287
WRITE_MESSAGE(toString(matrix.getNumLoaded()) + " vehicles loaded.");
288
// apply a curve if wished
289
if (oc.isSet("timeline")) {
290
matrix.applyCurve(matrix.parseTimeLine(oc.getStringVector("timeline"), oc.getBool("timeline.day-in-hours")));
291
}
292
const std::string modes = toString(oc.getStringVector("persontrips.modes"));
293
// write
294
bool haveOutput = false;
295
const SUMOTime end = oc.isDefault("end") ? SUMOTime_MAX : string2time(oc.getString("end"));
296
if (OutputDevice::createDeviceByOption("output-file", "routes", "routes_file.xsd")) {
297
matrix.write(string2time(oc.getString("begin")), end,
298
OutputDevice::getDeviceByOption("output-file"),
299
oc.getBool("spread.uniform"), oc.getBool("different-source-sink"),
300
oc.getBool("ignore-vehicle-type"),
301
oc.getString("prefix"), !oc.getBool("no-step-log"),
302
oc.getBool("pedestrians"),
303
oc.getBool("persontrips"), modes);
304
haveOutput = true;
305
}
306
if (OutputDevice::createDeviceByOption("flow-output", "routes", "routes_file.xsd")) {
307
matrix.writeFlows(string2time(oc.getString("begin")), end,
308
OutputDevice::getDeviceByOption("flow-output"),
309
oc.getBool("ignore-vehicle-type"), oc.getString("prefix"),
310
oc.getBool("flow-output.probability"), oc.getBool("pedestrians"),
311
oc.getBool("persontrips"), modes);
312
haveOutput = true;
313
}
314
if (!haveOutput) {
315
throw ProcessError(TL("No output file given."));
316
}
317
WRITE_MESSAGE(toString(matrix.getNumDiscarded()) + " vehicles discarded.");
318
WRITE_MESSAGE(toString(matrix.getNumWritten()) + " vehicles written.");
319
} catch (const ProcessError& e) {
320
if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
321
WRITE_ERROR(e.what());
322
}
323
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
324
ret = 1;
325
#ifndef _DEBUG
326
} catch (const std::exception& e) {
327
if (std::string(e.what()) != std::string("")) {
328
WRITE_ERROR(e.what());
329
}
330
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
331
ret = 1;
332
} catch (...) {
333
MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
334
ret = 1;
335
#endif
336
}
337
SystemFrame::close();
338
if (ret == 0) {
339
std::cout << "Success." << std::endl;
340
}
341
return ret;
342
}
343
344
345
/****************************************************************************/
346
347