1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file NBPTStop.cpp
11 /// @author Gregor Laemmel
12 /// @date Tue, 20 Mar 2017
13 /// @version $Id$
14 ///
15 // The representation of a single pt stop
16 /****************************************************************************/
17
18
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23
24 #include <utils/iodevices/OutputDevice.h>
25 #include <utils/common/StringUtils.h>
26 #include "NBPTStop.h"
27 #include "NBEdge.h"
28 #include "NBEdgeCont.h"
29
30
31 // ===========================================================================
32 // method definitions
33 // ===========================================================================
NBPTStop(std::string ptStopId,Position position,std::string edgeId,std::string origEdgeId,double length,std::string name,SVCPermissions svcPermissions)34 NBPTStop::NBPTStop(std::string ptStopId, Position position, std::string edgeId, std::string origEdgeId, double length,
35 std::string name, SVCPermissions svcPermissions) :
36 myPTStopId(ptStopId),
37 myPosition(position),
38 myEdgeId(edgeId),
39 myOrigEdgeId(origEdgeId),
40 myPTStopLength(length),
41 myName(name),
42 myPermissions(svcPermissions),
43 myBidiStop(nullptr),
44 myIsMultipleStopPositions(false) {
45 }
46
47 std::string
getID() const48 NBPTStop::getID() const {
49 return myPTStopId;
50 }
51
52 const std::string
getOrigEdgeId() const53 NBPTStop::getOrigEdgeId() const {
54 return myOrigEdgeId;
55 }
56
57
58 const std::string
getEdgeId() const59 NBPTStop::getEdgeId() const {
60 return myEdgeId;
61 }
62
63
64 const std::string
getName() const65 NBPTStop::getName() const {
66 return myName;
67 }
68
69
70 const Position&
getPosition() const71 NBPTStop::getPosition() const {
72 return myPosition;
73 }
74
75
76 void
computeExtent(double center,double edgeLength)77 NBPTStop::computeExtent(double center, double edgeLength) {
78 myStartPos = MAX2(0.0, center - myPTStopLength / 2.);
79 myEndPos = MIN2(center + myPTStopLength / 2., edgeLength);
80 }
81
82
83 void
addLine(const std::string & line)84 NBPTStop::addLine(const std::string& line) {
85 const std::string l = StringUtils::escapeXML(line);
86 if (std::find(myLines.begin(), myLines.end(), l) == myLines.end()) {
87 myLines.push_back(l);
88 }
89 }
90
91
92 void
write(OutputDevice & device)93 NBPTStop::write(OutputDevice& device) {
94 device.openTag(SUMO_TAG_BUS_STOP);
95 device.writeAttr(SUMO_ATTR_ID, myPTStopId);
96 if (!myName.empty()) {
97 device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myName));
98 }
99 device.writeAttr(SUMO_ATTR_LANE, myLaneId);
100 device.writeAttr(SUMO_ATTR_STARTPOS, myStartPos);
101 device.writeAttr(SUMO_ATTR_ENDPOS, myEndPos);
102 device.writeAttr(SUMO_ATTR_FRIENDLY_POS, "true");
103 if (myLines.size() > 0) {
104 device.writeAttr(SUMO_ATTR_LINES, toString(myLines));
105 }
106 if (!myAccesses.empty()) {
107 std::sort(myAccesses.begin(), myAccesses.end());
108 for (auto tuple : myAccesses) {
109 device.openTag(SUMO_TAG_ACCESS);
110 device.writeAttr(SUMO_ATTR_LANE, std::get<0>(tuple));
111 device.writeAttr(SUMO_ATTR_POSITION, std::get<1>(tuple));
112 device.writeAttr(SUMO_ATTR_LENGTH, std::get<2>(tuple));
113 device.writeAttr(SUMO_ATTR_FRIENDLY_POS, true);
114 device.closeTag();
115 }
116 }
117 device.closeTag();
118 }
119
120
121 void
reshiftPosition(const double offsetX,const double offsetY)122 NBPTStop::reshiftPosition(const double offsetX, const double offsetY) {
123 myPosition.add(offsetX, offsetY, 0);
124 for (NBPTPlatform& platformCand : myPlatformCands) {
125 platformCand.reshiftPosition(offsetX, offsetY);
126 }
127 }
128
129
130 SVCPermissions
getPermissions() const131 NBPTStop::getPermissions() const {
132 return myPermissions;
133 }
134
135
136 void
addPlatformCand(NBPTPlatform platform)137 NBPTStop::addPlatformCand(NBPTPlatform platform) {
138 myPlatformCands.push_back(platform);
139 }
140
141
142 const std::vector<NBPTPlatform>&
getPlatformCands()143 NBPTStop::getPlatformCands() {
144 return myPlatformCands;
145 }
146
147
148 bool
getIsMultipleStopPositions() const149 NBPTStop::getIsMultipleStopPositions() const {
150 return myIsMultipleStopPositions;
151 }
152
153
154 void
setIsMultipleStopPositions(bool multipleStopPositions)155 NBPTStop::setIsMultipleStopPositions(bool multipleStopPositions) {
156 myIsMultipleStopPositions = multipleStopPositions;
157 }
158
159
160 double
getLength() const161 NBPTStop::getLength() const {
162 return myPTStopLength;
163 }
164
165
166 bool
setEdgeId(std::string edgeId,NBEdgeCont & ec)167 NBPTStop::setEdgeId(std::string edgeId, NBEdgeCont& ec) {
168 myEdgeId = edgeId;
169 return findLaneAndComputeBusStopExtent(ec);
170 }
171
172
173 void
registerAdditionalEdge(std::string wayId,std::string edgeId)174 NBPTStop::registerAdditionalEdge(std::string wayId, std::string edgeId) {
175 myAdditionalEdgeCandidates[wayId] = edgeId;
176 }
177
178
179 const std::map<std::string, std::string>&
getMyAdditionalEdgeCandidates() const180 NBPTStop::getMyAdditionalEdgeCandidates() const {
181 return myAdditionalEdgeCandidates;
182 }
183
184
185 void
setMyOrigEdgeId(const std::string & myOrigEdgeId)186 NBPTStop::setMyOrigEdgeId(const std::string& myOrigEdgeId) {
187 NBPTStop::myOrigEdgeId = myOrigEdgeId;
188 }
189
190
191 void
setMyPTStopLength(double myPTStopLength)192 NBPTStop::setMyPTStopLength(double myPTStopLength) {
193 NBPTStop::myPTStopLength = myPTStopLength;
194 }
195
196
197 bool
findLaneAndComputeBusStopExtent(NBEdgeCont & ec)198 NBPTStop::findLaneAndComputeBusStopExtent(NBEdgeCont& ec) {
199 NBEdge* edge = ec.getByID(myEdgeId);
200 if (edge != nullptr) {
201 int laneNr = -1;
202 for (const auto& it : edge->getLanes()) {
203 if ((it.permissions & getPermissions()) > 0) {
204 ++laneNr;
205 break;
206 }
207 laneNr++;
208 }
209 if (laneNr != -1) {
210 myLaneId = edge->getLaneID(laneNr);
211 const PositionVector& shape = edge->getLaneShape(laneNr);
212 double offset = shape.nearest_offset_to_point2D(getPosition(), false);
213 computeExtent(offset, shape.length());
214 return true;
215 }
216 }
217 return false;
218 }
219
220
221 void
setMyPTStopId(std::string id)222 NBPTStop::setMyPTStopId(std::string id) {
223 myPTStopId = id;
224 }
225
226 void
clearAccess()227 NBPTStop::clearAccess() {
228 myAccesses.clear();
229 }
230
231 void
addAccess(std::string laneID,double offset,double length)232 NBPTStop::addAccess(std::string laneID, double offset, double length) {
233 const std::string newEdgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
234 // avoid duplicate access
235 for (auto it = myAccesses.begin(); it != myAccesses.end();) {
236 if (SUMOXMLDefinitions::getEdgeIDFromLane(std::get<0>(*it)) == newEdgeID) {
237 it = myAccesses.erase(it);
238 } else {
239 it++;
240 }
241 }
242 myAccesses.push_back(std::make_tuple(laneID, offset, length));
243 }
244
245
246 /****************************************************************************/
247