Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-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/****************************************************************************/
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>
35#include <netbuild/NBNodeCont.h>
36#include <netbuild/NBTypeCont.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
62void
64 const SUMOSAXAttributes& attrs) {
65 switch (element) {
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;
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
118void
120 switch (element) {
123 myCurrentStop = nullptr;
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
143void
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 double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok);
150 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 std::string edgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
156 NBEdge* edge = myEdgeCont.retrieve(edgeID);
157 if (edge == nullptr) {
158 edge = myEdgeCont.retrieve(edgeID, true);
159 if (edge != nullptr && myEdgeCont.getSplit(edge) == nullptr) {
160 // splits are treated later
161 edge = nullptr;
162 }
163 }
164 if (edge == nullptr) {
165 if (!myEdgeCont.wasIgnored(edgeID)) {
166 WRITE_ERRORF(TL("Edge '%' for stop '%' not found"), edgeID, id);
167 } else {
170 }
171 return;
172 }
173 if (edge->getNumLanes() <= laneIndex) {
174 WRITE_ERRORF(TL("Lane '%' for stop '%' not found"), laneID, id);
175 return;
176 }
177 SVCPermissions permissions = edge->getPermissions(laneIndex);
178 // 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
179 if (!isRailway(permissions) && permissions != SVC_SHIP && permissions != SVC_TAXI) {
180 permissions = SVC_BUS;
181 }
182 if (ok) {
183 if (startPos < 0) {
184 startPos += edge->getLoadedLength();
185 }
186 if (endPos < 0) {
187 endPos += edge->getLoadedLength();
188 }
189 if (myEdgeCont.wasRemoved(edgeID) && (
190 startPos >= endPos || startPos < 0 || endPos < 0
191 || startPos >= edge->getLoadedLength()
192 || endPos >= edge->getLoadedLength())) {
193 NBEdge* longest = myEdgeCont.getSplitBase(edgeID);
194 if (longest != nullptr) {
195 edge = longest;
196 }
197 }
198 Position pos = edge->geometryPositionAtOffset((startPos + endPos) / 2);
199 myCurrentStop = std::make_shared<NBPTStop>(id, pos, edgeID, edgeID, endPos - startPos, name, permissions, parkingLength, color, startPos);
200 while (myEdgeCont.getSplit(edge) != nullptr) {
201 myCurrentStop->resetLoaded();
202 const std::pair<NBEdge*, NBEdge*> split = *myEdgeCont.getSplit(edge);
203 if (myCurrentStop->replaceEdge(edgeID, {split.first, split.second})) {
204 edge = split.first->getID() == myCurrentStop->getEdgeId() ? split.first : split.second;
205 edgeID = edge->getID();
206 }
207 }
209 WRITE_ERRORF(TL("Could not add public transport stop '%' (already exists)"), id);
210 }
211 }
212}
213
214void
216 if (myCurrentStop == nullptr) {
218 return;
219 } else {
220 throw InvalidArgument("Could not add access outside a stopping place.");
221 }
222 }
223 bool ok = true;
224 const std::string laneID = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
225 const std::string edgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
226 if (myEdgeCont.retrieve(edgeID) == nullptr) {
227 if (!myEdgeCont.wasIgnored(edgeID)) {
228 WRITE_ERRORF(TL("Edge '%' for access to stop '%' not found"), edgeID, myCurrentStop->getID());
229 }
230 return;
231 }
232 const double pos = attrs.get<double>(SUMO_ATTR_POSITION, "access", ok);
233 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
234 if (ok) {
235 myCurrentStop->addAccess(laneID, pos, length);
236 }
237}
238
239
240void
242 bool ok = true;
243 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok);
244 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
245 const std::string line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, id.c_str(), ok, "");
246 const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
248 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
249 vClass = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok));
250 }
251 RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor(false));
252 const int intervalS = attrs.getOpt<int>(SUMO_ATTR_PERIOD, id.c_str(), ok, -1);
253 const std::string nightService = attrs.getStringSecure("nightService", "");
254 myCurrentCompletion = StringUtils::toDouble(attrs.getStringSecure("completeness", "1"));
255 myMissingBefore = StringUtils::toInt(attrs.getStringSecure("missingBefore", "0"));
256 myMissingAfter = StringUtils::toInt(attrs.getStringSecure("missingAfter", "0"));
257 if (ok) {
258 // patching existing line?
260 if (myCurrentLine == nullptr) {
261 myCurrentLine = new NBPTLine(id, name, type, line, intervalS / 60, nightService, vClass, color);
263 } else {
264 WRITE_MESSAGEF(TL("Duplicate ptLine id occurred ('%'); assuming overwriting is wished."), id);
265 if (name != "") {
266 myCurrentLine->setName(name);
267 }
268 if (line != "") {
269 myCurrentLine->setRef(line);
270 }
271 if (intervalS != -1) {
272 myCurrentLine->setPeriod(intervalS);
273 }
274 }
275 }
276}
277
278
279void
281 bool ok = true;
282 myMissingBefore = 0;
283 myMissingAfter = 0;
284 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "flow", ok);
285 const std::string line = attrs.get<std::string>(SUMO_ATTR_LINE, id.c_str(), ok);
286 const std::string type = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
287 const std::string route = attrs.get<std::string>(SUMO_ATTR_ROUTE, id.c_str(), ok);
289 const int intervalS = attrs.getOpt<int>(SUMO_ATTR_PERIOD, id.c_str(), ok, -1);
290 RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor(false));
291 if (ok) {
292 myCurrentLine = new NBPTLine(id, "", type, line, intervalS / 60, "", vClass, color);
294 for (std::shared_ptr<NBPTStop> stop : myRouteStops[route]) {
296 }
298 }
299}
300
301
302void
304 if (myCurrentLine == nullptr) {
305 WRITE_ERROR(TL("Found route outside line definition"));
306 return;
307 }
308 bool ok = true;
309 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
310 EdgeVector edges;
311 for (const std::string& edgeID : edgeIDs) {
312 NBEdge* edge = myEdgeCont.retrieve(edgeID);
313 if (edge == nullptr) {
314 if (!myEdgeCont.wasIgnored(edgeID)) {
315 WRITE_ERRORF(TL("Edge '%' in route of line '%' not found"), edgeID, myCurrentLine->getName());
316 }
317 } else {
318 edges.push_back(edge);
319 }
320 }
321 myCurrentLine->setEdges(edges);
322}
323
324
325void
327 bool ok = true;
328 myCurrentRouteID = attrs.get<std::string>(SUMO_ATTR_ID, "route", ok);
329 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentRouteID.c_str(), ok);
330 EdgeVector edges;
331 for (const std::string& edgeID : edgeIDs) {
332 NBEdge* edge = myEdgeCont.retrieve(edgeID);
333 if (edge == nullptr) {
334 if (!myEdgeCont.wasIgnored(edgeID)) {
335 WRITE_ERRORF(TL("Edge '%' in route of line '%' not found"), edgeID, myCurrentLine->getName());
336 }
337 } else {
338 edges.push_back(edge);
339 }
340 }
342}
343
344
345void
347 bool ok = true;
348 const std::string id = attrs.hasAttribute(SUMO_ATTR_ID)
349 ? attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok)
350 : attrs.get<std::string>(SUMO_ATTR_BUS_STOP, "ptline", ok);
351 std::shared_ptr<NBPTStop> stop = myStopCont.get(id);
352 if (stop == nullptr) {
353 if (!NBPTStopCont::wasIgnored(id)) {
354 WRITE_ERRORF(TL("Stop '%' within line '%' not found"), id, toString(myCurrentLine->getLineID()));
355 }
356 return;
357 }
359}
360
361void
363 assert(myCurrentRouteID != "");
364 bool ok = true;
365 const std::string id = attrs.hasAttribute(SUMO_ATTR_ID)
366 ? attrs.get<std::string>(SUMO_ATTR_ID, "ptLine", ok)
367 : attrs.get<std::string>(SUMO_ATTR_BUS_STOP, "ptline", ok);
368 std::shared_ptr<NBPTStop> stop = myStopCont.get(id);
369 if (stop == nullptr) {
370 WRITE_ERRORF(TL("Stop '%' within route '%' not found"), id, toString(myCurrentRouteID));
371 return;
372 }
373 myRouteStops[myCurrentRouteID].push_back(stop);
374}
375
376
377/****************************************************************************/
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:289
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:304
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
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 permissions is a (exclusive) 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
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
const std::pair< NBEdge *, NBEdge * > * getSplit(const NBEdge *const origEdge) const
Returns the edge split if the edge has been split, nullptr otherwise.
Definition NBEdgeCont.h:300
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition NBEdgeCont.h:483
bool wasRemoved(std::string id) const
Returns whether the edge with the id was deleted explicitly.
Definition NBEdgeCont.h:493
NBEdge * getSplitBase(const std::string &edgeID) const
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:4540
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition NBEdge.h:608
const std::string & getID() const
Definition NBEdge.h:1551
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:526
Position geometryPositionAtOffset(double offset) const
return position taking into account loaded length
Definition NBEdge.cpp:4874
static int getLaneIndexFromLaneID(const std::string laneID)
Definition NBEdge.cpp:4991
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 & getName() const
Definition NBPTLine.h:55
const std::string & getLineID() const
Definition NBPTLine.h:51
void setPeriod(int intervalS)
Definition NBPTLine.h:114
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.
static void addIgnored(const std::string &stopID)
std::shared_ptr< NBPTStop > get(std::string id) const
Retrieve a previously inserted pt stop.
static bool wasIgnored(const std::string &stopID)
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,...