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

Generated by: LCOV version 2.0-1