Eclipse SUMO - Simulation of Urban MObility
od2trips_main.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2002-2024 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 /****************************************************************************/
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>
42 #include <utils/common/ToString.h>
43 #include <utils/xml/XMLSubSys.h>
45 #include <od/ODDistrictCont.h>
46 #include <od/ODDistrictHandler.h>
47 #include <od/ODMatrix.h>
49 #include <utils/common/SUMOTime.h>
55 
56 
57 // ===========================================================================
58 // functions
59 // ===========================================================================
60 void
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
186 }
187 
188 bool
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 the options 'pedestrians' and 'persontrips' may be set."));
206  ok = false;
207  }
208  //
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) {
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 " VERSION_STRING);
250  int ret = 0;
251  try {
252  // initialise subsystems
253  XMLSubSys::init();
254  fillOptions();
255  OptionsIO::setArgs(argc, argv);
257  if (oc.processMetaOptions(argc < 2)) {
259  return 0;
260  }
261  XMLSubSys::setValidation(oc.getString("xml-validation"), "never", "never");
263  if (!checkOptions()) {
264  throw ProcessError();
265  }
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  }
338  if (ret == 0) {
339  std::cout << "Success." << std::endl;
340  }
341  return ret;
342 }
343 
344 
345 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
#define SUMOTime_MAX
Definition: SUMOTime.h:34
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:92
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:154
static void initOutputOptions()
init output options
Definition: MsgHandler.cpp:316
int size() const
Returns the number of stored items within the container.
A container for districts.
void loadDistricts(std::vector< std::string > files)
load districts from files
An O/D (origin/destination) matrix.
Definition: ODMatrix.h:68
double getNumLoaded() const
Returns the number of loaded vehicles.
Definition: ODMatrix.cpp:603
void writeFlows(const SUMOTime begin, const SUMOTime end, OutputDevice &dev, const bool noVtype, const std::string &prefix, bool asProbability=false, bool pedestrians=false, bool persontrips=false, const std::string &modes="")
Writes the flows stored in the matrix.
Definition: ODMatrix.cpp:346
void applyCurve(const Distribution_Points &ps)
Splits the stored cells dividing them on the given time line.
Definition: ODMatrix.cpp:637
void write(SUMOTime begin, const SUMOTime end, OutputDevice &dev, const bool uniform, const bool differSourceSink, const bool noVtype, const std::string &prefix, const bool stepLog, bool pedestrians, bool persontrips, const std::string &modes)
Writes the vehicles stored in the matrix assigning the sources and sinks.
Definition: ODMatrix.cpp:236
Distribution_Points parseTimeLine(const std::vector< std::string > &def, bool timelineDayInHours)
split the given timeline
Definition: ODMatrix.cpp:735
void loadMatrix(OptionsCont &oc)
read a matrix in one of several formats
Definition: ODMatrix.cpp:650
double getNumWritten() const
Returns the number of written vehicles.
Definition: ODMatrix.cpp:609
double getNumDiscarded() const
Returns the number of discarded vehicles.
Definition: ODMatrix.cpp:615
A storage for options typed value containers)
Definition: OptionsCont.h:89
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
Definition: OptionsCont.cpp:76
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
void addCallExample(const std::string &example, const std::string &desc)
Add a call example.
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:58
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition: OptionsIO.cpp:74
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
static void insertRandOptions(OptionsCont &oc)
Initialises the given options container with random number options.
Definition: RandHelper.cpp:59
static void initRandGlobal(SumoRNG *which=nullptr)
Reads the given random number options and initialises the random number generator in accordance.
Definition: RandHelper.cpp:87
Structure representing possible vehicle parameter.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
double departSpeed
(optional) The initial speed of the vehicle
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
double arrivalPos
(optional) The position the vehicle shall arrive on
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
static void close()
Closes all of an applications subsystems.
static bool checkOptions(OptionsCont &oc)
checks shared options and sets StdDefs
static void addConfigurationOptions(OptionsCont &oc)
Adds configuration options to the given container.
Definition: SystemFrame.cpp:38
static void addReportOptions(OptionsCont &oc)
Adds reporting options to the given container.
Definition: SystemFrame.cpp:67
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme, const std::string &routeValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:66
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:55
bool checkOptions()
void fillOptions()
int main(int argc, char **argv)