Eclipse SUMO - Simulation of Urban MObility
SUMORouteHandler.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-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Parser for routes during their loading
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <string>
28 #include <map>
29 #include <vector>
31 #include <utils/common/ToString.h>
39 #include <utils/xml/XMLSubSys.h>
40 #include "SUMORouteHandler.h"
41 
42 
43 // ===========================================================================
44 // method definitions
45 // ===========================================================================
46 SUMORouteHandler::SUMORouteHandler(const std::string& file, const std::string& expectedRoot, const bool hardFail) :
47  SUMOSAXHandler(file, XMLSubSys::isValidating() ? expectedRoot : ""),
48  myHardFail(hardFail),
49  myVehicleParameter(nullptr),
50  myLastDepart(-1),
51  myActiveRouteColor(nullptr),
52  myCurrentCosts(0.),
53  myCurrentVType(nullptr),
54  myBeginDefault(string2time(OptionsCont::getOptions().getString("begin"))),
55  myEndDefault(string2time(OptionsCont::getOptions().getString("end"))),
56  myFirstDepart(-1),
57  myInsertStopEdgesAt(-1) {
58 }
59 
60 
62  delete myCurrentVType;
63 }
64 
65 
66 bool
70  WRITE_WARNING("Route file should be sorted by departure time, ignoring '" + myVehicleParameter->id + "'!");
71  return false;
72  }
73  }
74  return true;
75 }
76 
77 
78 void
80  // register only non public transport to parse all public transport lines in advance
83  if (myFirstDepart == -1) {
85  }
86  }
87  // else: we don't know when this vehicle will depart. keep the previous known depart time
88 }
89 
90 
91 void
93  switch (element) {
94  case SUMO_TAG_VEHICLE:
95  // delete if myVehicleParameter isn't null
96  if (myVehicleParameter) {
97  delete myVehicleParameter;
98  }
99  // create a new vehicle
101  break;
102  case SUMO_TAG_PERSON:
103  // delete if myVehicleParameter isn't null
104  if (myVehicleParameter) {
105  delete myVehicleParameter;
106  }
107  // create a new person
109  addPerson(attrs);
110  break;
111  case SUMO_TAG_CONTAINER:
112  // delete if myVehicleParameter isn't null
113  if (myVehicleParameter) {
114  delete myVehicleParameter;
115  }
116  // create a new container
118  addContainer(attrs);
119  break;
120  case SUMO_TAG_FLOW:
121  // delete if myVehicleParameter isn't null
122  if (myVehicleParameter) {
123  delete myVehicleParameter;
124  }
125  // parse vehicle parameters
127  // check if myVehicleParameter was sucesfully created
128  if (myVehicleParameter) {
129  // open a flow (using openTrip function)
130  openTrip(attrs);
131  }
132  break;
133  case SUMO_TAG_PERSONFLOW:
134  // delete if myVehicleParameter isn't null
135  if (myVehicleParameter) {
136  delete myVehicleParameter;
137  }
138  // create a new flow
140  break;
141  case SUMO_TAG_VTYPE:
142  // delete if myCurrentVType isn't null
143  if (myCurrentVType != nullptr) {
144  delete myCurrentVType;
145  myCurrentVType = nullptr;
146  }
147  // create a new vType
149  break;
152  break;
153  case SUMO_TAG_ROUTE:
154  openRoute(attrs);
155  break;
157  openRouteDistribution(attrs);
158  break;
159  case SUMO_TAG_STOP:
160  addStop(attrs);
161  break;
162  case SUMO_TAG_TRIP: {
163  // delete if myVehicleParameter isn't null
164  if (myVehicleParameter) {
165  delete myVehicleParameter;
166  }
167  // parse vehicle parameters
169  // check if myVehicleParameter was sucesfully created
170  if (myVehicleParameter) {
173  // open trip
174  openTrip(attrs);
175  }
176  break;
177  }
178  case SUMO_TAG_PERSONTRIP:
179  case SUMO_TAG_WALK:
181  addWalk(attrs);
182  } else {
183  addPersonTrip(attrs);
184  }
185  break;
186  case SUMO_TAG_INTERVAL: {
187  bool ok;
189  myEndDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok);
190  break;
191  }
192  case SUMO_TAG_RIDE:
193  addRide(attrs);
194  break;
195  case SUMO_TAG_TRANSPORT:
196  addTransport(attrs);
197  break;
198  case SUMO_TAG_TRANSHIP:
199  addTranship(attrs);
200  break;
201  case SUMO_TAG_PARAM:
202  addParam(attrs);
203  break;
204  default:
205  // parse embedded car following model information
206  if (myCurrentVType != nullptr) {
207  WRITE_WARNING("Defining car following parameters in a nested element is deprecated in vType '" + myCurrentVType->id + "', use attributes instead!");
209  if (myHardFail) {
210  throw ProcessError("Invalid parsing embedded VType");
211  } else {
212  WRITE_ERROR("Invalid parsing embedded VType");
213  }
214  }
215  }
216  break;
217  }
218 }
219 
220 
221 void
223  switch (element) {
224  case SUMO_TAG_ROUTE:
225  closeRoute();
226  break;
227  case SUMO_TAG_VTYPE:
228  closeVType();
229  delete myCurrentVType;
230  myCurrentVType = nullptr;
231  break;
232  case SUMO_TAG_PERSON:
233  closePerson();
234  delete myVehicleParameter;
235  myVehicleParameter = nullptr;
236  break;
237  case SUMO_TAG_PERSONFLOW:
238  closePersonFlow();
239  delete myVehicleParameter;
240  myVehicleParameter = nullptr;
241  break;
242  case SUMO_TAG_CONTAINER:
243  closeContainer();
244  delete myVehicleParameter;
245  myVehicleParameter = nullptr;
246  break;
247  case SUMO_TAG_VEHICLE:
248  if (myVehicleParameter == nullptr) {
249  break;
250  }
252  myVehicleParameter->repetitionNumber++; // for backwards compatibility
253  // it is a flow, thus no break here
254  FALLTHROUGH;
255  } else {
256  closeVehicle();
257  delete myVehicleParameter;
258  myVehicleParameter = nullptr;
259  break;
260  }
261  case SUMO_TAG_FLOW:
262  closeFlow();
263  delete myVehicleParameter;
264  myVehicleParameter = nullptr;
265  myInsertStopEdgesAt = -1;
266  break;
267  case SUMO_TAG_TRIP:
268  closeTrip();
269  delete myVehicleParameter;
270  myVehicleParameter = nullptr;
271  myInsertStopEdgesAt = -1;
272  break;
275  break;
278  break;
279  case SUMO_TAG_INTERVAL:
280  myBeginDefault = string2time(OptionsCont::getOptions().getString("begin"));
281  myEndDefault = string2time(OptionsCont::getOptions().getString("end"));
282  break;
283  default:
284  break;
285  }
286 }
287 
288 
289 bool
290 SUMORouteHandler::checkStopPos(double& startPos, double& endPos, const double laneLength,
291  const double minLength, const bool friendlyPos) {
292  if (minLength > laneLength) {
293  return false;
294  }
295  if (startPos < 0) {
296  startPos += laneLength;
297  }
298  if (endPos < 0) {
299  endPos += laneLength;
300  }
301  if (endPos < minLength || endPos > laneLength) {
302  if (!friendlyPos) {
303  return false;
304  }
305  if (endPos < minLength) {
306  endPos = minLength;
307  }
308  if (endPos > laneLength) {
309  endPos = laneLength;
310  }
311  }
312  if (startPos < 0 || startPos > endPos - minLength) {
313  if (!friendlyPos) {
314  return false;
315  }
316  if (startPos < 0) {
317  startPos = 0;
318  }
319  if (startPos > endPos - minLength) {
320  startPos = endPos - minLength;
321  }
322  }
323  return true;
324 }
325 
326 
327 SUMOTime
329  return myFirstDepart;
330 }
331 
332 
333 SUMOTime
335  return myLastDepart;
336 }
337 
338 
339 void
341  bool ok = true;
342  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
343  // circumventing empty string test
344  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
345  // add parameter in current created element, or in myLoadedParameterised
346  if (myVehicleParameter != nullptr) {
347  myVehicleParameter->setParameter(key, val);
348  } else if (myCurrentVType != nullptr) {
349  myCurrentVType->setParameter(key, val);
350  } else {
352  }
353 }
354 
355 
356 bool
357 SUMORouteHandler::parseStop(SUMOVehicleParameter::Stop& stop, const SUMOSAXAttributes& attrs, std::string errorSuffix, MsgHandler* const errorOutput) {
358  stop.parametersSet = 0;
359  if (attrs.hasAttribute(SUMO_ATTR_ENDPOS)) {
360  stop.parametersSet |= STOP_END_SET;
361  }
362  if (attrs.hasAttribute(SUMO_ATTR_STARTPOS)) {
364  }
365  if (attrs.hasAttribute(SUMO_ATTR_TRIGGERED)) {
367  }
370  }
371  if (attrs.hasAttribute(SUMO_ATTR_PARKING)) {
373  }
374  if (attrs.hasAttribute(SUMO_ATTR_EXPECTED)) {
376  }
379  }
380  if (attrs.hasAttribute(SUMO_ATTR_TRIP_ID)) {
382  }
383  if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
385  }
386  bool ok = true;
387  stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
388  stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
389  stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
390  stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
391  if (stop.busstop != "") {
392  errorSuffix = " at '" + stop.busstop + "'" + errorSuffix;
393  } else if (stop.chargingStation != "") {
394  errorSuffix = " at '" + stop.chargingStation + "'" + errorSuffix;
395  } else if (stop.containerstop != "") {
396  errorSuffix = " at '" + stop.containerstop + "'" + errorSuffix;
397  } else if (stop.parkingarea != "") {
398  errorSuffix = " at '" + stop.parkingarea + "'" + errorSuffix;
399  } else {
400  errorSuffix = " on lane '" + stop.lane + "'" + errorSuffix;
401  }
402  // get the standing duration
405  stop.containerTriggered = attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, true);
406  stop.triggered = attrs.getOpt<bool>(SUMO_ATTR_TRIGGERED, nullptr, ok, false);
407  } else {
408  stop.triggered = attrs.getOpt<bool>(SUMO_ATTR_TRIGGERED, nullptr, ok, true);
409  stop.containerTriggered = attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, false);
410  }
411  stop.duration = -1;
412  stop.until = -1;
413  } else {
414  stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, nullptr, ok, -1);
415  stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, -1);
416  if (!ok || (stop.duration < 0 && stop.until < 0)) {
417  errorOutput->inform("Invalid duration or end time is given for a stop" + errorSuffix);
418  return false;
419  }
420  stop.triggered = attrs.getOpt<bool>(SUMO_ATTR_TRIGGERED, nullptr, ok, false);
421  stop.containerTriggered = attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, false);
422  }
423  stop.parking = attrs.getOpt<bool>(SUMO_ATTR_PARKING, nullptr, ok, stop.triggered || stop.containerTriggered || stop.parkingarea != "");
424  if (stop.parkingarea != "" && !stop.parking) {
425  WRITE_WARNING("Stop at parkingarea overrides attribute 'parking' for stop" + errorSuffix);
426  stop.parking = true;
427  }
428  if (!ok) {
429  errorOutput->inform("Invalid bool for 'triggered', 'containerTriggered' or 'parking' for stop" + errorSuffix);
430  return false;
431  }
432 
433  // expected persons
434  const std::vector<std::string>& expected = attrs.getOptStringVector(SUMO_ATTR_EXPECTED, nullptr, ok);
435  stop.awaitedPersons.insert(expected.begin(), expected.end());
436  if (stop.awaitedPersons.size() > 0 && (stop.parametersSet & STOP_TRIGGER_SET) == 0) {
437  stop.triggered = true;
438  if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
439  stop.parking = true;
440  }
441  }
442 
443  // expected containers
444  const std::vector<std::string>& expectedContainers = attrs.getOptStringVector(SUMO_ATTR_EXPECTED_CONTAINERS, nullptr, ok);
445  stop.awaitedContainers.insert(expectedContainers.begin(), expectedContainers.end());
446  if (stop.awaitedContainers.size() > 0 && (stop.parametersSet & STOP_CONTAINER_TRIGGER_SET) == 0) {
447  stop.containerTriggered = true;
448  if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
449  stop.parking = true;
450  }
451  }
452  // public transport trip id
453  stop.tripId = attrs.getOpt<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok, "");
454  stop.line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, nullptr, ok, "");
455 
456  const std::string idx = attrs.getOpt<std::string>(SUMO_ATTR_INDEX, nullptr, ok, "end");
457  if (idx == "end") {
458  stop.index = STOP_INDEX_END;
459  } else if (idx == "fit") {
460  stop.index = STOP_INDEX_FIT;
461  } else {
462  stop.index = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
463  if (!ok || stop.index < 0) {
464  errorOutput->inform("Invalid 'index' for stop" + errorSuffix);
465  return false;
466  }
467  }
468  return true;
469 }
470 
471 /****************************************************************************/
const int STOP_CONTAINER_TRIGGER_SET
virtual void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)=0
opens a type distribution for reading
virtual void addPersonTrip(const SUMOSAXAttributes &attrs)=0
add a routing request for a walking or intermodal person
SumoXMLTag
Numbers representing SUMO-XML - element names.
virtual void myEndElement(int element)
Called when a closing tag occurs.
std::string lane
The lane to stop at.
long long int SUMOTime
Definition: SUMOTime.h:35
const int VEHPARS_FORCE_REROUTE
description of a vehicle type
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
The time is given.
virtual void closeVType()=0
Ends the processing of a vehicle type.
SUMOTime myFirstDepart
the first read departure time
a flow definitio nusing a from-to edges instead of a route (used by router)
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, container or flow.
SUMOTime myEndDefault
The default value for flow ends.
distribution of a route
static SUMOVTypeParameter * beginVTypeParsing(const SUMOSAXAttributes &attrs, const bool hardFail, const std::string &file)
Starts to parse a vehicle type.
virtual void addStop(const SUMOSAXAttributes &attrs)=0
Processing of a stop.
const std::string & getFileName() const
returns the current file name
std::string line
the new line id of the trip within a cyclical public transport route
static SUMOVehicleParameter * parseVehicleAttributes(const SUMOSAXAttributes &attrs, const bool hardFail, const bool optionalID=false, const bool skipDepart=false, const bool isPerson=false)
Parses a vehicle&#39;s attributes.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (whe changing color) ...
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
virtual void addContainer(const SUMOSAXAttributes &attrs)=0
Processing of a container.
virtual void closeTrip()=0
Ends the processing of a trip.
virtual void openTrip(const SUMOSAXAttributes &attrs)=0
opens a trip for reading
weights: time range begin
std::string busstop
(Optional) bus stop if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
virtual void openRouteDistribution(const SUMOSAXAttributes &attrs)=0
opens a route distribution for reading
const int STOP_INDEX_FIT
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
std::string myActiveRouteID
The id of the current route.
virtual void addTranship(const SUMOSAXAttributes &attrs)=0
Processing of a tranship.
SAX-handler base for SUMO-files.
int myInsertStopEdgesAt
where stop edges can be inserted into the current route (-1 means no insertion)
std::string parkingarea
(Optional) parking area if one is assigned to the stop
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
begin/end of the description of a route
SUMOTime getLastDepart() const
Returns the last loaded depart time.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
bool triggered
whether an arriving person lets the vehicle continue
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
std::string tripId
id of the trip within a cyclical public transport route
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOTime getFirstDepart() const
returns the first departure time that was ever read
const int STOP_START_SET
virtual void addRide(const SUMOSAXAttributes &attrs)=0
Processing of a ride.
SUMOTime myBeginDefault
The default value for flow begins.
virtual void closePersonFlow()=0
Ends the processing of a person.
virtual void closeVehicle()=0
Ends the processing of a vehicle.
the edges of a route
virtual void addTransport(const SUMOSAXAttributes &attrs)=0
Processing of a transport.
virtual void closeContainer()=0
Ends the processing of a container.
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
parameter associated to a certain key
void addParam(const SUMOSAXAttributes &attrs)
assign arbitrary vehicle parameters
virtual ~SUMORouteHandler()
standard destructor
SUMOTime until
The time at which the vehicle may continue its journey.
const int STOP_INDEX_END
static SUMOVehicleParameter * parseFlowAttributes(const SUMOSAXAttributes &attrs, const bool hardFail, const SUMOTime beginDefault, const SUMOTime endDefault, bool isPerson=false)
Parses a flow&#39;s attributes.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
const int STOP_TRIP_ID_SET
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
const int STOP_EXPECTED_SET
const std::vector< std::string > getOptStringVector(int attr, const char *objectid, bool &ok, bool report=true) const
convenience function to avoid the default argument and the template stuff at getOpt<> ...
std::string line
The vehicle&#39;s line (mainly for public transport)
Definition of vehicle stop (position and duration)
int index
at which position in the stops list
virtual void closeRoute(const bool mayBeDisconnected=false)=0
const int STOP_END_SET
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
const int STOP_PARKING_SET
stop for vehicles
static bool checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
const int STOP_TRIGGER_SET
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
virtual void closeVehicleTypeDistribution()=0
closes (ends) the building of a distribution
const int STOP_EXPECTED_CONTAINERS_SET
bool containerTriggered
whether an arriving container lets the vehicle continue
SUMOTime myLastDepart
The insertion time of the vehicle read last.
weights: time range end
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
bool parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs, std::string errorSuffix, MsgHandler *const errorOutput)
parses attributes common to all stops
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:118
A storage for options typed value containers)
Definition: OptionsCont.h:90
Utility methods for initialising, closing and using the XML-subsystem.
Definition: XMLSubSys.h:67
virtual void closeRouteDistribution()=0
closes (ends) the building of a distribution
std::string id
The vehicle type&#39;s id.
Parameterised myLoadedParameterised
Parameterised used for saving loaded generic parameters that aren&#39;t saved in Vehicles or Vehicle Type...
virtual void closeFlow()=0
Ends the processing of a flow.
description of a vehicle
an aggreagated-output interval
virtual void closePerson()=0
Ends the processing of a person.
const bool myHardFail
flag to enable or disable hard fails
const int STOP_LINE_SET
a single trip definition (used by router)
std::string chargingStation
(Optional) charging station if one is assigned to the stop
std::string containerstop
(Optional) container stop if one is assigned to the stop
virtual void addPerson(const SUMOSAXAttributes &attrs)=0
Processing of a person.
distribution of a vehicle type
virtual void addWalk(const SUMOSAXAttributes &attrs)=0
add a fully specified walk
bool checkLastDepart()
Checks whether the route file is sorted by departure time if needed.
SUMOTime duration
The stopping duration.
bool parking
whether the vehicle is removed from the net while stopping
std::string id
The vehicle&#39;s id.
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
virtual void openRoute(const SUMOSAXAttributes &attrs)=0
opens a route for reading
SUMORouteHandler(const std::string &file, const std::string &expectedRoot, const bool hardFail)
standard constructor
static bool parseVTypeEmbedded(SUMOVTypeParameter &into, const SumoXMLTag element, const SUMOSAXAttributes &attrs, const bool hardFail, const bool fromVType=false)
Parses an element embedded in vtype definition.
#define FALLTHROUGH
Definition: StdDefs.h:37