LCOV - code coverage report
Current view: top level - src/netbuild - NBPTStop.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 98.5 % 135 133
Test Date: 2026-03-02 16:00:03 Functions: 100.0 % 23 23

            Line data    Source code
       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         2252 : NBPTStop::NBPTStop(SumoXMLTag tag, std::string ptStopId, Position position, std::string edgeId, std::string origEdgeId, double length,
      34         2252 :                    std::string name, SVCPermissions svcPermissions, double parkingLength, const RGBColor color, double givenStartPos) :
      35         2252 :     myTag(tag),
      36         2252 :     myPTStopId(ptStopId),
      37         2252 :     myPosition(position),
      38         2252 :     myEdgeId(edgeId),
      39         2252 :     myOrigEdgeId(origEdgeId),
      40         2252 :     myPTStopLength(length),
      41         2252 :     myName(name),
      42         2252 :     myParkingLength(parkingLength),
      43         2252 :     myColor(color),
      44         2252 :     myPermissions(svcPermissions),
      45         2252 :     myStartPos(0),
      46         2252 :     myEndPos(0),
      47              :     myBidiStop(std::weak_ptr<NBPTStop>()),
      48         2252 :     myIsLoose(origEdgeId == ""),
      49         2252 :     myIsPlatform(false),
      50         2252 :     myIsMultipleStopPositions(false),
      51         2252 :     myAreaID(-1),
      52         2252 :     myGivenStartPos(givenStartPos) {
      53         2252 : }
      54              : 
      55              : 
      56              : std::string
      57        14449 : NBPTStop::getID() const {
      58        14449 :     return myPTStopId;
      59              : }
      60              : 
      61              : 
      62              : const std::string
      63        39351 : NBPTStop::getOrigEdgeId() const {
      64        39351 :     return myOrigEdgeId;
      65              : }
      66              : 
      67              : 
      68              : const std::string&
      69        31038 : NBPTStop::getEdgeId() const {
      70        31038 :     return myEdgeId;
      71              : }
      72              : 
      73              : 
      74              : const std::string
      75         9664 : NBPTStop::getName() const {
      76         9664 :     return myName;
      77              : }
      78              : 
      79              : 
      80              : const Position&
      81         7718 : NBPTStop::getPosition() const {
      82         7718 :     return myPosition;
      83              : }
      84              : 
      85              : 
      86              : void
      87           59 : NBPTStop::mirrorX() {
      88              :     myPosition.mul(1, -1);
      89           59 : }
      90              : 
      91              : 
      92              : void
      93         2773 : NBPTStop::addLine(const std::string& line) {
      94         2773 :     const std::string l = StringUtils::escapeXML(line);
      95         2773 :     if (std::find(myLines.begin(), myLines.end(), l) == myLines.end()) {
      96         2352 :         myLines.push_back(l);
      97              :     }
      98         2773 : }
      99              : 
     100              : 
     101              : void
     102          805 : NBPTStop::write(OutputDevice& device) {
     103          805 :     device.openTag(myTag);
     104          805 :     device.writeAttr(SUMO_ATTR_ID, myPTStopId);
     105          805 :     if (!myName.empty()) {
     106         1558 :         device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myName));
     107              :     }
     108          805 :     device.writeAttr(SUMO_ATTR_LANE, myLaneId);
     109          805 :     device.writeAttr(SUMO_ATTR_STARTPOS, myStartPos);
     110          805 :     device.writeAttr(SUMO_ATTR_ENDPOS, myEndPos);
     111          805 :     device.writeAttr(SUMO_ATTR_FRIENDLY_POS, "true");
     112          805 :     if (myLines.size() > 0) {
     113         1112 :         device.writeAttr(SUMO_ATTR_LINES, toString(myLines));
     114              :     }
     115          805 :     if (myParkingLength > 0) {
     116            0 :         device.writeAttr(SUMO_ATTR_PARKING_LENGTH, myParkingLength);
     117              :     }
     118          805 :     if (myColor.isValid()) {
     119            0 :         device.writeAttr(SUMO_ATTR_COLOR, myColor);
     120              :     }
     121          805 :     if (!myAccesses.empty()) {
     122          199 :         std::sort(myAccesses.begin(), myAccesses.end());
     123         1098 :         for (auto tuple : myAccesses) {
     124          899 :             device.openTag(SUMO_TAG_ACCESS);
     125          899 :             device.writeAttr(SUMO_ATTR_LANE, std::get<0>(tuple));
     126          899 :             device.writeAttr(SUMO_ATTR_POSITION, std::get<1>(tuple));
     127          899 :             device.writeAttr(SUMO_ATTR_LENGTH, std::get<2>(tuple));
     128          899 :             device.writeAttr(SUMO_ATTR_FRIENDLY_POS, true);
     129         1798 :             device.closeTag();
     130              :         }
     131              :     }
     132          805 :     writeParams(device);
     133          805 :     device.closeTag();
     134          805 : }
     135              : 
     136              : 
     137              : void
     138         1865 : NBPTStop::reshiftPosition(const double offsetX, const double offsetY) {
     139              :     myPosition.add(offsetX, offsetY, 0);
     140         2927 :     for (NBPTPlatform& platformCand : myPlatformCands) {
     141         1062 :         platformCand.reshiftPosition(offsetX, offsetY);
     142              :     }
     143         1865 : }
     144              : 
     145              : 
     146              : SVCPermissions
     147        10840 : NBPTStop::getPermissions() const {
     148        10840 :     return myPermissions;
     149              : }
     150              : 
     151              : 
     152              : void
     153         1062 : NBPTStop::addPlatformCand(NBPTPlatform platform) {
     154         1062 :     myPlatformCands.push_back(platform);
     155         1062 : }
     156              : 
     157              : 
     158              : const std::vector<NBPTPlatform>&
     159         1450 : NBPTStop::getPlatformCands() {
     160         1450 :     return myPlatformCands;
     161              : }
     162              : 
     163              : 
     164              : bool
     165         1164 : NBPTStop::getIsMultipleStopPositions() const {
     166         1164 :     return myIsMultipleStopPositions;
     167              : }
     168              : 
     169              : 
     170              : void
     171          916 : NBPTStop::setIsMultipleStopPositions(bool multipleStopPositions, long long int areaID) {
     172          916 :     myIsMultipleStopPositions = multipleStopPositions;
     173          916 :     myAreaID = areaID;
     174          916 : }
     175              : 
     176              : 
     177              : double
     178          395 : NBPTStop::getLength() const {
     179          395 :     return myPTStopLength;
     180              : }
     181              : 
     182              : 
     183              : bool
     184          347 : NBPTStop::setEdgeId(std::string edgeId, const NBEdgeCont& ec) {
     185          347 :     myEdgeId = edgeId;
     186          347 :     return findLaneAndComputeBusStopExtent(ec);
     187              : }
     188              : 
     189              : 
     190              : void
     191          198 : NBPTStop::registerAdditionalEdge(std::string wayId, std::string edgeId) {
     192          198 :     myAdditionalEdgeCandidates[wayId] = edgeId;
     193          198 : }
     194              : 
     195              : 
     196              : bool
     197         4262 : NBPTStop::findLaneAndComputeBusStopExtent(const NBEdgeCont& ec) {
     198         4262 :     NBEdge* edge = ec.getByID(myEdgeId);
     199         4262 :     return findLaneAndComputeBusStopExtent(edge);
     200              : }
     201              : 
     202              : 
     203              : bool
     204         4740 : NBPTStop::findLaneAndComputeBusStopExtent(const NBEdge* edge) {
     205         4740 :     if (edge != nullptr) {
     206         4483 :         myEdgeId = edge->getID();
     207              :         int laneNr = -1;
     208         5733 :         for (const auto& it : edge->getLanes()) {
     209         5140 :             if ((it.permissions & getPermissions()) == getPermissions()) {
     210         3890 :                 ++laneNr;
     211         3890 :                 break;
     212              :             }
     213         1250 :             laneNr++;
     214              :         }
     215         4483 :         if (laneNr != -1) {
     216         4483 :             myLaneId = edge->getLaneID(laneNr);
     217         4483 :             const PositionVector& shape = edge->getLaneShape(laneNr);
     218         4483 :             double offset = shape.nearest_offset_to_point2D(getPosition(), false);
     219         4483 :             const double edgeLength = edge->getFinalLength();
     220         4483 :             offset *= edgeLength / shape.length2D();
     221         4483 :             if (wasLoaded()) {
     222          160 :                 myStartPos = myGivenStartPos;
     223          160 :                 myEndPos = myStartPos + myPTStopLength;
     224              :             } else {
     225         4323 :                 myStartPos = MAX2(0.0, offset - myPTStopLength / 2.);
     226         4323 :                 myEndPos = MIN2(myStartPos + myPTStopLength, edgeLength);
     227         4323 :                 double missing = myPTStopLength - (myEndPos - myStartPos);
     228         4323 :                 if (missing > 0) {
     229         3034 :                     myStartPos = MAX2(0.0, myStartPos - missing);
     230              :                 }
     231              :             }
     232         4483 :             return true;
     233              :         }
     234              :     }
     235          257 :     return myEdgeId == ""; // loose stop. Try later when processing lines
     236              : }
     237              : 
     238              : 
     239              : void
     240          228 : NBPTStop::clearAccess() {
     241              :     myAccesses.clear();
     242          228 : }
     243              : 
     244              : 
     245              : void
     246         2811 : NBPTStop::addAccess(std::string laneID, double offset, double length) {
     247         5622 :     const std::string newEdgeID = SUMOXMLDefinitions::getEdgeIDFromLane(laneID);
     248              :     // avoid duplicate access
     249         8281 :     for (auto it = myAccesses.begin(); it != myAccesses.end();) {
     250        10940 :         if (SUMOXMLDefinitions::getEdgeIDFromLane(std::get<0>(*it)) == newEdgeID) {
     251            5 :             it = myAccesses.erase(it);
     252              :         } else {
     253              :             it++;
     254              :         }
     255              :     }
     256         5622 :     myAccesses.push_back(std::make_tuple(laneID, offset, length));
     257         2811 : }
     258              : 
     259              : 
     260              : bool
     261          478 : NBPTStop::replaceEdge(const std::string& edgeID, const EdgeVector& replacement) {
     262          478 :     if (myEdgeId == edgeID) {
     263              :         // find best edge among replacement edges
     264              :         double bestDist = std::numeric_limits<double>::max();
     265              :         NBEdge* bestEdge = nullptr;
     266         1109 :         for (NBEdge* cand : replacement) {
     267          631 :             if (myPermissions == 0 || (cand->getPermissions() & myPermissions) != 0) {
     268         1262 :                 const double dist = cand->getGeometry().distance2D(myPosition) + MAX2(0., myPTStopLength - cand->getLoadedLength());
     269          631 :                 if (dist < bestDist) {
     270              :                     bestDist = dist;
     271              :                     bestEdge = cand;
     272              :                 }
     273              :             }
     274              :         }
     275          478 :         if (bestEdge != nullptr) {
     276          478 :             if ((bestEdge->getPermissions() & SVC_PEDESTRIAN) != 0) {
     277              :                 // no need for access
     278          228 :                 clearAccess();
     279              :             }
     280          478 :             return findLaneAndComputeBusStopExtent(bestEdge);
     281              :         }
     282              :         return false;
     283              :     }
     284              :     return true;
     285              : }
     286              : 
     287              : 
     288              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1