Eclipse SUMO - Simulation of Urban MObility
NBPTLine.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-2022 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/****************************************************************************/
19// The representation of one direction of a single pt line
20/****************************************************************************/
22
23#include <utility>
27#include "NBEdgeCont.h"
28#include "NBPTStopCont.h"
29#include "NBPTLine.h"
30#include "NBPTStop.h"
31
32NBPTLine::NBPTLine(const std::string& id, const std::string& name, const std::string& type, const std::string& ref, int interval, const std::string& nightService,
33 SUMOVehicleClass vClass, RGBColor color) :
34 myName(name),
35 myType(type),
36 myPTLineId(id),
37 myRef(ref != "" ? ref : name),
38 myColor(color),
39 myInterval(interval),
40 myNightService(nightService),
41 myVClass(vClass)
42{ }
43
44
45void
47 if (!myPTStops.empty() && pStop->getName() != "" && myPTStops.back()->getName() == pStop->getName()) {
48 // avoid duplicate stop when both platform and stop_position are given as nodes
49 if (myPTStops.back()->isPlatform() && !pStop->isPlatform()) {
50 myPTStops.pop_back();
51 } else if (pStop->isPlatform()) {
52 return;
53 }
54 }
55 myPTStops.push_back(pStop);
56}
57
58
59const std::vector<NBPTStop*>&
61 return myPTStops;
62}
63
64
65void
69 if (!myName.empty()) {
71 }
72
76 if (myInterval > 0) {
77 // write seconds
79 }
80 if (myNightService != "") {
81 device.writeAttr("nightService", myNightService);
82 }
83
84 if (myColor.isValid()) {
86 }
87 device.writeAttr("completeness", toString((double)myPTStops.size() / (double)myNumOfStops));
88
89 if (!myRoute.empty()) {
90 device.openTag(SUMO_TAG_ROUTE);
92 device.closeTag();
93 }
94
95 for (auto& myPTStop : myPTStops) {
97 device.writeAttr(SUMO_ATTR_ID, myPTStop->getID());
98 device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myPTStop->getName()));
99 device.closeTag();
100 }
101 device.closeTag();
102
103}
104
105
106void
107NBPTLine::addWayNode(long long int way, long long int node) {
108 std::string wayStr = toString(way);
109 if (wayStr != myCurrentWay) {
110 myCurrentWay = wayStr;
111 myWays.push_back(wayStr);
112 }
113 myWaysNodes[wayStr].push_back(node);
114}
115
116
117std::vector<long long int>*
118NBPTLine::getWaysNodes(std::string wayId) {
119 if (myWaysNodes.find(wayId) != myWaysNodes.end()) {
120 return &myWaysNodes[wayId];
121 }
122 return nullptr;
123}
124
125
126void
127NBPTLine::setEdges(const std::vector<NBEdge*>& edges) {
128 myRoute = edges;
129 // ensure permissions
130 for (NBEdge* e : edges) {
131 SVCPermissions permissions = e->getPermissions();
132 if ((permissions & myVClass) != myVClass) {
134 if (permissions != 0 && (permissions & nVuln) == 0) {
135 // this is a footpath or sidewalk. Add another lane
136 e->addRestrictedLane(SUMO_const_laneWidth, myVClass);
137 } else {
138 // add permissions to the rightmost lane that is not exclusively used for pedestrians / bicycles
139 for (int i = 0; i < (int)e->getNumLanes(); i++) {
140 if ((e->getPermissions(i) & nVuln) != 0) {
141 e->allowVehicleClass(i, myVClass);
142 break;
143 }
144 }
145 }
146 }
147 }
148}
149
150
151void
153 myNumOfStops = numStops;
154}
155
156
157const std::vector<NBEdge*>&
159 return myRoute;
160}
161
162
163std::vector<std::pair<NBEdge*, std::string> >
165 std::vector<std::pair<NBEdge*, std::string> > result;
166 for (NBPTStop* stop : myPTStops) {
167 NBEdge* e = ec.retrieve(stop->getEdgeId());
168 if (e != nullptr) {
169 result.push_back({e, stop->getID()});
170 }
171 }
172 return result;
173}
174
175
176NBEdge*
178 std::vector<NBEdge*> validEdges;
179 // filter out edges that have been removed due to joining junctions
180 for (NBEdge* e : myRoute) {
181 if (ec.retrieve(e->getID())) {
182 validEdges.push_back(e);
183 }
184 }
185 if (validEdges.size() == 0) {
186 return nullptr;
187 }
188 // filter out edges after the first stop
189 if (myPTStops.size() > 0) {
190 NBEdge* firstStopEdge = ec.retrieve(myPTStops.front()->getEdgeId());
191 if (firstStopEdge == nullptr) {
192 WRITE_WARNINGF(TL("Could not retrieve edge '%' for first stop of line '%'."), myPTStops.front()->getEdgeId(), myPTLineId);
193 return nullptr;
194
195 }
196 auto it = std::find(validEdges.begin(), validEdges.end(), firstStopEdge);
197 if (it == validEdges.end()) {
198 WRITE_WARNINGF(TL("First stop edge '%' is not part of the route of line '%'."), firstStopEdge->getID(), myPTLineId);
199 return nullptr;
200 }
201 }
202 return validEdges.front();
203}
204
205
206NBEdge*
208 std::vector<NBEdge*> validEdges;
209 // filter out edges that have been removed due to joining junctions
210 for (NBEdge* e : myRoute) {
211 if (ec.retrieve(e->getID())) {
212 validEdges.push_back(e);
213 }
214 }
215 if (validEdges.size() == 0) {
216 return nullptr;
217 }
218 // filter out edges after the last stop
219 if (myPTStops.size() > 0) {
220 NBEdge* lastStopEdge = ec.retrieve(myPTStops.back()->getEdgeId());
221 if (lastStopEdge == nullptr) {
222 WRITE_WARNINGF(TL("Could not retrieve edge '%' for last stop of line '%'."), myPTStops.back()->getEdgeId(), myPTLineId);
223 return nullptr;
224
225 }
226 auto it = std::find(validEdges.begin(), validEdges.end(), lastStopEdge);
227 if (it == validEdges.end()) {
228 WRITE_WARNINGF(TL("Last stop edge '%' is not part of the route of line '%'."), lastStopEdge->getID(), myPTLineId);
229 return nullptr;
230 }
231 }
232 return validEdges.back();
233}
234
235
236bool
237NBPTLine::isConsistent(const std::vector<NBEdge*>& stops) const {
238 if (myRoute.empty() || stops.empty()) {
239 return true;
240 }
241 std::vector<NBEdge*>::const_iterator stopIt = stops.begin();
242 for (const NBEdge* const e : myRoute) {
243 while (stopIt != stops.end() && e == *stopIt) {
244 ++stopIt;
245 }
246 if (stopIt == stops.end()) {
247 return true;
248 }
249 }
250 return false;
251}
252
253
254void
256 for (int i = 0; i < (int)myPTStops.size(); i++) {
257 if (myPTStops[i] == oldStop) {
258 myPTStops[i] = newStop;
259 }
260 }
261}
262
263
264void
265NBPTLine::replaceEdge(const std::string& edgeID, const EdgeVector& replacement) {
266 EdgeVector oldRoute = myRoute;
267 myRoute.clear();
268 for (NBEdge* e : oldRoute) {
269 if (e->getID() == edgeID) {
270 for (NBEdge* e2 : replacement) {
271 if (myRoute.empty() || myRoute.back() != e2) {
272 myRoute.push_back(e2);
273 }
274 }
275 } else {
276 myRoute.push_back(e);
277 }
278 }
279}
280
281
282void
284 // delete stops that are missing or have no edge
285 for (auto it = myPTStops.begin(); it != myPTStops.end();) {
286 NBPTStop* stop = *it;
287 if (sc.get(stop->getID()) == nullptr ||
288 ec.getByID(stop->getEdgeId()) == nullptr) {
289 WRITE_WARNINGF(TL("Removed invalid stop '%' from line '%'."), stop->getID(), getLineID());
290 it = myPTStops.erase(it);
291 } else {
292 it++;
293 }
294
295 }
296}
297
298
299void
301 // delete subsequent stops that belong to the same stopArea
302 long long int lastAreaID = -1;
303 std::string lastName = "";
304 for (auto it = myPTStops.begin(); it != myPTStops.end();) {
305 NBPTStop* stop = *it;
306 if (lastAreaID != -1 && stop->getAreaID() == lastAreaID) {
307 WRITE_WARNINGF(TL("Removed duplicate stop '%' at area '%' from line '%'."), stop->getID(), toString(lastAreaID), getLineID());
308 it = myPTStops.erase(it);
309 } else if (lastName != "" && stop->getName() == lastName) {
310 WRITE_WARNINGF(TL("Removed duplicate stop '%' named '%' from line '%'."), stop->getID(), lastName, getLineID());
311 it = myPTStops.erase(it);
312 } else {
313 it++;
314 }
315 lastAreaID = stop->getAreaID();
316 lastName = stop->getName();
317 }
318}
319
320
321void
323 for (int i = 0; i < (int)myRoute.size();) {
324 const std::pair<NBEdge*, NBEdge*>* split = ec.getSplit(myRoute[i]);
325 if (split != nullptr) {
326 myRoute[i] = split->first;
327 myRoute.insert(myRoute.begin() + i + 1, split->second);
328 } else if (ec.retrieve(myRoute[i]->getID()) == nullptr) {
329 myRoute.erase(myRoute.begin() + i);
330 } else {
331 i++;
332 }
333 }
334}
335
336
337/****************************************************************************/
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:266
#define TL(string)
Definition: MsgHandler.h:282
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:42
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SUMO_TAG_PT_LINE
A pt line.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ 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_COLOR
A color information.
@ SUMO_ATTR_ID
const double SUMO_const_laneWidth
Definition: StdDefs.h:48
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 * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
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:302
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:274
The representation of a single edge during network building.
Definition: NBEdge.h:92
const std::string & getID() const
Definition: NBEdge.h:1526
void deleteDuplicateStops()
Definition: NBPTLine.cpp:300
std::vector< NBPTStop * > myPTStops
Definition: NBPTLine.h:115
SUMOVehicleClass myVClass
Definition: NBPTLine.h:128
std::string myPTLineId
Definition: NBPTLine.h:119
bool isConsistent(const std::vector< NBEdge * > &stops) const
return whether the mentioned edges appear in that order in the route
Definition: NBPTLine.cpp:237
NBPTLine(const std::string &id, const std::string &name, const std::string &type, const std::string &ref, int interval, const std::string &nightService, SUMOVehicleClass vClass, RGBColor color)
Definition: NBPTLine.cpp:32
void addPTStop(NBPTStop *pStop)
Definition: NBPTLine.cpp:46
std::vector< std::string > myWays
Definition: NBPTLine.h:117
void deleteInvalidStops(const NBEdgeCont &ec, const NBPTStopCont &sc)
remove invalid stops from the line
Definition: NBPTLine.cpp:283
void write(OutputDevice &device)
Definition: NBPTLine.cpp:66
std::vector< NBEdge * > myRoute
Definition: NBPTLine.h:134
const std::vector< NBPTStop * > & getStops()
Definition: NBPTLine.cpp:60
void removeInvalidEdges(const NBEdgeCont &ec)
remove invalid edges from the line
Definition: NBPTLine.cpp:322
int myNumOfStops
Definition: NBPTLine.h:139
std::vector< std::pair< NBEdge *, std::string > > getStopEdges(const NBEdgeCont &ec) const
get stop edges and stop ids
Definition: NBPTLine.cpp:164
int myInterval
Definition: NBPTLine.h:125
std::string myName
Definition: NBPTLine.h:113
RGBColor myColor
Definition: NBPTLine.h:122
const std::string & getLineID() const
Definition: NBPTLine.h:47
std::vector< long long int > * getWaysNodes(std::string wayId)
Definition: NBPTLine.cpp:118
std::string myCurrentWay
Definition: NBPTLine.h:118
std::string myRef
Definition: NBPTLine.h:120
NBEdge * getRouteEnd(const NBEdgeCont &ec) const
return last valid edge of myRoute (if it doest not lie before the last stop)
Definition: NBPTLine.cpp:207
const std::vector< NBEdge * > & getRoute() const
Definition: NBPTLine.cpp:158
void addWayNode(long long int way, long long int node)
Definition: NBPTLine.cpp:107
std::string myType
Definition: NBPTLine.h:114
std::string myNightService
Definition: NBPTLine.h:127
NBEdge * getRouteStart(const NBEdgeCont &ec) const
return first valid edge of myRoute (if it doest not lie after the first stop)
Definition: NBPTLine.cpp:177
std::map< std::string, std::vector< long long int > > myWaysNodes
Definition: NBPTLine.h:116
void setMyNumOfStops(int numStops)
Definition: NBPTLine.cpp:152
void replaceStop(NBPTStop *oldStop, NBPTStop *newStop)
replace the given stop
Definition: NBPTLine.cpp:255
void replaceEdge(const std::string &edgeID, const EdgeVector &replacement)
replace the edge with the given edge list
Definition: NBPTLine.cpp:265
void setEdges(const std::vector< NBEdge * > &edges)
Definition: NBPTLine.cpp:127
NBPTStop * get(std::string id) const
Retrieve a previously inserted pt stop.
The representation of a single pt stop.
Definition: NBPTStop.h:46
std::string getID() const
Definition: NBPTStop.cpp:55
bool isPlatform() const
Definition: NBPTStop.h:113
long long int getAreaID() const
Definition: NBPTStop.h:79
const std::string & getEdgeId() const
Definition: NBPTStop.cpp:67
const std::string getName() const
Definition: NBPTStop.cpp:73
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:251
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool isValid() const
check if RGBColor is valid
Definition: RGBColor.cpp:120
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.