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