Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-2025 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>
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// ---------------------------------------------------------------------------
53void
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// ---------------------------------------------------------------------------
74void
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// ---------------------------------------------------------------------------
95ROLoader::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
105
106
107void
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 (!deprecatedVehicleClassesSeen.empty()) {
129 WRITE_WARNINGF(TL("Deprecated vehicle classes '%' in input network."), toString(deprecatedVehicleClassesSeen));
131 }
132 if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
133 std::vector<std::string> files = myOptions.getStringVector("additional-files");
134 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
135 if (!FileHelpers::isReadable(*fileIt)) {
136 throw ProcessError(TLF("The additional file '%' is not accessible.", *fileIt));
137 }
138 PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
139 handler.setFileName(*fileIt);
140 if (!XMLSubSys::runParser(handler, *fileIt)) {
142 throw ProcessError();
143 } else {
145 }
146 }
147 }
148 if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
149 // create a TAZ for every junction
150 toFill.addJunctionTaz(eb);
151 }
152 toFill.setBidiEdges(handler.getBidiMap());
153 if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
154 const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
155 for (auto& edgeIt : toFill.getEdgeMap()) {
156 edgeIt.second->cacheParamRestrictions(paramKeys);
157 }
158 }
159 if (toFill.hasRestrictions()) {
160 for (auto& edgeIt : toFill.getEdgeMap()) {
161 edgeIt.second->setRestrictions(toFill.getRestrictions(edgeIt.second->getType()));
162 }
163 }
164}
165
166
167void
169 // build loader
170 // load relevant elements from additional file
171 bool ok = openTypedRoutes("additional-files", net, true);
172 // load sumo routes, trips, and flows
173 ok &= openTypedRoutes("route-files", net);
174 // check
175 if (ok) {
177 if (!net.furtherStored()) {
178 if (MsgHandler::getErrorInstance()->wasInformed()) {
179 throw ProcessError();
180 } else {
181 const std::string error = "No route input specified or all routes were invalid.";
182 if (myOptions.getBool("ignore-errors")) {
183 WRITE_WARNING(error);
184 } else {
185 throw ProcessError(error);
186 }
187 }
188 }
189 // skip routes prior to the begin time
190 if (!myOptions.getBool("unsorted-input")) {
191 WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
192 }
193 }
194}
195
196
197void
198ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
199 RONet& net, const RORouterProvider& provider) {
200 const SUMOTime absNo = end - start;
201 const bool endGiven = !OptionsCont::getOptions().isDefault("end");
202 // skip routes that begin before the simulation's begin
203 // loop till the end
204 const SUMOTime firstStep = myLoaders.getFirstLoadTime();
205 SUMOTime lastStep = firstStep;
206 SUMOTime time = MIN2(firstStep, end);
207 while (time <= end) {
208 writeStats(time, start, absNo, endGiven);
209 myLoaders.loadNext(time);
211 break;
212 }
213 lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
214 if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
215 break;
216 }
217 if (time < end && time > end - increment) {
218 time = end;
219 } else {
220 time += increment;
221 }
222 }
223 if (myLogSteps) {
224 WRITE_MESSAGEF(TL("Routes found between time steps % and %."), time2string(firstStep), time2string(lastStep));
225 }
226}
227
228
229bool
230ROLoader::openTypedRoutes(const std::string& optionName,
231 RONet& net, const bool readAll) {
232 // check whether the current loader is wished
233 // and the file(s) can be used
234 if (!myOptions.isUsableFileList(optionName)) {
235 return !myOptions.isSet(optionName);
236 }
237 for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
238 try {
239 RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
240 if (readAll) {
241 if (!XMLSubSys::runParser(*handler, fileIt)) {
242 WRITE_ERRORF(TL("Loading of % failed."), fileIt);
243 return false;
244 }
245 delete handler;
246 } else {
247 myLoaders.add(new SUMORouteLoader(handler));
248 }
249 } catch (ProcessError& e) {
250 WRITE_ERRORF(TL("The loader for % from file '%' could not be initialised (%)."), optionName, fileIt, e.what());
251 return false;
252 }
253 }
254 return true;
255}
256
257
258bool
259ROLoader::loadWeights(RONet& net, const std::string& optionName,
260 const std::string& measure, const bool useLanes, const bool boundariesOverride) {
261 // check whether the file exists
262 if (!myOptions.isUsableFileList(optionName)) {
263 return false;
264 }
265 // build and prepare the weights handler
266 std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
267 // travel time, first (always used)
269 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
270 // the measure to use, then
272 if (measure != "traveltime") {
273 std::string umeasure = measure;
274 if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
275 umeasure = measure + "_perVeh";
276 }
277 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
278 }
279 // set up handler
280 SAXWeightsHandler handler(retrieverDefs, "");
281 // go through files
282 std::vector<std::string> files = myOptions.getStringVector(optionName);
283 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
284 PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
285 if (XMLSubSys::runParser(handler, *fileIt)) {
287 } else {
288 WRITE_MESSAGE(TL("failed."));
289 return false;
290 }
291 }
292 // build edge-internal time lines
293 for (const auto& i : net.getEdgeMap()) {
294 i.second->buildTimeLines(measure, boundariesOverride);
295 }
296 return true;
297}
298
299
300void
301ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
302 if (myLogSteps) {
303 if (endGiven) {
304 const double perc = (double)(time - start) / (double) absNo;
305 std::cout << "Reading up to time step: " + time2string(time) + " (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done) \r";
306 } else {
307 std::cout << "Reading up to time step: " + time2string(time) + "\r";
308 }
309 }
310}
311
314 auto loader = myLoaders.getFirstLoader();
315 if (loader != nullptr) {
316 return loader->getRouteHandler();
317 } else {
318 return nullptr;
319 }
320}
321/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:290
#define WRITE_ERRORF(...)
Definition MsgHandler.h:297
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:289
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:292
#define TLF(string,...)
Definition MsgHandler.h:307
#define PROGRESS_FAILED_MESSAGE()
Definition MsgHandler.h:295
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:291
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:91
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.
void setFileName(const std::string &name)
Sets the current file name.
bool wasInformed() const
Returns the information whether any messages were added.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
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.
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:72
void addEffort(double value, double timeBegin, double timeEnd)
Adds a weight value.
Definition ROEdge.cpp:163
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition ROEdge.cpp:170
Obtains edge travel times from a weights handler and stores them within the edges.
Definition ROLoader.h:145
RONet & myNet
The network edges shall be obtained from.
Definition ROLoader.h:166
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:114
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:259
bool openTypedRoutes(const std::string &optionName, RONet &net, const bool readAll=false)
Opens route handler of the given type.
Definition ROLoader.cpp:230
SUMORouteLoaderControl myLoaders
List of route loaders.
Definition ROLoader.h:187
SUMORouteHandler * getRouteHandler()
Definition ROLoader.cpp:313
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:198
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:301
void openRoutes(RONet &net)
Builds and opens all route loaders.
Definition ROLoader.cpp:168
const bool myLogSteps
Information whether the routing steps should be logged.
Definition ROLoader.h:184
OptionsCont & myOptions
Options to use.
Definition ROLoader.h:178
const bool myEmptyDestinationsAllowed
Information whether empty destinations are allowed.
Definition ROLoader.h:181
The handler that parses a SUMO-network for its usage in a router.
The router's network representation.
Definition RONet.h:63
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition RONet.cpp:150
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition RONet.h:161
bool furtherStored()
Returns the information whether further vehicles, persons or containers are stored.
Definition RONet.cpp:789
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:426
bool hasRestrictions() const
Definition RONet.h:97
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.
Parser for routes during their loading.
SUMOTime getFirstLoadTime() const
returns the timestamp of the first loaded vehicle or flow
SUMORouteLoader * getFirstLoader() const
return a route loader
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
SUMORouteHandler * getRouteHandler()
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.