Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netbuild/NBPTStop.cpp
193716 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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
/****************************************************************************/
14
/// @file NBPTStop.cpp
15
/// @author Gregor Laemmel
16
/// @date Tue, 20 Mar 2017
17
///
18
// The representation of a single pt stop
19
/****************************************************************************/
20
#include <config.h>
21
22
#include <utils/iodevices/OutputDevice.h>
23
#include <utils/common/StringUtils.h>
24
#include "NBEdge.h"
25
#include "NBEdgeCont.h"
26
#include "NBPTPlatform.h"
27
#include "NBPTStop.h"
28
29
30
// ===========================================================================
31
// method definitions
32
// ===========================================================================
33
NBPTStop::NBPTStop(SumoXMLTag tag, std::string ptStopId, Position position, std::string edgeId, std::string origEdgeId, double length,
34
std::string name, SVCPermissions svcPermissions, double parkingLength, const RGBColor color, double givenStartPos) :
35
myTag(tag),
36
myPTStopId(ptStopId),
37
myPosition(position),
38
myEdgeId(edgeId),
39
myOrigEdgeId(origEdgeId),
40
myPTStopLength(length),
41
myName(name),
42
myParkingLength(parkingLength),
43
myColor(color),
44
myPermissions(svcPermissions),
45
myStartPos(0),
46
myEndPos(0),
47
myBidiStop(std::weak_ptr<NBPTStop>()),
48
myIsLoose(origEdgeId == ""),
49
myIsPlatform(false),
50
myIsMultipleStopPositions(false),
51
myAreaID(-1),
52
myGivenStartPos(givenStartPos) {
53
}
54
55
56
std::string
57
NBPTStop::getID() const {
58
return myPTStopId;
59
}
60
61
62
const std::string
63
NBPTStop::getOrigEdgeId() const {
64
return myOrigEdgeId;
65
}
66
67
68
const std::string&
69
NBPTStop::getEdgeId() const {
70
return myEdgeId;
71
}
72
73
74
const std::string
75
NBPTStop::getName() const {
76
return myName;
77
}
78
79
80
const Position&
81
NBPTStop::getPosition() const {
82
return myPosition;
83
}
84
85
86
void
87
NBPTStop::mirrorX() {
88
myPosition.mul(1, -1);
89
}
90
91
92
void
93
NBPTStop::addLine(const std::string& line) {
94
const std::string l = StringUtils::escapeXML(line);
95
if (std::find(myLines.begin(), myLines.end(), l) == myLines.end()) {
96
myLines.push_back(l);
97
}
98
}
99
100
101
void
102
NBPTStop::write(OutputDevice& device) {
103
device.openTag(myTag);
104
device.writeAttr(SUMO_ATTR_ID, myPTStopId);
105
if (!myName.empty()) {
106
device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myName));
107
}
108
device.writeAttr(SUMO_ATTR_LANE, myLaneId);
109
device.writeAttr(SUMO_ATTR_STARTPOS, myStartPos);
110
device.writeAttr(SUMO_ATTR_ENDPOS, myEndPos);
111
device.writeAttr(SUMO_ATTR_FRIENDLY_POS, "true");
112
if (myLines.size() > 0) {
113
device.writeAttr(SUMO_ATTR_LINES, toString(myLines));
114
}
115
if (myParkingLength > 0) {
116
device.writeAttr(SUMO_ATTR_PARKING_LENGTH, myParkingLength);
117
}
118
if (myColor.isValid()) {
119
device.writeAttr(SUMO_ATTR_COLOR, myColor);
120
}
121
if (!myAccesses.empty()) {
122
std::sort(myAccesses.begin(), myAccesses.end());
123
for (auto tuple : myAccesses) {
124
device.openTag(SUMO_TAG_ACCESS);
125
device.writeAttr(SUMO_ATTR_LANE, std::get<0>(tuple));
126
device.writeAttr(SUMO_ATTR_POSITION, std::get<1>(tuple));
127
device.writeAttr(SUMO_ATTR_LENGTH, std::get<2>(tuple));
128
device.writeAttr(SUMO_ATTR_FRIENDLY_POS, true);
129
device.closeTag();
130
}
131
}
132
writeParams(device);
133
device.closeTag();
134
}
135
136
137
void
138
NBPTStop::reshiftPosition(const double offsetX, const double offsetY) {
139
myPosition.add(offsetX, offsetY, 0);
140
for (NBPTPlatform& platformCand : myPlatformCands) {
141
platformCand.reshiftPosition(offsetX, offsetY);
142
}
143
}
144
145
146
SVCPermissions
147
NBPTStop::getPermissions() const {
148
return myPermissions;
149
}
150
151
152
void
153
NBPTStop::addPlatformCand(NBPTPlatform platform) {
154
myPlatformCands.push_back(platform);
155
}
156
157
158
const std::vector<NBPTPlatform>&
159
NBPTStop::getPlatformCands() {
160
return myPlatformCands;
161
}
162
163
164
bool
165
NBPTStop::getIsMultipleStopPositions() const {
166
return myIsMultipleStopPositions;
167
}
168
169
170
void
171
NBPTStop::setIsMultipleStopPositions(bool multipleStopPositions, long long int areaID) {
172
myIsMultipleStopPositions = multipleStopPositions;
173
myAreaID = areaID;
174
}
175
176
177
double
178
NBPTStop::getLength() const {
179
return myPTStopLength;
180
}
181
182
183
bool
184
NBPTStop::setEdgeId(std::string edgeId, const NBEdgeCont& ec) {
185
myEdgeId = edgeId;
186
return findLaneAndComputeBusStopExtent(ec);
187
}
188
189
190
void
191
NBPTStop::registerAdditionalEdge(std::string wayId, std::string edgeId) {
192
myAdditionalEdgeCandidates[wayId] = edgeId;
193
}
194
195
196
bool
197
NBPTStop::findLaneAndComputeBusStopExtent(const NBEdgeCont& ec) {
198
NBEdge* edge = ec.getByID(myEdgeId);
199
return findLaneAndComputeBusStopExtent(edge);
200
}
201
202
203
bool
204
NBPTStop::findLaneAndComputeBusStopExtent(const NBEdge* edge) {
205
if (edge != nullptr) {
206
myEdgeId = edge->getID();
207
int laneNr = -1;
208
for (const auto& it : edge->getLanes()) {
209
if ((it.permissions & getPermissions()) == getPermissions()) {
210
++laneNr;
211
break;
212
}
213
laneNr++;
214
}
215
if (laneNr != -1) {
216
myLaneId = edge->getLaneID(laneNr);
217
const PositionVector& shape = edge->getLaneShape(laneNr);
218
double offset = shape.nearest_offset_to_point2D(getPosition(), false);
219
const double edgeLength = edge->getFinalLength();
220
offset *= edgeLength / shape.length2D();
221
if (wasLoaded()) {
222
myStartPos = myGivenStartPos;
223
myEndPos = myStartPos + myPTStopLength;
224
} else {
225
myStartPos = MAX2(0.0, offset - myPTStopLength / 2.);
226
myEndPos = MIN2(myStartPos + myPTStopLength, edgeLength);
227
double missing = myPTStopLength - (myEndPos - myStartPos);
228
if (missing > 0) {
229
myStartPos = MAX2(0.0, myStartPos - missing);
230
}
231
}
232
return true;
233
}
234
}
235
return myEdgeId == ""; // loose stop. Try later when processing lines
236
}
237
238
239
void
240
NBPTStop::clearAccess() {
241
myAccesses.clear();
242
}
243
244
245
void
246
NBPTStop::addAccess(std::string laneID, double offset, double length) {
247
const std::string newEdgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
248
// avoid duplicate access
249
for (auto it = myAccesses.begin(); it != myAccesses.end();) {
250
if (SUMOXMLDefinitions::getEdgeIDFromLane(std::get<0>(*it)) == newEdgeID) {
251
it = myAccesses.erase(it);
252
} else {
253
it++;
254
}
255
}
256
myAccesses.push_back(std::make_tuple(laneID, offset, length));
257
}
258
259
260
bool
261
NBPTStop::replaceEdge(const std::string& edgeID, const EdgeVector& replacement) {
262
if (myEdgeId == edgeID) {
263
// find best edge among replacement edges
264
double bestDist = std::numeric_limits<double>::max();
265
NBEdge* bestEdge = nullptr;
266
for (NBEdge* cand : replacement) {
267
if (myPermissions == 0 || (cand->getPermissions() & myPermissions) != 0) {
268
const double dist = cand->getGeometry().distance2D(myPosition) + MAX2(0., myPTStopLength - cand->getLoadedLength());
269
if (dist < bestDist) {
270
bestDist = dist;
271
bestEdge = cand;
272
}
273
}
274
}
275
if (bestEdge != nullptr) {
276
if ((bestEdge->getPermissions() & SVC_PEDESTRIAN) != 0) {
277
// no need for access
278
clearAccess();
279
}
280
return findLaneAndComputeBusStopExtent(bestEdge);
281
}
282
return false;
283
}
284
return true;
285
}
286
287
288
/****************************************************************************/
289
290