SUMO - Simulation of Urban MObility
dfrouter_main.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // Main for the DFROUTER
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
15 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #ifdef HAVE_VERSION_H
37 #include <version.h>
38 #endif
39 
40 #include <xercesc/sax/SAXException.hpp>
41 #include <xercesc/sax/SAXParseException.hpp>
43 #include <iostream>
44 #include <string>
45 #include <limits.h>
46 #include <ctime>
47 #include <router/ROLoader.h>
48 #include <router/RONet.h>
49 #include "RODFEdgeBuilder.h"
50 #include <router/ROFrame.h>
52 #include <utils/options/Option.h>
57 #include <utils/common/ToString.h>
58 #include <utils/xml/XMLSubSys.h>
59 #include "RODFFrame.h"
60 #include "RODFNet.h"
61 #include "RODFEdge.h"
62 #include "RODFDetector.h"
63 #include "RODFDetectorHandler.h"
64 #include "RODFRouteCont.h"
65 #include "RODFDetectorFlow.h"
66 #include "RODFDetFlowLoader.h"
69 
70 
71 // ===========================================================================
72 // functions
73 // ===========================================================================
74 /* -------------------------------------------------------------------------
75  * data processing methods
76  * ----------------------------------------------------------------------- */
77 void
78 readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
79  if (!oc.isSet("detector-files")) {
80  throw ProcessError("No detector file given (use --detector-files <FILE>).");
81  }
82  // read definitions stored in XML-format
83  std::vector<std::string> files = oc.getStringVector("detector-files");
84  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
85  if (!FileHelpers::isReadable(*fileIt)) {
86  throw ProcessError("Could not open detector file '" + *fileIt + "'");
87  }
88  PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
89  RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
90  if (XMLSubSys::runParser(handler, *fileIt)) {
92  } else {
94  throw ProcessError();
95  }
96  }
97  if (detectors.getDetectors().empty()) {
98  throw ProcessError("No detectors found.");
99  }
100 }
101 
102 
103 void
105  if (!oc.isSet("measure-files")) {
106  // ok, not given, return an empty container
107  return;
108  }
109  // check whether the file exists
110  std::vector<std::string> files = oc.getStringVector("measure-files");
111  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
112  if (!FileHelpers::isReadable(*fileIt)) {
113  throw ProcessError("The measure-file '" + *fileIt + "' can not be opened.");
114  }
115  // parse
116  PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
117  RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")),
118  string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor")));
119  dfl.read(*fileIt);
121  }
122 }
123 
124 
125 void
127  if (oc.getBool("print-absolute-flows")) {
128  flows.printAbsolute();
129  }
130 
131  // if a network was loaded... (mode1)
132  if (optNet != 0) {
133  if (oc.getBool("remove-empty-detectors")) {
134  PROGRESS_BEGIN_MESSAGE("Removing empty detectors");
135  optNet->removeEmptyDetectors(detectors, flows);
137  } else if (oc.getBool("report-empty-detectors")) {
138  PROGRESS_BEGIN_MESSAGE("Scanning for empty detectors");
139  optNet->reportEmptyDetectors(detectors, flows);
141  }
142  // compute the detector types (optionally)
143  if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
144  optNet->computeTypes(detectors, oc.getBool("strict-sources"));
145  }
146  std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
147  for (; i != detectors.getDetectors().end(); ++i) {
148  if ((*i)->getType() == SOURCE_DETECTOR) {
149  break;
150  }
151  }
152  if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
153  throw ProcessError("No source detectors found.");
154  }
155  // compute routes between the detectors (optionally)
156  if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
157  PROGRESS_BEGIN_MESSAGE("Computing routes");
158  optNet->buildRoutes(detectors,
159  oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
160  !oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
162  }
163  }
164 
165  // check
166  // whether the detectors are valid
167  if (!detectors.detectorsHaveCompleteTypes()) {
168  throw ProcessError("The detector types are not defined; use in combination with a network");
169  }
170  // whether the detectors have routes
171  if (!detectors.detectorsHaveRoutes()) {
172  throw ProcessError("The emitters have no routes; use in combination with a network");
173  }
174 
175  // save the detectors if wished
176  if (oc.isSet("detector-output")) {
177  detectors.save(oc.getString("detector-output"));
178  }
179  // save their positions as POIs if wished
180  if (oc.isSet("detectors-poi-output")) {
181  detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
182  }
183 
184  // save the routes file if it was changed or it's wished
185  if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
186  detectors.saveRoutes(oc.getString("routes-output"));
187  }
188 
189  // guess flows if wished
190  if (oc.getBool("guess-empty-flows")) {
191  optNet->buildDetectorDependencies(detectors);
192  detectors.guessEmptyFlows(flows);
193  }
194 
195  const SUMOTime begin = string2time(oc.getString("begin"));
196  const SUMOTime end = string2time(oc.getString("end"));
197  const SUMOTime step = string2time(oc.getString("time-step"));
198 
199  // save emitters if wished
200  if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
201  optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!!
202  if (oc.getBool("revalidate-flows")) {
203  PROGRESS_BEGIN_MESSAGE("Rechecking loaded flows");
204  optNet->revalidateFlows(detectors, flows, begin, end, step);
206  }
207  if (oc.isSet("emitters-output")) {
208  PROGRESS_BEGIN_MESSAGE("Writing emitters");
209  detectors.writeEmitters(oc.getString("emitters-output"), flows,
210  begin, end, step,
211  *optNet,
212  oc.getBool("calibrator-output"),
213  oc.getBool("include-unused-routes"),
214  oc.getFloat("scale"),
215 // oc.getInt("max-search-depth"),
216  oc.getBool("emissions-only"));
218  }
219  if (oc.isSet("emitters-poi-output")) {
220  PROGRESS_BEGIN_MESSAGE("Writing emitter pois");
221  detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
223  }
224  }
225  // save end speed trigger if wished
226  if (oc.isSet("variable-speed-sign-output")) {
227  PROGRESS_BEGIN_MESSAGE("Writing speed triggers");
228  detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
229  begin, end, step);
231  }
232  // save checking detectors if wished
233  if (oc.isSet("validation-output")) {
234  PROGRESS_BEGIN_MESSAGE("Writing validation detectors");
235  detectors.writeValidationDetectors(oc.getString("validation-output"),
236  oc.getBool("validation-output.add-sources"), true, true); // !!!
238  }
239  // build global rerouter on end if wished
240  if (oc.isSet("end-reroute-output")) {
241  PROGRESS_BEGIN_MESSAGE("Writing highway end rerouter");
242  detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!!
244  }
245  /*
246  // save the insertion definitions
247  if(oc.isSet("flow-definitions")) {
248  buildVehicleEmissions(oc.getString("flow-definitions"));
249  }
250  */
251  //
252 }
253 
254 
255 /* -------------------------------------------------------------------------
256  * main
257  * ----------------------------------------------------------------------- */
258 int
259 main(int argc, char** argv) {
261  // give some application descriptions
262  oc.setApplicationDescription("Builds vehicle routes for SUMO using detector values.");
263  oc.setApplicationName("dfrouter", "SUMO dfrouter Version " VERSION_STRING);
264  int ret = 0;
265  RODFNet* net = 0;
266  RODFDetectorCon* detectors = 0;
267  RODFDetectorFlows* flows = 0;
268  try {
269  // initialise the application system (messaging, xml, options)
270  XMLSubSys::init();
272  OptionsIO::setArgs(argc, argv);
274  if (oc.processMetaOptions(argc < 2)) {
276  return 0;
277  }
278  XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
280  if (!RODFFrame::checkOptions()) {
281  throw ProcessError();
282  }
284  // load data
285  ROLoader loader(oc, false, !oc.getBool("no-step-log"));
286  net = new RODFNet(oc.getBool("highway-mode"));
287  RODFEdgeBuilder builder;
288  loader.loadNet(*net, builder);
289  net->buildApproachList();
290  // load detectors
291  detectors = new RODFDetectorCon();
292  readDetectors(*detectors, oc, net);
293  // load detector values
294  flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
295  string2time(oc.getString("time-step")));
296  readDetectorFlows(*flows, oc, *detectors);
297  // build routes
298  startComputation(net, *flows, *detectors, oc);
299  } catch (const ProcessError& e) {
300  if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
301  WRITE_ERROR(e.what());
302  }
303  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
304  ret = 1;
305 #ifndef _DEBUG
306  } catch (const std::exception& e) {
307  if (std::string(e.what()) != std::string("")) {
308  WRITE_ERROR(e.what());
309  }
310  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
311  ret = 1;
312  } catch (...) {
313  MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
314  ret = 1;
315 #endif
316  }
317  delete net;
318  delete flows;
319  delete detectors;
321  if (ret == 0) {
322  std::cout << "Success." << std::endl;
323  }
324  return ret;
325 }
326 
327 
328 
329 /****************************************************************************/
330 
void revalidateFlows(const RODFDetectorCon &detectors, RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
Definition: RODFNet.cpp:576
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:54
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:76
bool detectorsHaveRoutes() const
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition: OptionsIO.cpp:82
void readDetectors(RODFDetectorCon &detectors, OptionsCont &oc, RODFNet *optNet)
void saveRoutes(const std::string &file) const
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:54
void save(const std::string &file) const
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:65
A source detector.
Definition: RODFDetector.h:77
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
void computeTypes(RODFDetectorCon &dets, bool sourcesStrict) const
Definition: RODFNet.cpp:114
void reportEmptyDetectors(RODFDetectorCon &detectors, RODFDetectorFlows &flows)
Definition: RODFNet.cpp:613
const std::vector< RODFDetector * > & getDetectors() const
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void writeSpeedTrigger(const RODFNet *const net, const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:110
static void close()
Closes all of an applications subsystems.
void printAbsolute() const
A container for flows.
A container for RODFDetectors.
Definition: RODFDetector.h:228
A loader for detector flows.
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:62
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
static void initRandGlobal(MTRand *which=0)
Reads the given random number options and initialises the random number generator in accordance...
Definition: RandHelper.cpp:64
#define PROGRESS_FAILED_MESSAGE()
Definition: MsgHandler.h:205
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void read(const std::string &file)
Reads the given file assuming it contains detector values.
The data loader.
Definition: ROLoader.h:63
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
A DFROUTER-network.
Definition: RODFNet.h:52
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:47
Interface for building instances of dfrouter-edges.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
void writeValidationDetectors(const std::string &file, bool includeSources, bool singleFile, bool friendly)
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:202
void readDetectorFlows(RODFDetectorFlows &flows, OptionsCont &oc, RODFDetectorCon &dc)
void saveAsPOIs(const std::string &file) const
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
void writeEmitters(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, bool writeCalibrators, bool includeUnusedRoutes, double scale, bool insertionsOnly)
#define VERSION_STRING
Definition: config.h:210
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void buildRoutes(RODFDetectorCon &det, bool keepUnfoundEnds, bool includeInBetween, bool keepShortestOnly, int maxFollowingLength) const
Definition: RODFNet.cpp:346
void startComputation(RODFNet *optNet, RODFDetectorFlows &flows, RODFDetectorCon &detectors, OptionsCont &oc)
bool detectorsHaveCompleteTypes() const
SAX2-Handler for loading DFROUTER-detector definitions.
void buildEdgeFlowMap(const RODFDetectorFlows &flows, const RODFDetectorCon &detectors, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
Definition: RODFNet.cpp:933
void guessEmptyFlows(RODFDetectorFlows &flows)
void buildDetectorDependencies(RODFDetectorCon &detectors)
Definition: RODFNet.cpp:1031
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:85
A storage for options typed value containers)
Definition: OptionsCont.h:99
static bool checkOptions()
Checks set options from the OptionsCont-singleton for being valid for usage within dfrouter...
Definition: RODFFrame.cpp:262
void writeEmitterPOIs(const std::string &file, const RODFDetectorFlows &flows)
long long int SUMOTime
Definition: TraCIDefs.h:52
void writeEndRerouterDetectors(const std::string &file)
void removeEmptyDetectors(RODFDetectorCon &detectors, RODFDetectorFlows &flows)
Definition: RODFNet.cpp:590
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:203
static void initOutputOptions()
Definition: MsgHandler.cpp:193
int main(int argc, char **argv)
static void fillOptions()
Inserts options used by dfrouter into the OptionsCont-singleton.
Definition: RODFFrame.cpp:54
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.