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>
24 #include <utils/common/ToString.h>
27 #include "NBEdgeCont.h"
28 #include "NBPTStopCont.h"
29 #include "NBPTLine.h"
30 #include "NBPTStop.h"
31 
32 NBPTLine::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 
45  if (!myPTStops.empty() && pStop->getName() != "" && myPTStops.back()->getName() == pStop->getName()) {
46  // avoid duplicate stop when both platform and stop_position are given as nodes
47  if (myPTStops.back()->isPlatform() && !pStop->isPlatform()) {
48  myPTStops.pop_back();
49  } else if (pStop->isPlatform()) {
50  return;
51  }
52  }
53  myPTStops.push_back(pStop);
54 }
55 
56 std::vector<NBPTStop*> NBPTLine::getStops() {
57  return myPTStops;
58 }
59 
61  device.openTag(SUMO_TAG_PT_LINE);
63  if (!myName.empty()) {
65  }
66 
70  if (myInterval > 0) {
71  // write seconds
73  }
74  if (myNightService != "") {
75  device.writeAttr("nightService", myNightService);
76  }
77 
78  if (myColor.isValid()) {
80  }
81  device.writeAttr("completeness", toString((double)myPTStops.size() / (double)myNumOfStops));
82 
83  if (!myRoute.empty()) {
84  device.openTag(SUMO_TAG_ROUTE);
86  device.closeTag();
87  }
88 
89  for (auto& myPTStop : myPTStops) {
90  device.openTag(SUMO_TAG_BUS_STOP);
91  device.writeAttr(SUMO_ATTR_ID, myPTStop->getID());
92  device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myPTStop->getName()));
93  device.closeTag();
94  }
95  device.closeTag();
96 
97 }
98 
99 void NBPTLine::addWayNode(long long int way, long long int node) {
100  std::string wayStr = toString(way);
101  if (wayStr != myCurrentWay) {
102  myCurrentWay = wayStr;
103  myWays.push_back(wayStr);
104  }
105  myWaysNodes[wayStr].push_back(node);
106 
107 }
108 const std::vector<std::string>& NBPTLine::getMyWays() const {
109  return myWays;
110 }
111 std::vector<long long int>* NBPTLine::getWaysNodes(std::string wayId) {
112  if (myWaysNodes.find(wayId) != myWaysNodes.end()) {
113  return &myWaysNodes[wayId];
114  }
115  return nullptr;
116 }
117 
118 void
119 NBPTLine::setEdges(const std::vector<NBEdge*>& edges) {
120  myRoute = edges;
121  // ensure permissions
122  for (NBEdge* e : edges) {
123  SVCPermissions permissions = e->getPermissions();
124  if ((permissions & myVClass) != myVClass) {
126  if (permissions != 0 && (permissions & nVuln) == 0) {
127  // this is a footpath or sidewalk. Add another lane
128  e->addRestrictedLane(SUMO_const_laneWidth, myVClass);
129  } else {
130  // add permissions to the rightmost lane that is not exclusively used for pedestrians / bicycles
131  for (int i = 0; i < (int)e->getNumLanes(); i++) {
132  if ((e->getPermissions(i) & nVuln) != 0) {
133  e->allowVehicleClass(i, myVClass);
134  break;
135  }
136  }
137  }
138  }
139  }
140 }
141 
142 void NBPTLine::setMyNumOfStops(int numStops) {
143  myNumOfStops = numStops;
144 }
145 const std::vector<NBEdge*>& NBPTLine::getRoute() const {
146  return myRoute;
147 }
148 
149 std::vector<NBEdge*>
151  std::vector<NBEdge*> result;
152  for (NBPTStop* stop : myPTStops) {
153  NBEdge* e = ec.retrieve(stop->getEdgeId());
154  if (e != nullptr) {
155  result.push_back(e);
156  }
157  }
158  return result;
159 }
160 
161 NBEdge*
163  std::vector<NBEdge*> validEdges;
164  // filter out edges that have been removed due to joining junctions
165  for (NBEdge* e : myRoute) {
166  if (ec.retrieve(e->getID())) {
167  validEdges.push_back(e);
168  }
169  }
170  if (validEdges.size() == 0) {
171  return nullptr;
172  }
173  // filter out edges after the first stop
174  if (myPTStops.size() > 0) {
175  NBEdge* firstStopEdge = ec.retrieve(myPTStops.front()->getEdgeId());
176  if (firstStopEdge == nullptr) {
177  WRITE_WARNINGF("Could not retrieve edge '%' for first stop of line '%'.", myPTStops.front()->getEdgeId(), myPTLineId);
178  return nullptr;
179 
180  }
181  auto it = std::find(validEdges.begin(), validEdges.end(), firstStopEdge);
182  if (it == validEdges.end()) {
183  WRITE_WARNINGF("First stop edge '%' is not part of the route of line '%'.", firstStopEdge->getID(), myPTLineId);
184  return nullptr;
185  }
186  }
187  return validEdges.front();
188 }
189 
190 NBEdge*
192  std::vector<NBEdge*> validEdges;
193  // filter out edges that have been removed due to joining junctions
194  for (NBEdge* e : myRoute) {
195  if (ec.retrieve(e->getID())) {
196  validEdges.push_back(e);
197  }
198  }
199  if (validEdges.size() == 0) {
200  return nullptr;
201  }
202  // filter out edges after the last stop
203  if (myPTStops.size() > 0) {
204  NBEdge* lastStopEdge = ec.retrieve(myPTStops.back()->getEdgeId());
205  if (lastStopEdge == nullptr) {
206  WRITE_WARNINGF("Could not retrieve edge '%' for last stop of line '%'.", myPTStops.back()->getEdgeId(), myPTLineId);
207  return nullptr;
208 
209  }
210  auto it = std::find(validEdges.begin(), validEdges.end(), lastStopEdge);
211  if (it == validEdges.end()) {
212  WRITE_WARNINGF("Last stop edge '%' is not part of the route of line '%'.", lastStopEdge->getID(), myPTLineId);
213  return nullptr;
214  }
215  }
216  return validEdges.back();
217 }
218 
219 void
221  for (int i = 0; i < (int)myPTStops.size(); i++) {
222  if (myPTStops[i] == oldStop) {
223  myPTStops[i] = newStop;
224  }
225  }
226 }
227 
228 void
229 NBPTLine::replaceEdge(const std::string& edgeID, const EdgeVector& replacement) {
230  EdgeVector oldRoute = myRoute;
231  myRoute.clear();
232  for (NBEdge* e : oldRoute) {
233  if (e->getID() == edgeID) {
234  for (NBEdge* e2 : replacement) {
235  if (myRoute.empty() || myRoute.back() != e2) {
236  myRoute.push_back(e2);
237  }
238  }
239  } else {
240  myRoute.push_back(e);
241  }
242  }
243 }
244 
245 void
247  // delete stops that are missing or have no edge
248  for (auto it = myPTStops.begin(); it != myPTStops.end();) {
249  NBPTStop* stop = *it;
250  if (sc.get(stop->getID()) == nullptr ||
251  ec.getByID(stop->getEdgeId()) == nullptr) {
252  WRITE_WARNINGF("Removed invalid stop '%' from line '%'.", stop->getID(), getLineID());
253  it = myPTStops.erase(it);
254  } else {
255  it++;
256  }
257 
258  }
259 }
260 
261 void
263  // delete subsequent stops that belong to the same stopArea
264  long long int lastAreaID = -1;
265  std::string lastName = "";
266  for (auto it = myPTStops.begin(); it != myPTStops.end();) {
267  NBPTStop* stop = *it;
268  if (lastAreaID != -1 && stop->getAreaID() == lastAreaID) {
269  WRITE_WARNINGF("Removed duplicate stop '%' at area '%' from line '%'.", stop->getID(), toString(lastAreaID), getLineID());
270  it = myPTStops.erase(it);
271  } else if (lastName != "" && stop->getName() == lastName) {
272  WRITE_WARNINGF("Removed duplicate stop '%' named '%' from line '%'.", stop->getID(), lastName, getLineID());
273  it = myPTStops.erase(it);
274  } else {
275  it++;
276  }
277  lastAreaID = stop->getAreaID();
278  lastName = stop->getName();
279  }
280 }
281 
282 void
284  for (auto it = myRoute.begin(); it != myRoute.end();) {
285  NBEdge* e = *it;
286  if (ec.retrieve(e->getID())) {
287  it++;
288  } else {
289  it = myRoute.erase(it);
290  }
291  }
292 }
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:281
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
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.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:275
The representation of a single edge during network building.
Definition: NBEdge.h:91
const std::string & getID() const
Definition: NBEdge.h:1465
void deleteDuplicateStops()
Definition: NBPTLine.cpp:262
std::vector< NBPTStop * > myPTStops
Definition: NBPTLine.h:106
SUMOVehicleClass myVClass
Definition: NBPTLine.h:126
std::string myPTLineId
Definition: NBPTLine.h:117
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:44
std::vector< std::string > myWays
Definition: NBPTLine.h:110
void deleteInvalidStops(const NBEdgeCont &ec, const NBPTStopCont &sc)
remove invalid stops from the line
Definition: NBPTLine.cpp:246
void write(OutputDevice &device)
Definition: NBPTLine.cpp:60
std::vector< NBEdge * > myRoute
Definition: NBPTLine.h:132
void removeInvalidEdges(const NBEdgeCont &ec)
remove invalid edges from the line
Definition: NBPTLine.cpp:283
const std::vector< std::string > & getMyWays() const
Definition: NBPTLine.cpp:108
int myNumOfStops
Definition: NBPTLine.h:137
const std::string & getLineID() const
Definition: NBPTLine.h:47
int myInterval
Definition: NBPTLine.h:123
std::string myName
Definition: NBPTLine.h:104
RGBColor myColor
Definition: NBPTLine.h:120
std::vector< long long int > * getWaysNodes(std::string wayId)
Definition: NBPTLine.cpp:111
std::string myCurrentWay
Definition: NBPTLine.h:116
std::string myRef
Definition: NBPTLine.h:118
NBEdge * getRouteEnd(const NBEdgeCont &ec) const
return last valid edge of myRoute (if it doest not lie before the last stop)
Definition: NBPTLine.cpp:191
const std::vector< NBEdge * > & getRoute() const
Definition: NBPTLine.cpp:145
void addWayNode(long long int way, long long int node)
Definition: NBPTLine.cpp:99
std::string myType
Definition: NBPTLine.h:105
std::string myNightService
Definition: NBPTLine.h:125
NBEdge * getRouteStart(const NBEdgeCont &ec) const
return first valid edge of myRoute (if it doest not lie after the first stop)
Definition: NBPTLine.cpp:162
std::map< std::string, std::vector< long long int > > myWaysNodes
Definition: NBPTLine.h:109
std::vector< NBEdge * > getStopEdges(const NBEdgeCont &ec) const
get stop edges
Definition: NBPTLine.cpp:150
void setMyNumOfStops(int numStops)
Definition: NBPTLine.cpp:142
void replaceStop(NBPTStop *oldStop, NBPTStop *newStop)
replace the given stop
Definition: NBPTLine.cpp:220
void replaceEdge(const std::string &edgeID, const EdgeVector &replacement)
replace the edge with the given edge list
Definition: NBPTLine.cpp:229
std::vector< NBPTStop * > getStops()
Definition: NBPTLine.cpp:56
void setEdges(const std::vector< NBEdge * > &edges)
Definition: NBPTLine.cpp:119
NBPTStop * get(std::string id) const
Retrieve a previously inserted pt stop.
The representation of a single pt stop.
Definition: NBPTStop.h:46
const std::string getEdgeId() const
Definition: NBPTStop.cpp:66
std::string getID() const
Definition: NBPTStop.cpp:54
bool isPlatform() const
Definition: NBPTStop.h:108
long long int getAreaID() const
Definition: NBPTStop.h:74
const std::string getName() const
Definition: NBPTStop.cpp:72
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
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.