Eclipse SUMO - Simulation of Urban MObility
AGActivityGenHandler.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 // activitygen module
5 // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)
6 // This program and the accompanying materials are made available under the
7 // terms of the Eclipse Public License 2.0 which is available at
8 // https://www.eclipse.org/legal/epl-2.0/
9 // This Source Code may also be made available under the following Secondary
10 // Licenses when the conditions for such availability set forth in the Eclipse
11 // Public License 2.0 are satisfied: GNU General Public License, version 2
12 // or later which is available at
13 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
14 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
15 /****************************************************************************/
24 // The handler for parsing the statistics file.
25 /****************************************************************************/
26 #include <config.h>
27 
28 #include "AGActivityGenHandler.h"
29 #include <iostream>
30 #include <utility>
31 #include <map>
32 #include <string>
39 #include <router/RONet.h>
40 #include "city/AGCity.h"
41 #include "city/AGSchool.h"
42 #include "city/AGPosition.h"
43 #include "city/AGBusLine.h"
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
50  : SUMOSAXHandler("sumo-stat"),
51  myCity(city), net(net) {}
52 
53 
55 
56 
57 void
59  try {
60  switch (element) {
61  case AGEN_TAG_GENERAL:
62  parseGeneralCityInfo(attrs);
63  break;
64  case AGEN_TAG_STREET:
65  parseStreets(attrs);
66  break;
67  case AGEN_TAG_WORKHOURS:
69  break;
70  case AGEN_TAG_OPENING:
71  parseOpeningHour(attrs);
72  break;
73  case AGEN_TAG_CLOSING:
74  parseClosingHour(attrs);
75  break;
76  case AGEN_TAG_SCHOOLS:
77  parseSchools();
78  break;
79  case AGEN_TAG_SCHOOL:
80  parseSchool(attrs);
81  break;
83  parseBusStation(attrs);
84  break;
85  case AGEN_TAG_BUSLINE:
86  parseBusLine(attrs);
87  break;
88  case AGEN_TAG_STATIONS:
89  parseStations();
90  break;
93  break;
94  case AGEN_TAG_STATION:
95  parseStation(attrs);
96  break;
97  case AGEN_TAG_FREQUENCY:
98  parseFrequency(attrs);
99  break;
100  case AGEN_TAG_POPULATION:
101  parsePopulation();
102  break;
103  /*case AGEN_TAG_CHILD_ACOMP:
104  parseChildrenAccompaniment();
105  break;*/
106  case AGEN_TAG_BRACKET:
107  parseBracket(attrs);
108  break;
109  case AGEN_TAG_PARAM:
110  parseParameters(attrs);
111  break;
112  case AGEN_TAG_ENTRANCE:
113  parseCityGates(attrs);
114  break;
115  default:
116  break;
117  }
118  } catch (const std::exception& e) {
119  throw ProcessError(e.what());
120  }
121 }
122 
123 
124 void
126  try {
127  bool ok;
130  myCity.statData.limitAgeChildren = attrs.getOpt<int>(AGEN_ATTR_CHILDREN, nullptr, ok, 18);
131  myCity.statData.limitAgeRetirement = attrs.getOpt<int>(AGEN_ATTR_RETIREMENT, nullptr, ok, 63);
132  myCity.statData.carRate = attrs.getOpt<double>(AGEN_ATTR_CARS, nullptr, ok, 0.58);
133  myCity.statData.unemployement = attrs.getOpt<double>(AGEN_ATTR_UNEMPLOYEMENT, nullptr, ok, 0.06);
134  myCity.statData.laborDemand = attrs.getOpt<double>(AGEN_ATTR_LABORDEMAND, nullptr, ok, 1.05);
135  myCity.statData.maxFootDistance = attrs.getOpt<double>(AGEN_ATTR_MAX_FOOT_DIST, nullptr, ok, 300.0);
136  myCity.statData.incomingTraffic = attrs.getOpt<int>(AGEN_ATTR_IN_TRAFFIC, nullptr, ok, 0);
137  myCity.statData.outgoingTraffic = attrs.getOpt<int>(AGEN_ATTR_OUT_TRAFFIC, nullptr, ok, 0);
138  } catch (const std::exception& e) {
139  WRITE_ERROR("Error while parsing the element " +
140  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_GENERAL) + ": " +
141  e.what());
142  throw ProcessError();
143  }
144 }
145 
146 void
148  try {
149  bool ok;
150  myCity.statData.carPreference = attrs.getOpt<double>(AGEN_ATTR_CARPREF, nullptr, ok, 0.0);
151  myCity.statData.speedTimePerKm = attrs.getOpt<double>(AGEN_ATTR_CITYSPEED, nullptr, ok, 360.0);
152  myCity.statData.freeTimeActivityRate = attrs.getOpt<double>(AGEN_ATTR_FREETIMERATE, nullptr, ok, 0.15);
153  myCity.statData.uniformRandomTrafficRate = attrs.getOpt<double>(AGEN_ATTR_UNI_RAND_TRAFFIC, nullptr, ok, 0.0);
154  myCity.statData.departureVariation = attrs.getOpt<double>(AGEN_ATTR_DEP_VARIATION, nullptr, ok, 0.0);
155  } catch (const std::exception& e) {
156  WRITE_ERROR("Error while parsing the element " +
157  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_PARAM) + ": " +
158  e.what());
159  throw ProcessError();
160  }
161 }
162 
163 void
165  try {
166  double pop = 0;
167  double work = 0;
168 
169  std::string eid = attrs.getString(SUMO_ATTR_EDGE);
170  if (attrs.hasAttribute(AGEN_ATTR_POPULATION)) {
171  pop = attrs.getFloat(AGEN_ATTR_POPULATION);
172  if (std::isnan(pop)) {
173  pop = 0;
174  WRITE_WARNINGF(TL("Invalid % value of edge % is treated as zero."), SUMOXMLDefinitions::Attrs.getString(AGEN_ATTR_POPULATION), eid);
175  }
176  }
178  work = attrs.getFloat(AGEN_ATTR_OUT_WORKPOSITION);
179  if (std::isnan(work)) {
180  work = 0;
181  WRITE_WARNINGF(TL("Invalid % value of edge % is treated as zero."), SUMOXMLDefinitions::Attrs.getString(AGEN_ATTR_OUT_WORKPOSITION), eid);
182  }
183  }
184  AGStreet* street = dynamic_cast<AGStreet*>(net->getEdge(eid));
185  if (street == nullptr) {
186  WRITE_ERRORF(TL("Edge '%' is not known."), eid);
187  return;
188  }
189  street->setPopulation(pop * street->getLength());
190  street->setWorkplaceNumber(work * street->getLength());
191  myCity.streets.push_back(street);
192  } catch (const std::exception& e) {
193  WRITE_ERROR("Error while parsing the element " +
194  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_STREET) + ": " +
195  e.what());
196  throw ProcessError();
197  }
198 }
199 
200 void
202  try {
203  std::string edge = attrs.getString(SUMO_ATTR_EDGE);
204  double positionOnEdge = attrs.getFloat(SUMO_ATTR_POSITION);
205  AGPosition posi(myCity.getStreet(edge), positionOnEdge);
208  myCity.cityGates.push_back(posi);
209 
210  } catch (const std::exception& e) {
211  WRITE_ERROR("Error while parsing the element " +
212  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_CITYGATES) + ": " +
213  e.what());
214  throw ProcessError();
215  }
216 }
217 
218 void
220  myCurrentObject = "workHours";
221 }
222 
223 void
225  if (myCurrentObject == "workHours") {
226  try {
228 
229  } catch (const std::exception& e) {
230  WRITE_ERROR("Error while parsing the element " +
232  + e.what());
233  throw ProcessError();
234  }
235  }
236 }
237 
238 void
240  if (myCurrentObject == "workHours") {
241  try {
243 
244  } catch (const std::exception& e) {
245  WRITE_ERROR("Error while parsing the element " +
247  + e.what());
248  throw ProcessError();
249  }
250  }
251 }
252 
253 void
255  myCurrentObject = "schools";
256 }
257 
258 void
260  try {
261  std::string edge = attrs.getString(SUMO_ATTR_EDGE);
262  double positionOnEdge = attrs.getFloat(SUMO_ATTR_POSITION);
263  AGPosition posi(myCity.getStreet(edge), positionOnEdge);
264  int beginAge = attrs.getInt(AGEN_ATTR_BEGINAGE);
265  int endAge = attrs.getInt(AGEN_ATTR_ENDAGE);
266  int capacity = attrs.getInt(AGEN_ATTR_CAPACITY);
267  int openingHour = attrs.getInt(AGEN_ATTR_OPENING);
268  int closingHour = attrs.getInt(AGEN_ATTR_CLOSING);
269  AGSchool sch(capacity, posi, beginAge, endAge, openingHour, closingHour);
270  myCity.schools.push_back(sch);
271 
272  } catch (const std::exception& e) {
273  WRITE_ERROR("Error while parsing the element " +
274  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_SCHOOL) + ": " +
275  e.what());
276  throw ProcessError();
277  }
278 }
279 
280 void
282  try {
283  std::string edge = attrs.getString(SUMO_ATTR_EDGE);
284  double positionOnEdge = attrs.getFloat(SUMO_ATTR_POSITION);
285  int id = attrs.getInt(SUMO_ATTR_ID);
286  AGPosition posi(myCity.getStreet(edge), positionOnEdge);
287  myCity.statData.busStations.insert(std::pair<int, AGPosition>(id, posi));
288 
289  } catch (const std::exception& e) {
290  WRITE_ERROR("Error while parsing the element " +
292  e.what());
293  throw ProcessError();
294  }
295 }
296 
297 void
299  try {
300  myCurrentObject = "busLine";
301  AGBusLine busL(attrs.getString(SUMO_ATTR_ID));
303  myCity.busLines.push_front(busL);
304  currentBusLine = &*myCity.busLines.begin();
305 
306  } catch (const std::exception& e) {
307  WRITE_ERROR("Error while parsing the element " +
308  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_BUSLINE) + ": " +
309  e.what());
310  throw ProcessError();
311  }
312 }
313 
314 void
316  isRevStation = false;
317 }
318 
319 void
321  isRevStation = true;
322 }
323 
324 void
326  if (myCurrentObject != "busLine") {
327  return;
328  }
329 
330  try {
331  bool ok = true;
332  int refID = attrs.get<int>(SUMO_ATTR_REFID, myCurrentObject.c_str(), ok);
333  if (!ok) {
334  throw ProcessError();
335  }
336  if (myCity.statData.busStations.count(refID) == 0) {
337  throw ProcessError(TLF("Unknown bus station '%'.", refID));
338  }
339  if (!isRevStation) {
341  } else {
343  }
344 
345  } catch (const std::exception& e) {
346  WRITE_ERROR("Error while parsing the element " +
347  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_STATION) + ": " +
348  e.what());
349  throw ProcessError();
350  }
351 }
352 
353 void
355  if (myCurrentObject != "busLine") {
356  return;
357  }
358 
359  try {
360  int beginB = attrs.getInt(SUMO_ATTR_BEGIN);
361  int endB = attrs.getInt(SUMO_ATTR_END);
362  int rateB = attrs.getInt(AGEN_ATTR_RATE);
363  currentBusLine->generateBuses(beginB, endB, rateB);
364 
365  } catch (const std::exception& e) {
366  WRITE_ERROR("Error while parsing the element " +
367  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_FREQUENCY) + ": " +
368  e.what());
369  throw ProcessError();
370  }
371 }
372 
373 void
375  myCurrentObject = "population";
376 }
377 
378 void
380  try {
381 
382  int beginAge = attrs.getInt(AGEN_ATTR_BEGINAGE); //included in the bracket
383  int endAge = attrs.getInt(AGEN_ATTR_ENDAGE); //NOT included in the bracket
384  bool overlapping = false;
385  // evaluate age
386  if (beginAge < endAge) {
387  for (auto it = myCity.statData.ageSpan.begin(); it != myCity.statData.ageSpan.end(); ++it) {
388  if (!(beginAge >= it->second || endAge <= it->first)) {
389  overlapping = true;
390  }
391  }
392  if (!overlapping) {
393  myCity.statData.ageSpan[beginAge] = endAge;
394 
395  if (myCurrentObject == "population") {
397  }
398  } else {
399  WRITE_ERROR("Error while parsing the element " +
400  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_BRACKET) + ": begin and end age of the population is overlapping");
401  throw ProcessError();
402  }
403  } else {
404  WRITE_ERROR("Error while parsing the element " +
405  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_BRACKET) + ": begin and end age of the population are not properly set");
406  throw ProcessError();
407  }
408 
409  } catch (const std::exception& e) {
410  WRITE_ERROR("Error while parsing the element " +
411  SUMOXMLDefinitions::Tags.getString(AGEN_TAG_BRACKET) + ": " +
412  e.what());
413  throw ProcessError();
414  }
415 }
416 
417 
418 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
@ AGEN_TAG_CITYGATES
city entrances
@ AGEN_TAG_STATION
station for a certain vehicle
@ AGEN_TAG_STREET
streets object
@ AGEN_TAG_BRACKET
alternative definition for Population
@ AGEN_TAG_FREQUENCY
frequency of a object
@ AGEN_TAG_SCHOOL
schools object
@ AGEN_TAG_CLOSING
closing for workingHours object
@ AGEN_TAG_POPULATION
population and children accompaniment brackets
@ AGEN_TAG_REV_STATIONS
rev stations for certain vehicles
@ AGEN_TAG_WORKHOURS
workingHours object
@ AGEN_TAG_SCHOOLS
school object
@ AGEN_TAG_STATIONS
stations for certain vehicles
@ AGEN_TAG_OPENING
opening for workingHours object
@ AGEN_TAG_GENERAL
ActivityGen Tags.
@ AGEN_TAG_ENTRANCE
alternative definition for city entrances
@ AGEN_TAG_PARAM
parameters
@ AGEN_TAG_BUSSTATION
busStation and bus objects
@ AGEN_TAG_BUSLINE
bus line
@ AGEN_ATTR_FREETIMERATE
@ AGEN_ATTR_RETIREMENT
@ AGEN_ATTR_DEP_VARIATION
@ SUMO_ATTR_REFID
@ AGEN_ATTR_LABORDEMAND
@ AGEN_ATTR_CAPACITY
@ AGEN_ATTR_CHILDREN
@ SUMO_ATTR_EDGE
@ AGEN_ATTR_OUTGOING
@ AGEN_ATTR_PEOPLENBR
@ SUMO_ATTR_BEGIN
weights: time range begin
@ AGEN_ATTR_PROP
@ AGEN_ATTR_UNI_RAND_TRAFFIC
@ AGEN_ATTR_HOUSEHOLDS
@ AGEN_ATTR_INHABITANTS
@ AGEN_ATTR_OPENING
@ AGEN_ATTR_INCOMING
@ AGEN_ATTR_OUT_TRAFFIC
@ AGEN_ATTR_CARS
@ SUMO_ATTR_END
weights: time range end
@ AGEN_ATTR_CARPREF
@ AGEN_ATTR_CITYSPEED
@ AGEN_ATTR_HOUR
@ AGEN_ATTR_CLOSING
@ AGEN_ATTR_OUT_WORKPOSITION
@ AGEN_ATTR_ENDAGE
@ SUMO_ATTR_ID
@ AGEN_ATTR_POPULATION
@ AGEN_ATTR_MAX_TRIP_DURATION
@ AGEN_ATTR_UNEMPLOYEMENT
@ AGEN_ATTR_IN_TRAFFIC
@ AGEN_ATTR_RATE
@ AGEN_ATTR_MAX_FOOT_DIST
@ AGEN_ATTR_BEGINAGE
@ SUMO_ATTR_POSITION
void parseBusStation(const SUMOSAXAttributes &attrs)
bool isRevStation
indicator whether the current station (in bus line context) is a reverse station or not.
void parseBracket(const SUMOSAXAttributes &attrs)
void parseBusLine(const SUMOSAXAttributes &attrs)
void parseCityGates(const SUMOSAXAttributes &attrs)
void parseSchool(const SUMOSAXAttributes &attrs)
void parseClosingHour(const SUMOSAXAttributes &attrs)
void parseOpeningHour(const SUMOSAXAttributes &attrs)
void parseParameters(const SUMOSAXAttributes &attrs)
AGCity & myCity
The city to store the information into.
std::string myCurrentObject
The name of the object that is currently processed.
RONet * net
The loaded network.
AGActivityGenHandler(AGCity &city, RONet *net)
Constructor.
void parseFrequency(const SUMOSAXAttributes &attrs)
void parseGeneralCityInfo(const SUMOSAXAttributes &attrs)
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void parseStreets(const SUMOSAXAttributes &attrs)
void parseStation(const SUMOSAXAttributes &attrs)
virtual ~AGActivityGenHandler()
Destructor.
void locateRevStation(AGPosition pos)
Definition: AGBusLine.cpp:136
void locateStation(AGPosition pos)
Definition: AGBusLine.cpp:131
void generateBuses(int start, int stop, int rate)
Definition: AGBusLine.cpp:141
void setMaxTripTime(int time)
Definition: AGBusLine.cpp:46
Definition: AGCity.h:50
std::vector< AGStreet * > streets
Definition: AGCity.h:79
std::vector< AGPosition > cityGates
Definition: AGCity.h:85
std::list< AGSchool > schools
Definition: AGCity.h:82
AGDataAndStatistics & statData
Definition: AGCity.h:78
std::list< AGBusLine > busLines
Definition: AGCity.h:83
const AGStreet & getStreet(const std::string &edge)
Definition: AGCity.cpp:388
std::map< int, double > incoming
std::map< int, double > endWorkHours
std::map< int, AGPosition > busStations
std::map< int, int > ageSpan
std::map< int, double > beginWorkHours
std::map< int, double > outgoing
std::map< int, double > population
A location in the 2D plane freely positioned on a street.
Definition: AGPosition.h:53
A model of the street in the city.
Definition: AGStreet.h:50
void setWorkplaceNumber(const double work)
Modifies the number of work places in this street.
Definition: AGStreet.cpp:65
void setPopulation(const double pop)
Modifies the number of persons living in this street.
Definition: AGStreet.cpp:53
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:219
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
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
int getInt(int id) const
Returns the int-value of the named (by its enum-value) attribute.
double getFloat(int id) const
Returns the double-value of the named (by its enum-value) attribute.
SAX-handler base for SUMO-files.
static StringBijection< int > Tags
The names of SUMO-XML elements for use in netbuild.
static StringBijection< int > Attrs
The names of SUMO-XML attributes for use in netbuild.