LCOV - code coverage report
Current view: top level - src/netbuild - NBPTStop.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 128 129 99.2 %
Date: 2024-05-07 15:28:01 Functions: 23 23 100.0 %

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

Generated by: LCOV version 1.14