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-2022 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>
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// ---------------------------------------------------------------------------
57void
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// ---------------------------------------------------------------------------
78void
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// ---------------------------------------------------------------------------
99ROLoader::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
111void
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
164void
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
194void
195ROLoader::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);
211 if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
212 break;
213 }
214 if (time < end && time > end - increment) {
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
226bool
227ROLoader::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
255bool
256ROLoader::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(TL("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
297void
298ROLoader::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/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:267
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:270
#define PROGRESS_FAILED_MESSAGE()
Definition: MsgHandler.h:273
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:269
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
std::set< std::string > deprecatedVehicleClassesSeen
T MIN2(T a, T b)
Definition: StdDefs.h:71
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:321
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:79
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:59
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: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:753
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition: RONet.cpp:642
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:244
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:208
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition: RONet.h:409
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:137