Eclipse SUMO - Simulation of Urban MObility
NIXMLPTHandler.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 // 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 /****************************************************************************/
18 // Importer for static public transport information
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <string>
23 #include <iostream>
24 #include <map>
25 #include <cmath>
32 #include <utils/common/ToString.h>
35 #include <netbuild/NBNodeCont.h>
36 #include <netbuild/NBTypeCont.h>
37 #include <netbuild/NBNetBuilder.h>
38 #include <netbuild/NBPTStop.h>
40 #include "NIXMLNodesHandler.h"
41 #include "NIXMLPTHandler.h"
42 
43 
44 // ===========================================================================
45 // method definitions
46 // ===========================================================================
48  SUMOSAXHandler("public transport - file"),
49  myEdgeCont(ec),
50  myStopCont(sc),
51  myLineCont(lc),
52  myCurrentStop(nullptr),
53  myCurrentLine(nullptr),
54  myCurrentCompletion(0),
55  myCurrentStopWasIgnored(false)
56 { }
57 
58 
60 
61 
62 void
64  const SUMOSAXAttributes& attrs) {
65  switch (element) {
66  case SUMO_TAG_BUS_STOP:
68  case SUMO_TAG_STOP:
69  if (myCurrentRouteID != "") {
70  addRouteStop(attrs);
71  } else if (myCurrentLine == nullptr) {
72  addPTStop(attrs);
73  } else {
74  addPTLineStop(attrs);
75  }
76  break;
77  case SUMO_TAG_ACCESS:
78  addAccess(attrs);
79  break;
80  case SUMO_TAG_PT_LINE:
81  addPTLine(attrs);
82  break;
83  case SUMO_TAG_ROUTE:
84  if (myCurrentLine == nullptr) {
85  addRoute(attrs);
86  } else {
87  addPTLineRoute(attrs);
88  }
89  break;
90  case SUMO_TAG_FLOW:
91  case SUMO_TAG_TRIP:
92  addPTLineFromFlow(attrs);
93  break;
94  case SUMO_TAG_PARAM: {
95  bool ok = true;
96  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
97  if (myCurrentLine != nullptr) {
98  if (key == "completeness") {
99  myCurrentCompletion = attrs.get<double>(SUMO_ATTR_VALUE, nullptr, ok);
100  } else if (key == "name") {
101  myCurrentLine->setName(attrs.get<std::string>(SUMO_ATTR_VALUE, nullptr, ok));
102  } else if (key == "missingBefore") {
103  myMissingBefore = attrs.get<int>(SUMO_ATTR_VALUE, nullptr, ok);
104  } else if (key == "missingAfter") {
105  myMissingAfter = attrs.get<int>(SUMO_ATTR_VALUE, nullptr, ok);
106  }
107  } else if (myCurrentStop != nullptr) {
108  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
109  myCurrentStop->setParameter(key, val);
110  }
111  }
112  break;
113  default:
114  break;
115  }
116 }
117 
118 void
120  switch (element) {
121  case SUMO_TAG_BUS_STOP:
122  case SUMO_TAG_TRAIN_STOP:
123  myCurrentStop = nullptr;
124  myCurrentStopWasIgnored = false;
125  break;
126  case SUMO_TAG_PT_LINE:
127  case SUMO_TAG_FLOW:
128  case SUMO_TAG_TRIP:
129  if (myCurrentLine != nullptr) {
131  }
132  myCurrentLine = nullptr;
133  break;
134  case SUMO_TAG_ROUTE:
135  myCurrentRouteID = "";
136  break;
137  default:
138  break;
139  }
140 }
141 
142 
143 void
145  bool ok = true;
146  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "busStop", ok);
147  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
148  const std::string laneID = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
149  const double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok);
150  const double endPos = attrs.get<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok);
151  const double parkingLength = attrs.getOpt<double>(SUMO_ATTR_PARKING_LENGTH, id.c_str(), ok, 0);
152  const RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor(false));
153  //const std::string lines = attrs.get<std::string>(SUMO_ATTR_LINES, id.c_str(), ok);
154  const int laneIndex = NBEdge::getLaneIndexFromLaneID(laneID);
155  const std::string edgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
156  NBEdge* edge = myEdgeCont.retrieve(edgeID);
157  if (edge == nullptr) {
158  if (!myEdgeCont.wasIgnored(edgeID)) {
159  WRITE_ERRORF(TL("Edge '%' for stop '%' not found"), edgeID, id);
160  } else {
163  }
164  return;
165  }
166  if (edge->getNumLanes() <= laneIndex) {
167  WRITE_ERRORF(TL("Lane '%' for stop '%' not found"), laneID, id);
168  return;
169  }
170  SVCPermissions permissions = edge->getPermissions(laneIndex);
171  // possibly the stops were written for a different network. If the lane is not a typical public transport stop lane, assume bus as the default
172  if (!isRailway(permissions) && permissions != SVC_SHIP && permissions != SVC_TAXI) {
173  permissions = SVC_BUS;
174  }
175  if (ok) {
176  Position pos = edge->geometryPositionAtOffset((startPos + endPos) / 2);
177  myCurrentStop = std::make_shared<NBPTStop>(id, pos, edgeID, edgeID, endPos - startPos, name, permissions, parkingLength, color, startPos);
179  WRITE_ERRORF(TL("Could not add public transport stop '%' (already exists)"), id);
180  }
181  }
182 }
183 
184 void
186  if (myCurrentStop == nullptr) {
188  return;
189  } else {
190  throw InvalidArgument("Could not add access outside a stopping place.");
191  }
192  }
193  bool ok = true;
194  const std::string laneID = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
195  const std::string edgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
196  if (myEdgeCont.retrieve(edgeID) == nullptr) {
197  if (!myEdgeCont.wasIgnored(edgeID)) {
198  WRITE_ERRORF(TL("Edge '%' for access to stop '%' not found"), edgeID, myCurrentStop->getID());
199  }
200  return;
201  }
202  const double pos = attrs.get<double>(SUMO_ATTR_POSITION, "access", ok);
203  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
204  if (ok) {
205  myCurrentStop->addAccess(laneID, pos, length);
206  }
207 }
208 
209 
210 void
212  bool ok = true;
213  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok);
214  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
215  const std::string line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, id.c_str(), ok, "");
216  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
218  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
219  vClass = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok));
220  }
221  RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor(false));
222  const int intervalS = attrs.getOpt<int>(SUMO_ATTR_PERIOD, id.c_str(), ok, -1);
223  const std::string nightService = attrs.getStringSecure("nightService", "");
224  myCurrentCompletion = StringUtils::toDouble(attrs.getStringSecure("completeness", "1"));
225  myMissingBefore = StringUtils::toInt(attrs.getStringSecure("missingBefore", "0"));
226  myMissingAfter = StringUtils::toInt(attrs.getStringSecure("missingAfter", "0"));
227  if (ok) {
228  // patching existing line?
230  if (myCurrentLine == nullptr) {
231  myCurrentLine = new NBPTLine(id, name, type, line, intervalS / 60, nightService, vClass, color);
233  } else {
234  WRITE_MESSAGEF(TL("Duplicate ptLine id occurred ('%'); assuming overwriting is wished."), id);
235  if (name != "") {
236  myCurrentLine->setName(name);
237  }
238  if (line != "") {
239  myCurrentLine->setRef(line);
240  }
241  if (intervalS != -1) {
242  myCurrentLine->setPeriod(intervalS);
243  }
244  }
245  }
246 }
247 
248 
249 void
251  bool ok = true;
252  myMissingBefore = 0;
253  myMissingAfter = 0;
254  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "flow", ok);
255  const std::string line = attrs.get<std::string>(SUMO_ATTR_LINE, id.c_str(), ok);
256  const std::string type = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
257  const std::string route = attrs.get<std::string>(SUMO_ATTR_ROUTE, id.c_str(), ok);
259  const int intervalS = attrs.getOpt<int>(SUMO_ATTR_PERIOD, id.c_str(), ok, -1);
260  RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor(false));
261  if (ok) {
262  myCurrentLine = new NBPTLine(id, "", type, line, intervalS / 60, "", vClass, color);
264  for (std::shared_ptr<NBPTStop> stop : myRouteStops[route]) {
265  myCurrentLine->addPTStop(stop);
266  }
268  }
269 }
270 
271 
272 void
274  if (myCurrentLine == nullptr) {
275  WRITE_ERROR(TL("Found route outside line definition"));
276  return;
277  }
278  bool ok = true;
279  const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
280  EdgeVector edges;
281  for (const std::string& edgeID : edgeIDs) {
282  NBEdge* edge = myEdgeCont.retrieve(edgeID);
283  if (edge == nullptr) {
284  if (!myEdgeCont.wasIgnored(edgeID)) {
285  WRITE_ERRORF(TL("Edge '%' in route of line '%' not found"), edgeID, myCurrentLine->getName());
286  }
287  } else {
288  edges.push_back(edge);
289  }
290  }
291  myCurrentLine->setEdges(edges);
292 }
293 
294 
295 void
297  bool ok = true;
298  myCurrentRouteID = attrs.get<std::string>(SUMO_ATTR_ID, "route", ok);
299  const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentRouteID.c_str(), ok);
300  EdgeVector edges;
301  for (const std::string& edgeID : edgeIDs) {
302  NBEdge* edge = myEdgeCont.retrieve(edgeID);
303  if (edge == nullptr) {
304  if (!myEdgeCont.wasIgnored(edgeID)) {
305  WRITE_ERRORF(TL("Edge '%' in route of line '%' not found"), edgeID, myCurrentLine->getName());
306  }
307  } else {
308  edges.push_back(edge);
309  }
310  }
312 }
313 
314 
315 void
317  bool ok = true;
318  const std::string id = attrs.hasAttribute(SUMO_ATTR_ID)
319  ? attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok)
320  : attrs.get<std::string>(SUMO_ATTR_BUS_STOP, "ptline", ok);
321  std::shared_ptr<NBPTStop> stop = myStopCont.get(id);
322  if (stop == nullptr) {
323  if (!NBPTStopCont::wasIgnored(id)) {
324  WRITE_ERRORF(TL("Stop '%' within line '%' not found"), id, toString(myCurrentLine->getLineID()));
325  }
326  return;
327  }
328  myCurrentLine->addPTStop(stop);
329 }
330 
331 void
333  assert(myCurrentRouteID != "");
334  bool ok = true;
335  const std::string id = attrs.hasAttribute(SUMO_ATTR_ID)
336  ? attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok)
337  : attrs.get<std::string>(SUMO_ATTR_BUS_STOP, "ptline", ok);
338  std::shared_ptr<NBPTStop> stop = myStopCont.get(id);
339  if (stop == nullptr) {
340  WRITE_ERRORF(TL("Stop '%' within route '%' not found"), id, toString(myCurrentRouteID));
341  return;
342  }
343  myRouteStops[myCurrentRouteID].push_back(stop);
344 }
345 
346 
347 /****************************************************************************/
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_SHIP
is an arbitrary ship
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_PT_LINE
A pt line.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_STOP
stop for vehicles
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_LANE
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_PARKING_LENGTH
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_LINE
@ SUMO_ATTR_NAME
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_VCLASS
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_KEY
@ SUMO_ATTR_POSITION
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:281
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:477
The representation of a single edge during network building.
Definition: NBEdge.h:92
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:4306
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:516
Position geometryPositionAtOffset(double offset) const
return position taking into account loaded length
Definition: NBEdge.cpp:4632
static int getLaneIndexFromLaneID(const std::string laneID)
Definition: NBEdge.cpp:4749
NBPTLine * retrieve(const std::string &lineID)
bool insert(NBPTLine *ptLine)
insert new line
void setNumOfStops(int numStops, int missingBefore, int missingAfter)
Definition: NBPTLine.cpp:166
void setName(const std::string &name)
Definition: NBPTLine.h:106
void setRef(const std::string &line)
Definition: NBPTLine.h:110
const std::string & getLineID() const
Definition: NBPTLine.h:51
void setPeriod(int intervalS)
Definition: NBPTLine.h:114
const std::string & getName() const
Definition: NBPTLine.h:55
const std::vector< std::shared_ptr< NBPTStop > > & getStops()
Definition: NBPTLine.cpp:68
void addPTStop(std::shared_ptr< NBPTStop > pStop)
Definition: NBPTLine.cpp:54
void setEdges(const std::vector< NBEdge * > &edges)
Definition: NBPTLine.cpp:141
Container for public transport stops during the net building process.
Definition: NBPTStopCont.h:44
static void addIgnored(const std::string &stopID)
Definition: NBPTStopCont.h:122
std::shared_ptr< NBPTStop > get(std::string id) const
Retrieve a previously inserted pt stop.
static bool wasIgnored(const std::string &stopID)
Definition: NBPTStopCont.h:126
bool insert(std::shared_ptr< NBPTStop > ptStop, bool floating=false)
Inserts a node into the map.
static SUMOVehicleClass interpretTransportType(const std::string &type, NIOSMNode *toSet=nullptr)
translate osm transport designations into sumo vehicle class
NIXMLPTHandler(NBEdgeCont &ec, NBPTStopCont &sc, NBPTLineCont &lc)
Constructor.
void addPTLine(const SUMOSAXAttributes &attrs)
Parses a public transport line.
std::shared_ptr< NBPTStop > myCurrentStop
The currently processed stop.
~NIXMLPTHandler()
Destructor.
std::map< std::string, std::vector< std::shared_ptr< NBPTStop > > > myRouteStops
stand-alone route information
std::string myCurrentRouteID
The currently processed stand-alone route.
void addPTLineStop(const SUMOSAXAttributes &attrs)
Parses an public transport stop reference within a line element.
void addPTLineFromFlow(const SUMOSAXAttributes &attrs)
Parses a public transport line.
NBPTStopCont & myStopCont
The stop container (for loading of stops)
void myEndElement(int element)
Called when a closing tag occurs.
NBEdgeCont & myEdgeCont
The edges container (for retrieving referenced stop edge)
std::map< std::string, EdgeVector > myRouteEdges
NBPTLineCont & myLineCont
The line container (for loading of lines)
bool myCurrentStopWasIgnored
whether the current stop should be discarded
void addPTLineRoute(const SUMOSAXAttributes &attrs)
Parses a route as port of a public transport line.
void addPTStop(const SUMOSAXAttributes &attrs)
Parses an public transport stop.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myCurrentCompletion
the completion level of the current line
void addRoute(const SUMOSAXAttributes &attrs)
Parses a stand-alone route when parsing implicit ptlines from routes and flows.
void addRouteStop(const SUMOSAXAttributes &attrs)
Parses an public transport stop reference within a route element.
void addAccess(const SUMOSAXAttributes &attrs)
Parses an stop access definition.
NBPTLine * myCurrentLine
The currently processed line.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
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.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
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.
SAX-handler base for SUMO-files.
static std::string getEdgeIDFromLane(const std::string laneID)
return edge id when given the lane ID
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...