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.org/sumo
3 // Copyright (C) 2001-2020 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>
29 #include <xercesc/parsers/SAXParser.hpp>
30 #include <xercesc/util/PlatformUtils.hpp>
31 #include <xercesc/util/TransService.hpp>
32 #include <xercesc/sax2/SAX2XMLReader.hpp>
34 #include <utils/common/ToString.h>
39 #include <utils/xml/XMLSubSys.h>
43 #include "RONet.h"
44 #include "RONetHandler.h"
45 #include "ROLoader.h"
46 #include "ROLane.h"
47 #include "ROEdge.h"
48 #include "RORouteHandler.h"
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 // ---------------------------------------------------------------------------
55 // ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
56 // ---------------------------------------------------------------------------
57 void
59  double val, double beg, double end) const {
60  ROEdge* e = myNet.getEdge(id);
61  if (e != nullptr) {
62  e->addTravelTime(val, beg, end);
63  } else {
64  if (id[0] != ':') {
65  if (OptionsCont::getOptions().getBool("ignore-errors")) {
66  WRITE_WARNING("Trying to set a weight for the unknown edge '" + id + "'.");
67  } else {
68  WRITE_ERROR("Trying to set a weight for the unknown edge '" + id + "'.");
69  }
70  }
71  }
72 }
73 
74 
75 // ---------------------------------------------------------------------------
76 // ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight - methods
77 // ---------------------------------------------------------------------------
78 void
80  double val, double beg, double end) const {
81  ROEdge* e = myNet.getEdge(id);
82  if (e != nullptr) {
83  e->addEffort(val, beg, end);
84  } else {
85  if (id[0] != ':') {
86  if (OptionsCont::getOptions().getBool("ignore-errors")) {
87  WRITE_WARNING("Trying to set a weight for the unknown edge '" + id + "'.");
88  } else {
89  WRITE_ERROR("Trying to set a weight for the unknown edge '" + id + "'.");
90  }
91  }
92  }
93 }
94 
95 
96 // ---------------------------------------------------------------------------
97 // ROLoader - methods
98 // ---------------------------------------------------------------------------
99 ROLoader::ROLoader(OptionsCont& oc, const bool emptyDestinationsAllowed, const bool logSteps) :
100  myOptions(oc),
101  myEmptyDestinationsAllowed(emptyDestinationsAllowed),
102  myLogSteps(logSteps),
103  myLoaders(oc.exists("unsorted-input") && oc.getBool("unsorted-input") ? 0 : DELTA_T) {
104 }
105 
106 
108 }
109 
110 
111 void
113  std::string file = myOptions.getString("net-file");
114  if (file == "") {
115  throw ProcessError("Missing definition of network to load!");
116  }
117  if (!FileHelpers::isReadable(file)) {
118  throw ProcessError("The network file '" + file + "' is not accessible.");
119  }
120  PROGRESS_BEGIN_MESSAGE("Loading net");
121  RONetHandler handler(toFill, eb, !myOptions.exists("no-internal-links") || myOptions.getBool("no-internal-links"),
122  myOptions.exists("weights.minor-penalty") ? myOptions.getFloat("weights.minor-penalty") : 0);
123  handler.setFileName(file);
124  if (!XMLSubSys::runParser(handler, file, true)) {
126  throw ProcessError();
127  } else {
129  }
130  if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
131  const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
132  for (auto& edgeIt : toFill.getEdgeMap()) {
133  edgeIt.second->cacheParamRestrictions(paramKeys);
134  }
135  }
136  if (!deprecatedVehicleClassesSeen.empty()) {
137  WRITE_WARNING("Deprecated vehicle classes '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
139  }
140  if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
141  std::vector<std::string> files = myOptions.getStringVector("additional-files");
142  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
143  if (!FileHelpers::isReadable(*fileIt)) {
144  throw ProcessError("The additional file '" + *fileIt + "' is not accessible.");
145  }
146  PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
147  handler.setFileName(*fileIt);
148  if (!XMLSubSys::runParser(handler, *fileIt)) {
150  throw ProcessError();
151  } else {
153  }
154  }
155  }
156  if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
157  // create a TAZ for every junction
158  toFill.addJunctionTaz(eb);
159  }
160  toFill.setBidiEdges(handler.getBidiMap());
161 }
162 
163 
164 void
166  // build loader
167  // load relevant elements from additional file
168  bool ok = openTypedRoutes("additional-files", net, true);
169  // load sumo routes, trips, and flows
170  ok &= openTypedRoutes("route-files", net);
171  // check
172  if (ok) {
174  if (!net.furtherStored()) {
175  if (MsgHandler::getErrorInstance()->wasInformed()) {
176  throw ProcessError();
177  } else {
178  const std::string error = "No route input specified or all routes were invalid.";
179  if (myOptions.getBool("ignore-errors")) {
180  WRITE_WARNING(error);
181  } else {
182  throw ProcessError(error);
183  }
184  }
185  }
186  // skip routes prior to the begin time
187  if (!myOptions.getBool("unsorted-input")) {
188  WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
189  }
190  }
191 }
192 
193 
194 void
195 ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
196  RONet& net, const RORouterProvider& provider) {
197  const SUMOTime absNo = end - start;
198  const bool endGiven = !OptionsCont::getOptions().isDefault("end");
199  // skip routes that begin before the simulation's begin
200  // loop till the end
201  const SUMOTime firstStep = myLoaders.getFirstLoadTime();
202  SUMOTime lastStep = firstStep;
203  SUMOTime time = MIN2(firstStep, end);
204  while (time <= end) {
205  writeStats(time, start, absNo, endGiven);
206  myLoaders.loadNext(time);
208  break;
209  }
210  lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
212  break;
213  }
214  if (time < end && time + increment > end) {
215  time = end;
216  } else {
217  time += increment;
218  }
219  }
220  if (myLogSteps) {
221  WRITE_MESSAGE("Routes found between time steps " + time2string(firstStep) + " and " + time2string(lastStep) + ".");
222  }
223 }
224 
225 
226 bool
227 ROLoader::openTypedRoutes(const std::string& optionName,
228  RONet& net, const bool readAll) {
229  // check whether the current loader is wished
230  // and the file(s) can be used
231  if (!myOptions.isUsableFileList(optionName)) {
232  return !myOptions.isSet(optionName);
233  }
234  for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
235  try {
236  RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
237  if (readAll) {
238  if (!XMLSubSys::runParser(*handler, fileIt)) {
239  WRITE_ERROR("Loading of " + fileIt + " failed.");
240  return false;
241  }
242  delete handler;
243  } else {
244  myLoaders.add(new SUMORouteLoader(handler));
245  }
246  } catch (ProcessError& e) {
247  WRITE_ERROR("The loader for " + optionName + " from file '" + fileIt + "' could not be initialised (" + e.what() + ").");
248  return false;
249  }
250  }
251  return true;
252 }
253 
254 
255 bool
256 ROLoader::loadWeights(RONet& net, const std::string& optionName,
257  const std::string& measure, const bool useLanes, const bool boundariesOverride) {
258  // check whether the file exists
259  if (!myOptions.isUsableFileList(optionName)) {
260  return false;
261  }
262  // build and prepare the weights handler
263  std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
264  // travel time, first (always used)
266  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
267  // the measure to use, then
269  if (measure != "traveltime") {
270  std::string umeasure = measure;
271  if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
272  umeasure = measure + "_perVeh";
273  }
274  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
275  }
276  // set up handler
277  SAXWeightsHandler handler(retrieverDefs, "");
278  // go through files
279  std::vector<std::string> files = myOptions.getStringVector(optionName);
280  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
281  PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
282  if (XMLSubSys::runParser(handler, *fileIt)) {
284  } else {
285  WRITE_MESSAGE("failed.");
286  return false;
287  }
288  }
289  // build edge-internal time lines
290  for (const auto& i : net.getEdgeMap()) {
291  i.second->buildTimeLines(measure, boundariesOverride);
292  }
293  return true;
294 }
295 
296 
297 void
298 ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
299  if (myLogSteps) {
300  if (endGiven) {
301  const double perc = (double)(time - start) / (double) absNo;
302  std::cout << "Reading up to time step: " + time2string(time) + " (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done) \r";
303  } else {
304  std::cout << "Reading up to time step: " + time2string(time) + "\r";
305  }
306  }
307 }
308 
309 
310 /****************************************************************************/
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:278
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:280
#define PROGRESS_FAILED_MESSAGE()
Definition: MsgHandler.h:283
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:279
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
long long int SUMOTime
Definition: SUMOTime.h:31
std::set< std::string > deprecatedVehicleClassesSeen
T MIN2(T a, T b)
Definition: StdDefs.h:73
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:48
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:281
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
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:58
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:136
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition: ROEdge.cpp:143
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:58
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:79
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:256
bool openTypedRoutes(const std::string &optionName, RONet &net, const bool readAll=false)
Opens route handler of the given type.
Definition: ROLoader.cpp:227
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:195
virtual ~ROLoader()
Destructor.
Definition: ROLoader.cpp:107
ROLoader(OptionsCont &oc, const bool emptyDestinationsAllowed, const bool logSteps)
Constructor.
Definition: ROLoader.cpp:99
virtual void loadNet(RONet &toFill, ROAbstractEdgeBuilder &eb)
Loads the network.
Definition: ROLoader.cpp:112
void writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven)
Definition: ROLoader.cpp:298
void openRoutes(RONet &net)
Builds and opens all route loaders.
Definition: ROLoader.cpp:165
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:704
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition: RONet.cpp:596
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:234
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:201
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition: RONet.h:399
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)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:148