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

Generated by: LCOV version 2.0-1