Eclipse SUMO - Simulation of Urban MObility
ROLoader.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-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 // Loader for networks and route imports
23 /****************************************************************************/
24 #include <config.h>
25 
26 #include <iostream>
27 #include <string>
28 #include <iomanip>
30 #include <utils/common/ToString.h>
35 #include <utils/xml/XMLSubSys.h>
39 #include "RONet.h"
40 #include "RONetHandler.h"
41 #include "ROLoader.h"
42 #include "ROLane.h"
43 #include "ROEdge.h"
44 #include "RORouteHandler.h"
45 
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 // ---------------------------------------------------------------------------
51 // ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
52 // ---------------------------------------------------------------------------
53 void
55  double val, double beg, double end) const {
56  ROEdge* e = myNet.getEdge(id);
57  if (e != nullptr) {
58  e->addTravelTime(val, beg, end);
59  } else {
60  if (id[0] != ':') {
61  if (OptionsCont::getOptions().getBool("ignore-errors")) {
62  WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
63  } else {
64  WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
65  }
66  }
67  }
68 }
69 
70 
71 // ---------------------------------------------------------------------------
72 // ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight - methods
73 // ---------------------------------------------------------------------------
74 void
76  double val, double beg, double end) const {
77  ROEdge* e = myNet.getEdge(id);
78  if (e != nullptr) {
79  e->addEffort(val, beg, end);
80  } else {
81  if (id[0] != ':') {
82  if (OptionsCont::getOptions().getBool("ignore-errors")) {
83  WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
84  } else {
85  WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
86  }
87  }
88  }
89 }
90 
91 
92 // ---------------------------------------------------------------------------
93 // ROLoader - methods
94 // ---------------------------------------------------------------------------
95 ROLoader::ROLoader(OptionsCont& oc, const bool emptyDestinationsAllowed, const bool logSteps) :
96  myOptions(oc),
97  myEmptyDestinationsAllowed(emptyDestinationsAllowed),
98  myLogSteps(logSteps),
99  myLoaders(oc.exists("unsorted-input") && oc.getBool("unsorted-input") ? 0 : DELTA_T) {
100 }
101 
102 
104 }
105 
106 
107 void
109  std::string file = myOptions.getString("net-file");
110  if (file == "") {
111  throw ProcessError(TL("Missing definition of network to load!"));
112  }
113  if (!FileHelpers::isReadable(file)) {
114  throw ProcessError(TLF("The network file '%' is not accessible.", file));
115  }
116  PROGRESS_BEGIN_MESSAGE(TL("Loading net"));
117  RONetHandler handler(toFill, eb, !myOptions.exists("no-internal-links") || myOptions.getBool("no-internal-links"),
118  myOptions.exists("weights.minor-penalty") ? myOptions.getFloat("weights.minor-penalty") : 0,
119  myOptions.exists("weights.tls-penalty") ? myOptions.getFloat("weights.tls-penalty") : 0,
120  myOptions.exists("weights.turnaround-penalty") ? myOptions.getFloat("weights.turnaround-penalty") : 0);
121  handler.setFileName(file);
122  if (!XMLSubSys::runParser(handler, file, true)) {
124  throw ProcessError();
125  } else {
127  }
128  if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
129  const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
130  for (auto& edgeIt : toFill.getEdgeMap()) {
131  edgeIt.second->cacheParamRestrictions(paramKeys);
132  }
133  }
134  if (!deprecatedVehicleClassesSeen.empty()) {
135  WRITE_WARNINGF(TL("Deprecated vehicle classes '%' in input network."), toString(deprecatedVehicleClassesSeen));
137  }
138  if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
139  std::vector<std::string> files = myOptions.getStringVector("additional-files");
140  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
141  if (!FileHelpers::isReadable(*fileIt)) {
142  throw ProcessError(TLF("The additional file '%' is not accessible.", *fileIt));
143  }
144  PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
145  handler.setFileName(*fileIt);
146  if (!XMLSubSys::runParser(handler, *fileIt)) {
148  throw ProcessError();
149  } else {
151  }
152  }
153  }
154  if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
155  // create a TAZ for every junction
156  toFill.addJunctionTaz(eb);
157  }
158  toFill.setBidiEdges(handler.getBidiMap());
159 }
160 
161 
162 void
164  // build loader
165  // load relevant elements from additional file
166  bool ok = openTypedRoutes("additional-files", net, true);
167  // load sumo routes, trips, and flows
168  ok &= openTypedRoutes("route-files", net);
169  // check
170  if (ok) {
172  if (!net.furtherStored()) {
173  if (MsgHandler::getErrorInstance()->wasInformed()) {
174  throw ProcessError();
175  } else {
176  const std::string error = "No route input specified or all routes were invalid.";
177  if (myOptions.getBool("ignore-errors")) {
178  WRITE_WARNING(error);
179  } else {
180  throw ProcessError(error);
181  }
182  }
183  }
184  // skip routes prior to the begin time
185  if (!myOptions.getBool("unsorted-input")) {
186  WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
187  }
188  }
189 }
190 
191 
192 void
193 ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
194  RONet& net, const RORouterProvider& provider) {
195  const SUMOTime absNo = end - start;
196  const bool endGiven = !OptionsCont::getOptions().isDefault("end");
197  // skip routes that begin before the simulation's begin
198  // loop till the end
199  const SUMOTime firstStep = myLoaders.getFirstLoadTime();
200  SUMOTime lastStep = firstStep;
201  SUMOTime time = MIN2(firstStep, end);
202  while (time <= end) {
203  writeStats(time, start, absNo, endGiven);
204  myLoaders.loadNext(time);
206  break;
207  }
208  lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
209  if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
210  break;
211  }
212  if (time < end && time > end - increment) {
213  time = end;
214  } else {
215  time += increment;
216  }
217  }
218  if (myLogSteps) {
219  WRITE_MESSAGEF(TL("Routes found between time steps % and %."), time2string(firstStep), time2string(lastStep));
220  }
221 }
222 
223 
224 bool
225 ROLoader::openTypedRoutes(const std::string& optionName,
226  RONet& net, const bool readAll) {
227  // check whether the current loader is wished
228  // and the file(s) can be used
229  if (!myOptions.isUsableFileList(optionName)) {
230  return !myOptions.isSet(optionName);
231  }
232  for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
233  try {
234  RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
235  if (readAll) {
236  if (!XMLSubSys::runParser(*handler, fileIt)) {
237  WRITE_ERRORF(TL("Loading of % failed."), fileIt);
238  return false;
239  }
240  delete handler;
241  } else {
242  myLoaders.add(new SUMORouteLoader(handler));
243  }
244  } catch (ProcessError& e) {
245  WRITE_ERRORF(TL("The loader for % from file '%' could not be initialised (%)."), optionName, fileIt, e.what());
246  return false;
247  }
248  }
249  return true;
250 }
251 
252 
253 bool
254 ROLoader::loadWeights(RONet& net, const std::string& optionName,
255  const std::string& measure, const bool useLanes, const bool boundariesOverride) {
256  // check whether the file exists
257  if (!myOptions.isUsableFileList(optionName)) {
258  return false;
259  }
260  // build and prepare the weights handler
261  std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
262  // travel time, first (always used)
264  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
265  // the measure to use, then
267  if (measure != "traveltime") {
268  std::string umeasure = measure;
269  if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
270  umeasure = measure + "_perVeh";
271  }
272  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
273  }
274  // set up handler
275  SAXWeightsHandler handler(retrieverDefs, "");
276  // go through files
277  std::vector<std::string> files = myOptions.getStringVector(optionName);
278  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
279  PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
280  if (XMLSubSys::runParser(handler, *fileIt)) {
282  } else {
283  WRITE_MESSAGE(TL("failed."));
284  return false;
285  }
286  }
287  // build edge-internal time lines
288  for (const auto& i : net.getEdgeMap()) {
289  i.second->buildTimeLines(measure, boundariesOverride);
290  }
291  return true;
292 }
293 
294 
295 void
296 ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
297  if (myLogSteps) {
298  if (endGiven) {
299  const double perc = (double)(time - start) / (double) absNo;
300  std::cout << "Reading up to time step: " + time2string(time) + " (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done) \r";
301  } else {
302  std::cout << "Reading up to time step: " + time2string(time) + "\r";
303  }
304  }
305 }
306 
307 
308 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:300
#define TLF(string,...)
Definition: MsgHandler.h:317
#define PROGRESS_FAILED_MESSAGE()
Definition: MsgHandler.h:303
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:299
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
std::set< std::string > deprecatedVehicleClassesSeen
T MIN2(T a, T b)
Definition: StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:51
void setFileName(const std::string &name)
Sets the current file name.
bool wasInformed() const
Returns the information whether any messages were added.
Definition: MsgHandler.cpp:416
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:92
A storage for options typed value containers)
Definition: OptionsCont.h:89
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)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
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 isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
Interface for building instances of router-edges.
A basic edge for routing applications.
Definition: ROEdge.h:70
void addEffort(double value, double timeBegin, double timeEnd)
Adds a weight value.
Definition: ROEdge.cpp:140
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition: ROEdge.cpp:147
Obtains edge travel times from a weights handler and stores them within the edges.
Definition: ROLoader.h:142
RONet & myNet
The network edges shall be obtained from.
Definition: ROLoader.h:163
void addEdgeWeight(const std::string &id, double val, double beg, double end) const
Adds a travel time for a given edge and time period.
Definition: ROLoader.cpp:54
Obtains edge weights from a weights handler and stores them within the edges.
Definition: ROLoader.h:111
void addEdgeWeight(const std::string &id, double val, double beg, double end) const
Adds an effort for a given edge and time period.
Definition: ROLoader.cpp:75
bool loadWeights(RONet &net, const std::string &optionName, const std::string &measure, const bool useLanes, const bool boundariesOverride)
Loads the net weights.
Definition: ROLoader.cpp:254
bool openTypedRoutes(const std::string &optionName, RONet &net, const bool readAll=false)
Opens route handler of the given type.
Definition: ROLoader.cpp:225
SUMORouteLoaderControl myLoaders
List of route loaders.
Definition: ROLoader.h:184
void processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment, RONet &net, const RORouterProvider &provider)
Loads routes from all previously build route loaders.
Definition: ROLoader.cpp:193
virtual ~ROLoader()
Destructor.
Definition: ROLoader.cpp:103
ROLoader(OptionsCont &oc, const bool emptyDestinationsAllowed, const bool logSteps)
Constructor.
Definition: ROLoader.cpp:95
virtual void loadNet(RONet &toFill, ROAbstractEdgeBuilder &eb)
Loads the network.
Definition: ROLoader.cpp:108
void writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven)
Definition: ROLoader.cpp:296
void openRoutes(RONet &net)
Builds and opens all route loaders.
Definition: ROLoader.cpp:163
const bool myLogSteps
Information whether the routing steps should be logged.
Definition: ROLoader.h:181
OptionsCont & myOptions
Options to use.
Definition: ROLoader.h:175
const bool myEmptyDestinationsAllowed
Information whether empty destinations are allowed.
Definition: ROLoader.h:178
The handler that parses a SUMO-network for its usage in a router.
Definition: RONetHandler.h:50
const std::map< ROEdge *, std::string > & getBidiMap() const
retrieve mapping of edges to bidi edges (must be resolved after loading network)
Definition: RONetHandler.h:64
The router's network representation.
Definition: RONet.h:62
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
bool furtherStored()
Returns the information whether further vehicles, persons or containers are stored.
Definition: RONet.cpp:787
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition: RONet.cpp:676
void setBidiEdges(const std::map< ROEdge *, std::string > &bidiMap)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:255
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:219
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition: RONet.h:422
Parser and container for routes during their loading.
Complete definition about what shall be retrieved and where to store it.
An XML-handler for network weights.
SUMOTime getFirstLoadTime() const
returns the timestamp of the first loaded vehicle or flow
bool haveAllLoaded() const
returns whether loading is completed
void loadNext(SUMOTime step)
loads the next routes up to and including the given time step
void add(SUMORouteLoader *loader)
add another loader
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:148