LCOV - code coverage report
Current view: top level - src/microsim - MSParkingArea.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 88.5 % 261 231
Test Date: 2024-11-22 15:46:21 Functions: 87.2 % 39 34

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2015-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    MSParkingArea.cpp
      15              : /// @author  Mirco Sturari
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Mirko Barthauer
      18              : /// @date    Tue, 19.01.2016
      19              : ///
      20              : // A area where vehicles can park next to the road
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <utils/common/WrappingCommand.h>
      26              : #include <utils/vehicle/SUMOVehicle.h>
      27              : #include <utils/geom/Position.h>
      28              : #include <utils/geom/GeomHelper.h>
      29              : #include <microsim/MSEventControl.h>
      30              : #include <microsim/MSNet.h>
      31              : #include <microsim/MSVehicle.h>
      32              : #include <microsim/MSVehicleType.h>
      33              : #include "MSLane.h"
      34              : #include <microsim/transportables/MSTransportable.h>
      35              : #include "MSParkingArea.h"
      36              : #include "MSGlobals.h"
      37              : 
      38              : //#define DEBUG_RESERVATIONS
      39              : //#define DEBUG_GET_LAST_FREE_POS
      40              : //#define DEBUG_COND2(obj) (obj.getID() == "v.3")
      41              : #define DEBUG_COND2(obj) (obj.isSelected())
      42              : 
      43              : 
      44              : // ===========================================================================
      45              : // method definitions
      46              : // ===========================================================================
      47        13247 : MSParkingArea::MSParkingArea(const std::string& id, const std::vector<std::string>& lines,
      48              :                              const std::vector<std::string>& badges, MSLane& lane,
      49              :                              double begPos, double endPos, int capacity, double width, double length,
      50              :                              double angle, const std::string& name, bool onRoad,
      51        13247 :                              const std::string& departPos, bool lefthand) :
      52              :     MSStoppingPlace(id, SUMO_TAG_PARKING_AREA, lines, lane, begPos, endPos, name),
      53        13247 :     myRoadSideCapacity(capacity),
      54        13247 :     myCapacity(0),
      55        13247 :     myOnRoad(onRoad),
      56        13247 :     myWidth(width),
      57        13247 :     myLength(length),
      58        13247 :     myAngle(lefthand ? -angle : angle),
      59        13247 :     myAcceptedBadges(badges.begin(), badges.end()),
      60        13247 :     myEgressBlocked(false),
      61        13247 :     myReservationTime(-1),
      62        13247 :     myReservations(0),
      63        13247 :     myReservationMaxLength(0),
      64        13247 :     myNumAlternatives(0),
      65        13247 :     myLastStepOccupancy(0),
      66        13247 :     myDepartPos(-1),
      67        13247 :     myDepartPosDefinition(DepartPosDefinition::DEFAULT),
      68        26508 :     myUpdateEvent(nullptr) {
      69              :     // initialize unspecified defaults
      70        13247 :     if (myWidth == 0) {
      71        11276 :         myWidth = SUMO_const_laneWidth;
      72              :     }
      73              : 
      74        13247 :     if (departPos != "") {
      75              :         std::string error;
      76           58 :         if (!SUMOVehicleParameter::parseDepartPos(departPos, toString(myElement), getID(), myDepartPos, myDepartPosDefinition, error)) {
      77            0 :             throw ProcessError(error);
      78              :         }
      79           29 :         if (myDepartPosDefinition != DepartPosDefinition::GIVEN) {
      80              :             // maybe allow other methods at a later time
      81            0 :             throw ProcessError("Only a numerical departPos is supported for " + toString(myElement) + " '" + getID() + "'");
      82           29 :         } else if (myDepartPos < 0 || myDepartPos > lane.getLength()) {
      83            0 :             throw ProcessError("Invalid departPos for " + toString(myElement) + " '" + getID() + "'");
      84              :         }
      85              :     }
      86              : 
      87        13247 :     const double offset = (MSGlobals::gLefthand != lefthand) ? -1 : 1;
      88        26494 :     myShape = lane.getShape().getSubpart(
      89              :                   lane.interpolateLanePosToGeometryPos(begPos),
      90              :                   lane.interpolateLanePosToGeometryPos(endPos));
      91        13247 :     if (!myOnRoad) {
      92        13186 :         myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset);
      93              :     }
      94        13247 :     setRoadsideCapacity(capacity);
      95        13247 : }
      96              : 
      97              : 
      98        25756 : MSParkingArea::~MSParkingArea() {}
      99              : 
     100              : 
     101              : void
     102        48499 : MSParkingArea::addLotEntry(double x, double y, double z, double width, double length, double angle, double slope) {
     103              :     // create LotSpaceDefinition
     104        48499 :     LotSpaceDefinition lsd((int)mySpaceOccupancies.size(), nullptr, x, y, z, angle, slope, width, length);
     105              :     // If we are modelling parking set the end position to the lot position relative to the lane
     106              :     // rather than the end of the parking area - this results in vehicles stopping nearer the space
     107              :     // and re-entering the lane nearer the space. (If we are not modelling parking the vehicle will usually
     108              :     // enter the space and re-enter at the end of the parking area.)
     109        48499 :     if (MSGlobals::gModelParkingManoeuver) {
     110           30 :         const double offset = this->getLane().getShape().nearest_offset_to_point2D(lsd.position);
     111           30 :         if (offset <  getBeginLanePosition()) {
     112            0 :             lsd.endPos =  getBeginLanePosition() + POSITION_EPS;
     113              :         } else {
     114           30 :             if (this->getLane().getLength() > offset) {
     115           30 :                 lsd.endPos = offset;
     116              :             } else {
     117            0 :                 lsd.endPos = this->getLane().getLength() - POSITION_EPS;
     118              :             }
     119              :         }
     120              :         // Work out the angle of the lot relative to the lane  (-90 adjusts for the way the bay is drawn )
     121           30 :         double relativeAngle = fmod(lsd.rotation - 90., 360) - fmod(RAD2DEG(this->getLane().getShape().rotationAtOffset(lsd.endPos)), 360) + 0.5;
     122           30 :         if (relativeAngle < 0.) {
     123           10 :             relativeAngle += 360.;
     124              :         }
     125           30 :         lsd.manoeuverAngle = relativeAngle;
     126              : 
     127              :         // if p2.y is -ve the lot is on LHS of lane relative to lane direction
     128              :         // we need to know this because it inverts the complexity of the parking manoeuver
     129           30 :         Position p2 = this->getLane().getShape().transformToVectorCoordinates(lsd.position);
     130           30 :         if (p2.y() < (0. + POSITION_EPS)) {
     131           30 :             lsd.sideIsLHS = true;
     132              :         } else {
     133            0 :             lsd.sideIsLHS = false;
     134              :         }
     135              :     } else {
     136        48469 :         lsd.endPos = myEndPos;
     137        48469 :         lsd.manoeuverAngle = int(angle); // unused unless gModelParkingManoeuver is true
     138        48469 :         lsd.sideIsLHS = true;
     139              :     }
     140        48499 :     mySpaceOccupancies.push_back(lsd);
     141        48499 :     myCapacity++;
     142        48499 :     computeLastFreePos();
     143        48499 : }
     144              : 
     145              : int
     146           30 : MSParkingArea::getLastFreeLotAngle() const {
     147              :     assert(myLastFreeLot >= 0);
     148              :     assert(myLastFreeLot < (int)mySpaceOccupancies.size());
     149              : 
     150           30 :     const LotSpaceDefinition& lsd = mySpaceOccupancies[myLastFreeLot];
     151           30 :     if (lsd.sideIsLHS) {
     152           30 :         return abs(int(lsd.manoeuverAngle)) % 180;
     153              :     } else {
     154            0 :         return abs(abs(int(lsd.manoeuverAngle)) % 180 - 180) % 180;
     155              :     }
     156              : }
     157              : 
     158              : double
     159           30 : MSParkingArea::getLastFreeLotGUIAngle() const {
     160              :     assert(myLastFreeLot >= 0);
     161              :     assert(myLastFreeLot < (int)mySpaceOccupancies.size());
     162              : 
     163           30 :     const LotSpaceDefinition& lsd = mySpaceOccupancies[myLastFreeLot];
     164           30 :     if (lsd.manoeuverAngle > 180.) {
     165           15 :         return DEG2RAD(lsd.manoeuverAngle - 360.);
     166              :     } else {
     167           15 :         return DEG2RAD(lsd.manoeuverAngle);
     168              :     }
     169              : }
     170              : 
     171              : 
     172              : double
     173      1322654 : MSParkingArea::getLastFreePos(const SUMOVehicle& forVehicle, double brakePos) const {
     174      1322654 :     if (myCapacity == (int)myEndPositions.size()) {
     175              :         // keep enough space so that  parking vehicles can leave
     176              : #ifdef DEBUG_GET_LAST_FREE_POS
     177              :         if (DEBUG_COND2(forVehicle)) {
     178              :             std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " allOccupied\n";
     179              :         }
     180              : #endif
     181       762629 :         return myLastFreePos - forVehicle.getVehicleType().getMinGap() - POSITION_EPS;
     182              :     } else {
     183       560025 :         const double minPos = MIN2(myEndPos, brakePos);
     184       560025 :         if (myLastFreePos >= minPos) {
     185              : #ifdef DEBUG_GET_LAST_FREE_POS
     186              :             if (DEBUG_COND2(forVehicle)) {
     187              :                 std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " using myLastFreePos=" << myLastFreePos << "\n";
     188              :             }
     189              : #endif
     190              :             return myLastFreePos;
     191              :         } else {
     192              :             // find free pos after minPos
     193        39490 :             for (const auto& lsd : mySpaceOccupancies) {
     194        38773 :                 if (lsd.vehicle == nullptr && lsd.endPos >= minPos) {
     195              : #ifdef DEBUG_GET_LAST_FREE_POS
     196              :                     if (DEBUG_COND2(forVehicle)) {
     197              :                         std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " nextFreePos=" << lsd.endPos << "\n";
     198              :                     }
     199              : #endif
     200              :                     return lsd.endPos;
     201              :                 }
     202              :             }
     203              :             // shouldn't happen. No good solution seems possible
     204              : #ifdef DEBUG_GET_LAST_FREE_POS
     205              :             if (DEBUG_COND2(forVehicle)) {
     206              :                 std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " noGoodFreePos blockedAt=" << brakePos << "\n";
     207              :             }
     208              : #endif
     209              :             return brakePos;
     210              :         }
     211              :     }
     212              : }
     213              : 
     214              : Position
     215        14022 : MSParkingArea::getVehiclePosition(const SUMOVehicle& forVehicle) const {
     216        34080 :     for (const auto& lsd : mySpaceOccupancies) {
     217        34080 :         if (lsd.vehicle == &forVehicle) {
     218        14022 :             return lsd.position;
     219              :         }
     220              :     }
     221            0 :     return Position::INVALID;
     222              : }
     223              : 
     224              : 
     225              : double
     226        69055 : MSParkingArea::getInsertionPosition(const SUMOVehicle& forVehicle) const {
     227        69055 :     if (myDepartPosDefinition == DepartPosDefinition::GIVEN) {
     228          250 :         return myDepartPos;
     229              :     }
     230       193991 :     for (const auto& lsd : mySpaceOccupancies) {
     231       193983 :         if (lsd.vehicle == &forVehicle) {
     232        68797 :             return lsd.endPos;
     233              :         }
     234              :     }
     235              :     return -1;
     236              : }
     237              : 
     238              : 
     239              : double
     240        12588 : MSParkingArea::getVehicleAngle(const SUMOVehicle& forVehicle) const {
     241        34386 :     for (const auto& lsd : mySpaceOccupancies) {
     242        34369 :         if (lsd.vehicle == &forVehicle) {
     243        12571 :             return (lsd.rotation - 90.) * (double) M_PI / (double) 180.0;
     244              :         }
     245              :     }
     246              :     return 0;
     247              : }
     248              : 
     249              : double
     250         3621 : MSParkingArea::getVehicleSlope(const SUMOVehicle& forVehicle) const {
     251        12171 :     for (const auto& lsd : mySpaceOccupancies) {
     252        12171 :         if (lsd.vehicle == &forVehicle) {
     253         3621 :             return lsd.slope;
     254              :         }
     255              :     }
     256              :     return 0;
     257              : }
     258              : 
     259              : double
     260           30 : MSParkingArea::getGUIAngle(const SUMOVehicle& forVehicle) const {
     261           60 :     for (const auto& lsd : mySpaceOccupancies) {
     262           60 :         if (lsd.vehicle == &forVehicle) {
     263           30 :             if (lsd.manoeuverAngle > 180.) {
     264           15 :                 return DEG2RAD(lsd.manoeuverAngle - 360.);
     265              :             } else {
     266           15 :                 return DEG2RAD(lsd.manoeuverAngle);
     267              :             }
     268              :         }
     269              :     }
     270              :     return 0.;
     271              : }
     272              : 
     273              : int
     274           30 : MSParkingArea::getManoeuverAngle(const SUMOVehicle& forVehicle) const {
     275           60 :     for (const auto& lsd : mySpaceOccupancies) {
     276           60 :         if (lsd.vehicle == &forVehicle) {
     277           30 :             if (lsd.sideIsLHS) {
     278           30 :                 return abs(int(lsd.manoeuverAngle)) % 180;
     279              :             } else {
     280            0 :                 return abs(abs(int(lsd.manoeuverAngle)) % 180 - 180) % 180;
     281              :             }
     282              :         }
     283              :     }
     284              :     return 0;
     285              : }
     286              : 
     287              : int
     288        46612 : MSParkingArea::getLotIndex(const SUMOVehicle* veh) const {
     289        46612 :     if (veh->getPositionOnLane() > myLastFreePos) {
     290              :         // vehicle has gone past myLastFreePos and we need to find the actual lot
     291              :         int closestLot = -1;
     292        10030 :         for (int i = 0; i < (int)mySpaceOccupancies.size(); i++) {
     293         9695 :             const LotSpaceDefinition lsd = mySpaceOccupancies[i];
     294         9695 :             if (lsd.vehicle == nullptr) {
     295              :                 closestLot = i;
     296         3770 :                 if (lsd.endPos >= veh->getPositionOnLane()) {
     297              :                     return i;
     298              :                 }
     299              :             }
     300              :         }
     301          335 :         return closestLot;
     302              :     }
     303        44891 :     if (myOnRoad && myLastFreePos - veh->getPositionOnLane() > POSITION_EPS) {
     304              :         // for on-road parking we need to be precise
     305              :         return -1;
     306              :     }
     307         7138 :     return myLastFreeLot;
     308              : }
     309              : 
     310              : void
     311         7318 : MSParkingArea::enter(SUMOVehicle* veh) {
     312         7318 :     double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
     313         7318 :     double end = veh->getPositionOnLane() - veh->getVehicleType().getLength();
     314         7318 :     if (myUpdateEvent == nullptr) {
     315         6915 :         myUpdateEvent = new WrappingCommand<MSParkingArea>(this, &MSParkingArea::updateOccupancy);
     316         6915 :         MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myUpdateEvent);
     317              :     }
     318         7318 :     int lotIndex = getLotIndex(veh);
     319         7318 :     if (lotIndex < 0) {
     320            0 :         WRITE_WARNING("Unsuitable parking position for vehicle '" + veh->getID() + "' at parkingArea '" + getID() + "' time=" + time2string(SIMSTEP));
     321            0 :         lotIndex = myLastFreeLot;
     322              :     }
     323              : #ifdef DEBUG_GET_LAST_FREE_POS
     324              :     ((SUMOVehicleParameter&)veh->getParameter()).setParameter("lotIndex", toString(lotIndex));
     325              : #endif
     326              :     assert(myLastFreePos >= 0);
     327              :     assert(lotIndex < (int)mySpaceOccupancies.size());
     328         7318 :     mySpaceOccupancies[lotIndex].vehicle = veh;
     329         7318 :     myEndPositions[veh] = std::pair<double, double>(beg, end);
     330         7318 :     computeLastFreePos();
     331              :     // current search ends here
     332         7318 :     veh->setNumberParkingReroutes(0);
     333         7318 : }
     334              : 
     335              : 
     336              : void
     337         6073 : MSParkingArea::leaveFrom(SUMOVehicle* what) {
     338              :     assert(myEndPositions.find(what) != myEndPositions.end());
     339         6073 :     if (myUpdateEvent == nullptr) {
     340         5998 :         myUpdateEvent = new WrappingCommand<MSParkingArea>(this, &MSParkingArea::updateOccupancy);
     341         5998 :         MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myUpdateEvent);
     342              :     }
     343        17874 :     for (auto& lsd : mySpaceOccupancies) {
     344        17874 :         if (lsd.vehicle == what) {
     345         6073 :             lsd.vehicle = nullptr;
     346         6073 :             break;
     347              :         }
     348              :     }
     349              :     myEndPositions.erase(myEndPositions.find(what));
     350         6073 :     computeLastFreePos();
     351         6073 : }
     352              : 
     353              : 
     354              : SUMOTime
     355        12913 : MSParkingArea::updateOccupancy(SUMOTime /* currentTime */) {
     356        12913 :     myLastStepOccupancy = getOccupancy();
     357        12913 :     myUpdateEvent = nullptr;
     358        12913 :     return 0;
     359              : }
     360              : 
     361              : 
     362            0 : MSParkingArea::LotSpaceDefinition::LotSpaceDefinition() :
     363            0 :     index(-1),
     364            0 :     vehicle(nullptr),
     365            0 :     rotation(0),
     366            0 :     slope(0),
     367            0 :     width(0),
     368            0 :     length(0),
     369            0 :     endPos(0),
     370            0 :     manoeuverAngle(0),
     371            0 :     sideIsLHS(false) {
     372            0 : }
     373              : 
     374              : 
     375        48499 : MSParkingArea::LotSpaceDefinition::LotSpaceDefinition(int index_, SUMOVehicle* vehicle_, double x, double y, double z, double rotation_, double slope_, double width_, double length_) :
     376        48499 :     index(index_),
     377        48499 :     vehicle(vehicle_),
     378              :     position(Position(x, y, z)),
     379        48499 :     rotation(rotation_),
     380        48499 :     slope(slope_),
     381        48499 :     width(width_),
     382        48499 :     length(length_),
     383        48499 :     endPos(0),
     384        48499 :     manoeuverAngle(0),
     385        48499 :     sideIsLHS(false) {
     386        48499 : }
     387              : 
     388              : 
     389              : void
     390        63005 : MSParkingArea::computeLastFreePos() {
     391        63005 :     myLastFreeLot = -1;
     392        63005 :     myLastFreePos = myBegPos;
     393        63005 :     myEgressBlocked = false;
     394        89710 :     for (auto& lsd : mySpaceOccupancies) {
     395        87240 :         if (lsd.vehicle == nullptr
     396        87240 :                 || (getOccupancy() == getCapacity()
     397         8156 :                     && lsd.vehicle->remainingStopDuration() <= 0
     398          959 :                     && !lsd.vehicle->isStoppedTriggered())) {
     399        60535 :             if (lsd.vehicle == nullptr) {
     400        59679 :                 myLastFreeLot = lsd.index;
     401        59679 :                 myLastFreePos = lsd.endPos;
     402              :             } else {
     403              :                 // vehicle wants to exit the parking area
     404          856 :                 myLastFreeLot = lsd.index;
     405          856 :                 myLastFreePos = lsd.endPos - lsd.vehicle->getVehicleType().getLength() - POSITION_EPS;
     406          856 :                 myEgressBlocked = true;
     407              :             }
     408              :             break;
     409              :         } else {
     410        26705 :             myLastFreePos = MIN2(myLastFreePos,
     411        26705 :                                  lsd.endPos - lsd.vehicle->getVehicleType().getLength() - NUMERICAL_EPS);
     412              :         }
     413              :     }
     414        63005 : }
     415              : 
     416              : 
     417              : double
     418       731865 : MSParkingArea::getLastFreePosWithReservation(SUMOTime t, const SUMOVehicle& forVehicle, double brakePos) {
     419       731865 :     if (forVehicle.getLane() != &myLane) {
     420              :         // for different lanes, do not consider reservations to avoid lane-order
     421              :         // dependency in parallel simulation
     422              : #ifdef DEBUG_RESERVATIONS
     423              :         if (DEBUG_COND2(forVehicle)) {
     424              :             std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " other lane\n";
     425              :         }
     426              : #endif
     427       559426 :         if (myNumAlternatives > 0 && getOccupancy() == getCapacity()) {
     428              :             // ensure that the vehicle reaches the rerouter lane
     429       154687 :             return MAX2(myBegPos, MIN2(POSITION_EPS, myEndPos));
     430              :         } else {
     431       404739 :             return getLastFreePos(forVehicle, brakePos);
     432              :         }
     433              :     }
     434       172439 :     if (t > myReservationTime) {
     435              : #ifdef DEBUG_RESERVATIONS
     436              :         if (DEBUG_COND2(forVehicle)) {
     437              :             std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " first reservation\n";
     438              :         }
     439              : #endif
     440        91782 :         myReservationTime = t;
     441        91782 :         myReservations = 1;
     442        91782 :         myReservationMaxLength = forVehicle.getVehicleType().getLength();
     443       868629 :         for (const auto& lsd : mySpaceOccupancies) {
     444       776847 :             if (lsd.vehicle != nullptr) {
     445       456202 :                 myReservationMaxLength = MAX2(myReservationMaxLength, lsd.vehicle->getVehicleType().getLength());
     446              :             }
     447              :         }
     448        91782 :         return getLastFreePos(forVehicle, brakePos);
     449              :     } else {
     450        80657 :         if (myCapacity > getOccupancy() + myReservations) {
     451              : #ifdef DEBUG_RESERVATIONS
     452              :             if (DEBUG_COND2(forVehicle)) {
     453              :                 std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " res=" << myReservations << " enough space\n";
     454              :             }
     455              : #endif
     456        34823 :             myReservations++;
     457        34823 :             myReservationMaxLength = MAX2(myReservationMaxLength, forVehicle.getVehicleType().getLength());
     458        34823 :             return getLastFreePos(forVehicle, brakePos);
     459              :         } else {
     460        45834 :             if (myCapacity == 0) {
     461          620 :                 return getLastFreePos(forVehicle, brakePos);
     462              :             } else {
     463              : #ifdef DEBUG_RESERVATIONS
     464              :                 if (DEBUG_COND2(forVehicle)) std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID()
     465              :                                                            << " res=" << myReservations << " resTime=" << myReservationTime << " reserved full, maxLen=" << myReservationMaxLength << " endPos=" << mySpaceOccupancies[0].endPos << "\n";
     466              : #endif
     467        45214 :                 return (mySpaceOccupancies[0].endPos
     468        45214 :                         - myReservationMaxLength
     469        45214 :                         - forVehicle.getVehicleType().getMinGap()
     470        45214 :                         - NUMERICAL_EPS);
     471              :             }
     472              :         }
     473              :     }
     474              : }
     475              : 
     476              : 
     477              : double
     478          600 : MSParkingArea::getWidth() const {
     479          600 :     return myWidth;
     480              : }
     481              : 
     482              : 
     483              : double
     484          600 : MSParkingArea::getLength() const {
     485          600 :     return myLength;
     486              : }
     487              : 
     488              : 
     489              : double
     490          600 : MSParkingArea::getAngle() const {
     491          600 :     return myAngle;
     492              : }
     493              : 
     494              : 
     495              : int
     496       741889 : MSParkingArea::getCapacity() const {
     497       741889 :     return myCapacity;
     498              : }
     499              : 
     500              : 
     501              : bool
     502       381089 : MSParkingArea::parkOnRoad() const {
     503       381089 :     return myOnRoad;
     504              : }
     505              : 
     506              : 
     507              : int
     508       583114 : MSParkingArea::getOccupancy() const {
     509       583114 :     return (int)myEndPositions.size() - (myEgressBlocked ? 1 : 0);
     510              : }
     511              : 
     512              : 
     513              : int
     514       139520 : MSParkingArea::getOccupancyIncludingBlocked() const {
     515       139520 :     return (int)myEndPositions.size();
     516              : }
     517              : 
     518              : 
     519              : int
     520        49280 : MSParkingArea::getLastStepOccupancy() const {
     521        49280 :     return myLastStepOccupancy;
     522              : }
     523              : 
     524              : 
     525              : void
     526            0 : MSParkingArea::accept(std::string badge) {
     527              :     myAcceptedBadges.insert(badge);
     528            0 : }
     529              : 
     530              : 
     531              : void
     532            0 : MSParkingArea::accept(std::vector<std::string> badges) {
     533              :     myAcceptedBadges.insert(badges.begin(), badges.end());
     534            0 : }
     535              : 
     536              : 
     537              : void
     538            0 : MSParkingArea::refuse(std::string badge) {
     539              :     myAcceptedBadges.erase(badge);
     540            0 : }
     541              : 
     542              : 
     543              : bool
     544        16338 : MSParkingArea::accepts(MSBaseVehicle* veh) const {
     545        16338 :     if (myAcceptedBadges.size() == 0) {
     546              :         return true;
     547              :     } else {
     548           21 :         std::vector<std::string> vehicleBadges = veh->getParkingBadges();
     549           21 :         for (auto badge : vehicleBadges) {
     550              :             if (myAcceptedBadges.count(badge) != 0) {
     551              :                 return true;
     552              :             }
     553              :         }
     554            7 :         return false;
     555           21 :     }
     556              : }
     557              : 
     558              : 
     559              : void
     560         1115 : MSParkingArea::notifyEgressBlocked() {
     561         1115 :     computeLastFreePos();
     562         1115 : }
     563              : 
     564              : 
     565              : int
     566            0 : MSParkingArea::getNumAlternatives() const {
     567            0 :     return myNumAlternatives;
     568              : }
     569              : 
     570              : 
     571              : void
     572        12087 : MSParkingArea::setNumAlternatives(int alternatives) {
     573        12087 :     myNumAlternatives = MAX2(myNumAlternatives, alternatives);
     574        12087 : }
     575              : 
     576              : 
     577              : std::vector<std::string>
     578           20 : MSParkingArea::getAcceptedBadges() const {
     579           20 :     std::vector<std::string> result(myAcceptedBadges.begin(), myAcceptedBadges.end());
     580           20 :     return result;
     581              : }
     582              : 
     583              : 
     584              : void
     585           10 : MSParkingArea::setAcceptedBadges(const std::vector<std::string>& badges) {
     586              :     myAcceptedBadges.clear();
     587              :     myAcceptedBadges.insert(badges.begin(), badges.end());
     588           10 : }
     589              : 
     590              : 
     591              : void
     592        22872 : MSParkingArea::setRoadsideCapacity(int capacity) {
     593              :     // reinit parking lot generation process
     594        22872 :     myRoadSideCapacity = capacity;
     595              : 
     596              :     // Initialize space occupancies if there is a road-side capacity
     597              :     // The overall number of lots is fixed and each lot accepts one vehicle regardless of size
     598        22872 :     const double spaceDim = myRoadSideCapacity > 0 ? myLane.interpolateLanePosToGeometryPos((myEndPos - myBegPos) / myRoadSideCapacity) : 7.5;
     599        22872 :     if (myLength == 0) {
     600        10547 :         myLength = spaceDim;
     601              :     }
     602              :     mySpaceOccupancies.clear();
     603        22872 :     myCapacity = 0;
     604        70771 :     for (int i = 0; i < myRoadSideCapacity; ++i) {
     605              :         // calculate pos, angle and slope of parking lot space
     606        47899 :         const Position pos = GeomHelper::calculateLotSpacePosition(myShape, i, spaceDim, myAngle, myWidth, myLength);
     607        47899 :         double spaceAngle = GeomHelper::calculateLotSpaceAngle(myShape, i, spaceDim, myAngle);
     608        47899 :         double spaceSlope = GeomHelper::calculateLotSpaceSlope(myShape, i, spaceDim);
     609              :         // add lotEntry
     610        47899 :         addLotEntry(pos.x(), pos.y(), pos.z(), myWidth, myLength, spaceAngle, spaceSlope);
     611              :         // update endPos
     612       141715 :         mySpaceOccupancies.back().endPos = MIN2(myEndPos, myBegPos + MAX2(POSITION_EPS, spaceDim * (i + 1)));
     613              :     }
     614        22872 : }
     615              : 
     616              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1