LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSStageTrip.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.5 % 219 196
Test Date: 2025-11-13 15:38:19 Functions: 81.2 % 16 13

            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    MSStageTrip.cpp
      15              : /// @author  Melanie Weber
      16              : /// @author  Andreas Kendziorra
      17              : /// @author  Michael Behrisch
      18              : /// @author  Jakob Erdmann
      19              : /// @date    Wed, 1 Jun 2022
      20              : ///
      21              : // An intermodal routing request (to be transformed into a sequence of walks and rides)
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <utils/common/StringTokenizer.h>
      26              : #include <utils/geom/GeomHelper.h>
      27              : #include <utils/options/OptionsCont.h>
      28              : #include <utils/vehicle/SUMOVehicleParameter.h>
      29              : #include <utils/router/PedestrianRouter.h>
      30              : #include <utils/router/IntermodalRouter.h>
      31              : #include <microsim/MSEdge.h>
      32              : #include <microsim/MSLane.h>
      33              : #include <microsim/MSNet.h>
      34              : #include <microsim/MSStoppingPlace.h>
      35              : #include <microsim/MSVehicleControl.h>
      36              : #include <microsim/transportables/MSStageDriving.h>
      37              : #include <microsim/transportables/MSStageWaiting.h>
      38              : #include <microsim/transportables/MSStageWalking.h>
      39              : #include <microsim/transportables/MSTransportable.h>
      40              : #include <microsim/transportables/MSPerson.h>
      41              : #include <microsim/transportables/MSStageTrip.h>
      42              : 
      43              : 
      44              : // ===========================================================================
      45              : // method definitions
      46              : // ===========================================================================
      47              : 
      48              : /* -------------------------------------------------------------------------
      49              : * MSStageTrip - methods
      50              : * ----------------------------------------------------------------------- */
      51       230104 : MSStageTrip::MSStageTrip(const MSEdge* origin, MSStoppingPlace* fromStop,
      52              :                          const MSEdge* destination, MSStoppingPlace* toStop,
      53              :                          const SUMOTime duration, const SVCPermissions modeSet,
      54              :                          const std::string& vTypes, const double speed, const double walkFactor,
      55              :                          const std::string& group,
      56       230104 :                          const double departPosLat, const bool hasArrivalPos, const double arrivalPos):
      57              :     MSStage(MSStageType::TRIP, destination, toStop, arrivalPos, 0.0, group),
      58       230104 :     myOrigin(origin),
      59       230104 :     myOriginStop(fromStop),
      60       230104 :     myDuration(duration),
      61       230104 :     myModeSet(modeSet),
      62       230104 :     myVTypes(vTypes),
      63       230104 :     mySpeed(speed),
      64       230104 :     myWalkFactor(walkFactor),
      65       230104 :     myDepartPosLat(departPosLat),
      66       230104 :     myHaveArrivalPos(hasArrivalPos) {
      67       230104 : }
      68              : 
      69              : 
      70       460198 : MSStageTrip::~MSStageTrip() {}
      71              : 
      72              : MSStage*
      73       221626 : MSStageTrip::clone() const {
      74       221626 :     MSStage* const clon = new MSStageTrip(myOrigin, const_cast<MSStoppingPlace*>(myOriginStop),
      75       221626 :                                           myDestination, myDestinationStop, myDuration,
      76       221626 :                                           myModeSet, myVTypes, mySpeed, myWalkFactor, myGroup,
      77       221626 :                                           myDepartPosLat, myHaveArrivalPos, myArrivalPos);
      78       221626 :     clon->setParameters(*this);
      79       221626 :     return clon;
      80              : }
      81              : 
      82              : 
      83              : Position
      84            0 : MSStageTrip::getPosition(SUMOTime /* now */) const {
      85              :     // may be called concurrently while the trip is still being routed
      86            0 :     return getEdgePosition(myOrigin, myDepartPos, ROADSIDE_OFFSET * (MSGlobals::gLefthand ? -1 : 1));
      87              : }
      88              : 
      89              : 
      90              : double
      91            0 : MSStageTrip::getAngle(SUMOTime /* now */) const {
      92              :     // may be called concurrently while the trip is still being routed
      93            0 :     return getEdgeAngle(myOrigin, myDepartPos) + M_PI / 2 * (MSGlobals::gLefthand ? -1 : 1);
      94              : }
      95              : 
      96              : 
      97              : const MSEdge*
      98       416891 : MSStageTrip::getEdge() const {
      99       416891 :     return myOrigin;
     100              : }
     101              : 
     102              : 
     103              : double
     104       408390 : MSStageTrip::getEdgePos(SUMOTime /* now */) const {
     105       408390 :     return myDepartPos;
     106              : }
     107              : 
     108              : 
     109              : std::vector<SUMOVehicle*>
     110       205586 : MSStageTrip::getVehicles(MSVehicleControl& vehControl, MSTransportable* transportable, const MSEdge* origin) {
     111              :     std::vector<SUMOVehicleParameter*> pars;
     112       411279 :     for (StringTokenizer st(myVTypes); st.hasNext();) {
     113          107 :         pars.push_back(new SUMOVehicleParameter());
     114          214 :         pars.back()->vtypeid = st.next();
     115          107 :         pars.back()->parametersSet |= VEHPARS_VTYPE_SET;
     116          107 :         pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     117          214 :         pars.back()->id = transportable->getID() + "_" + toString(pars.size() - 1);
     118       205586 :     }
     119       205586 :     if (pars.empty()) {
     120       205483 :         if ((myModeSet & SVC_PASSENGER) != 0) {
     121         1599 :             pars.push_back(new SUMOVehicleParameter());
     122         3198 :             pars.back()->id = transportable->getID() + "_0";
     123         1599 :             pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     124              :         }
     125       205483 :         if ((myModeSet & SVC_TAXI) != 0) {
     126          168 :             pars.push_back(new SUMOVehicleParameter());
     127          168 :             pars.back()->vtypeid = DEFAULT_TAXITYPE_ID;
     128          336 :             pars.back()->id = transportable->getID() + "_taxi";
     129          168 :             pars.back()->line = "taxi";
     130              :         }
     131       205483 :         if ((myModeSet & SVC_BICYCLE) != 0) {
     132           37 :             pars.push_back(new SUMOVehicleParameter());
     133           37 :             pars.back()->vtypeid = DEFAULT_BIKETYPE_ID;
     134           74 :             pars.back()->id = transportable->getID() + "_b0";
     135           37 :             pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     136              :         }
     137              :     }
     138       411172 :     ConstMSRoutePtr const routeDummy = std::make_shared<MSRoute>(transportable->getID() + "_0", ConstMSEdgeVector({ origin }), false, nullptr, StopParVector());
     139              :     std::vector<SUMOVehicle*> result;
     140       207497 :     for (SUMOVehicleParameter* vehPar : pars) {
     141         1911 :         const bool isTaxi = vehPar->vtypeid == DEFAULT_TAXITYPE_ID && vehPar->line == "taxi";
     142         1911 :         if (myDepartPos != 0) {
     143           81 :             vehPar->departPosProcedure = DepartPosDefinition::GIVEN;
     144           81 :             vehPar->departPos = myDepartPos;
     145           81 :             vehPar->parametersSet |= VEHPARS_DEPARTPOS_SET;
     146              :         }
     147         1911 :         vehPar->parametersSet |= VEHPARS_ARRIVALPOS_SET;
     148         1911 :         vehPar->arrivalPosProcedure = ArrivalPosDefinition::GIVEN;
     149         1911 :         vehPar->parametersSet |= VEHPARS_ARRIVALSPEED_SET;
     150         1911 :         vehPar->arrivalSpeedProcedure = ArrivalSpeedDefinition::GIVEN;
     151         1911 :         vehPar->arrivalSpeed = 0;
     152         1911 :         MSVehicleType* type = vehControl.getVType(vehPar->vtypeid);
     153         1911 :         if (type->getVehicleClass() != SVC_IGNORING && (origin->getPermissions() & type->getVehicleClass()) == 0 && !isTaxi) {
     154          120 :             WRITE_WARNINGF(TL("Ignoring vehicle type '%' when routing person '%' because it is not allowed on the start edge."), type->getID(), transportable->getID());
     155           40 :             delete vehPar;
     156              :         } else {
     157         3742 :             result.push_back(vehControl.buildVehicle(vehPar, routeDummy, type, !MSGlobals::gCheckRoutes));
     158              :         }
     159              :     }
     160       205586 :     if (result.empty()) {
     161              :         // walking only but may use access infrastructure
     162       203749 :         result.push_back(nullptr);
     163              :     }
     164       205586 :     return result;
     165       205586 : }
     166              : 
     167              : 
     168              : const std::string
     169       205586 : MSStageTrip::reroute(const SUMOTime time, MSTransportableRouter& router, MSTransportable* const transportable,
     170              :                      MSStage* previous, const MSEdge* origin, const MSEdge* destination, std::vector<MSStage*>& stages) {
     171       205586 :     if (origin->isTazConnector() && origin->getSuccessors().size() == 0) {
     172              :         // previous stage ended at a taz sink-edge
     173          299 :         origin = transportable->getNextStage(-1)->getDestination();
     174              :     }
     175       205586 :     MSVehicleControl& vehControl = MSNet::getInstance()->getVehicleControl();
     176              :     double minCost = std::numeric_limits<double>::max();
     177              :     std::vector<MSTransportableRouter::TripItem> minResult;
     178              :     SUMOVehicle* minVehicle = nullptr;
     179       411206 :     for (SUMOVehicle* vehicle : getVehicles(vehControl, transportable, origin)) {
     180              :         std::vector<MSTransportableRouter::TripItem> result;
     181       205620 :         double departPos = previous->getArrivalPos();
     182              :         MSStoppingPlace* const prevStop = previous->getDestinationStop();
     183       205620 :         if (MSGlobals::gUseMesoSim && prevStop != nullptr) {
     184          191 :             departPos = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2.;
     185              :         }
     186       430811 :         if (router.compute(origin, destination, departPos, prevStop == nullptr ? "" : prevStop->getID(),
     187       380806 :                            myArrivalPos, myDestinationStop == nullptr ? "" : myDestinationStop->getID(),
     188       205620 :                            transportable->getMaxSpeed() * myWalkFactor, vehicle, transportable->getVTypeParameter(), myModeSet, time, result)) {
     189              :             double totalCost = 0;
     190       436647 :             for (const MSTransportableRouter::TripItem& item : result) {
     191       231098 :                 totalCost += item.cost;
     192              :             }
     193       205549 :             if (totalCost < minCost) {
     194              :                 minCost = totalCost;
     195              :                 minResult.swap(result);
     196              :                 std::swap(minVehicle, vehicle);
     197              :             }
     198              :         }
     199       205620 :         if (vehicle != nullptr) {
     200           41 :             vehControl.deleteVehicle(vehicle, true);
     201              :             vehControl.discountRoutingVehicle();
     202              :         }
     203       411206 :     }
     204       205586 :     if (minCost != std::numeric_limits<double>::max()) {
     205       205515 :         const bool isTaxi = minVehicle != nullptr && minVehicle->getParameter().vtypeid == DEFAULT_TAXITYPE_ID && minVehicle->getParameter().line == "taxi";
     206              :         bool carUsed = false;
     207       436567 :         for (std::vector<MSTransportableRouter::TripItem>::iterator it = minResult.begin(); it != minResult.end(); ++it) {
     208       231052 :             if (!it->edges.empty()) {
     209       211488 :                 MSStoppingPlace* bs = MSNet::getInstance()->getStoppingPlace(it->destStop);
     210       211488 :                 double localArrivalPos = bs != nullptr ? bs->getAccessPos(it->edges.back()) : it->arrivalPos;
     211       211488 :                 const MSEdge* const first = it->edges.front();
     212       211488 :                 const MSEdge* const rideOrigin = origin->isTazConnector() && stages.empty() ? first : nullptr;
     213       211488 :                 if (it + 1 == minResult.end() && myHaveArrivalPos) {
     214         5561 :                     localArrivalPos = myArrivalPos;
     215              :                 }
     216       211488 :                 if (it->line == "") {
     217              :                     // determine walk departPos
     218       206816 :                     double depPos = previous->getArrivalPos();
     219       206816 :                     if (previous->getDestinationStop() != nullptr) {
     220        22406 :                         depPos = previous->getDestinationStop()->getAccessPos(first, first->getLanes()[0]->getRNG());
     221       184410 :                     } else if (origin->isTazConnector()) {
     222              :                         // walk the whole length of the first edge
     223          105 :                         if (std::find(first->getPredecessors().begin(), first->getPredecessors().end(), origin) != first->getPredecessors().end()) {
     224              :                             depPos = 0;
     225              :                         } else {
     226              :                             depPos = first->getLength();
     227              :                         }
     228       184305 :                     } else if (previous->getDestination() != first) {
     229           53 :                         if ((previous->getDestination()->getToJunction() == first->getToJunction())
     230           53 :                                 || (previous->getDestination()->getFromJunction() == first->getToJunction())) {
     231              :                             depPos = first->getLength();
     232              :                         } else {
     233              :                             depPos = 0.;
     234              :                         }
     235              :                     }
     236       206816 :                     if (destination->isTazConnector()) {
     237              :                         // walk the whole length of the last edge
     238          745 :                         const MSEdge* last = it->edges.back();
     239          745 :                         if (std::find(last->getSuccessors().begin(), last->getSuccessors().end(), destination) != last->getSuccessors().end()) {
     240              :                             localArrivalPos = last->getLength();
     241              :                         } else {
     242              :                             localArrivalPos = 0;
     243              :                         }
     244              :                     }
     245       206816 :                     previous = new MSStageWalking(transportable->getID(), it->edges, bs, myDuration, mySpeed, depPos, localArrivalPos, myDepartPosLat);
     246       206816 :                     previous->setParameters(*this);
     247       206816 :                     previous->setCosts(it->cost);
     248              :                     previous->setTrip(this);
     249       206816 :                     stages.push_back(previous);
     250         4672 :                 } else if (isTaxi && it->line == minVehicle->getID()) {
     251          170 :                     const ConstMSEdgeVector& prevEdges = previous->getEdges();
     252          170 :                     if (prevEdges.size() >= 2 && previous->getDestinationStop() == nullptr) {
     253              :                         // determine walking direction and let the previous
     254              :                         // stage end after entering its final edge
     255            6 :                         const MSEdge* last = prevEdges.back();
     256            6 :                         const MSEdge* prev = prevEdges[prevEdges.size() - 2];
     257            6 :                         if (last->getFromJunction() == prev->getToJunction() || prev->getFromJunction() == last->getFromJunction()) {
     258              :                             previous->setArrivalPos(MIN2(last->getLength(), 10.0));
     259              :                         } else {
     260            6 :                             previous->setArrivalPos(MAX2(0.0, last->getLength() - 10));
     261              :                         }
     262              :                     }
     263          510 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ "taxi" }), myGroup);
     264          170 :                     previous->setParameters(*this);
     265          170 :                     previous->setCosts(it->cost);
     266              :                     previous->setTrip(this);
     267          170 :                     stages.push_back(previous);
     268         4672 :                 } else if (minVehicle != nullptr && it->line == minVehicle->getID()) {
     269         4602 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ it->line }));
     270         1534 :                     previous->setParameters(*this);
     271         1534 :                     previous->setCosts(it->cost);
     272              :                     previous->setTrip(this);
     273         1534 :                     stages.push_back(previous);
     274         1534 :                     minVehicle->replaceRouteEdges(it->edges, -1, 0, "person:" + transportable->getID(), true);
     275         1534 :                     minVehicle->setArrivalPos(localArrivalPos);
     276         1534 :                     const_cast<SUMOVehicleParameter&>(minVehicle->getParameter()).arrivalPos = localArrivalPos;
     277         1534 :                     vehControl.addVehicle(minVehicle->getID(), minVehicle);
     278              :                     carUsed = true;
     279              :                 } else {
     280         2968 :                     const std::string line = OptionsCont::getOptions().getBool("persontrip.ride-public-line") ? it->line : LINE_ANY;
     281         8904 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ line }), myGroup, it->intended, TIME2STEPS(it->depart));
     282         2968 :                     previous->setParameters(*this);
     283         2968 :                     previous->setCosts(it->cost);
     284              :                     previous->setTrip(this);
     285         2968 :                     stages.push_back(previous);
     286              :                 }
     287              :             }
     288              :         }
     289       205515 :         if (wasSet(VEHPARS_ARRIVALPOS_SET) && !stages.empty()) {
     290              :             // mark the last stage
     291         1175 :             stages.back()->markSet(VEHPARS_ARRIVALPOS_SET);
     292              :         }
     293              :         setCosts(minCost);
     294       205515 :         if (minVehicle != nullptr && (isTaxi || !carUsed)) {
     295          296 :             vehControl.deleteVehicle(minVehicle, true);
     296              :             vehControl.discountRoutingVehicle();
     297              :         }
     298              :     } else {
     299              :         // append stage so the GUI won't crash due to inconsistent state
     300           71 :         previous = new MSStageWalking(transportable->getID(), ConstMSEdgeVector({ origin, destination }), myDestinationStop, myDuration, mySpeed, previous->getArrivalPos(), myArrivalPos, myDepartPosLat);
     301           71 :         previous->setParameters(*this);
     302           71 :         stages.push_back(previous);
     303           71 :         if (MSGlobals::gCheckRoutes) {  // if not pedestrians will teleport
     304          141 :             return "No connection found between " + getOriginDescription() + " and " + getDestinationDescription() + " for person '" + transportable->getID() + "'.";
     305              :         }
     306              :     }
     307       205539 :     if (stages.empty()) {
     308              :         // append stage so the GUI won't crash due to inconsistent state
     309           14 :         if (myOriginStop != nullptr && myOriginStop == myDestinationStop) {
     310           28 :             stages.push_back(new MSStageWaiting(destination, myDestinationStop, 0, -1, previous->getArrivalPos(), "sameStop", false));
     311              :         } else {
     312            0 :             stages.push_back(new MSStageWalking(transportable->getID(), ConstMSEdgeVector({ origin, destination }), myDestinationStop, myDuration, mySpeed, previous->getArrivalPos(), myArrivalPos, myDepartPosLat));
     313            0 :             if (MSGlobals::gCheckRoutes) {  // if not pedestrians will teleport
     314            0 :                 return "Empty route between " + getOriginDescription() + " and " + getDestinationDescription() + " for person '" + transportable->getID() + "'.";
     315              :             }
     316              :         }
     317              :     }
     318       205539 :     return "";
     319       205926 : }
     320              : 
     321              : 
     322              : const std::string
     323       205506 : MSStageTrip::setArrived(MSNet* net, MSTransportable* transportable, SUMOTime now, const bool vehicleArrived) {
     324       411012 :     MSStage::setArrived(net, transportable, now, vehicleArrived);
     325              :     std::vector<MSStage*> stages;
     326              :     std::string result;
     327       205506 :     if (transportable->getCurrentStageIndex() == 0) {
     328            0 :         myDepartPos = transportable->getParameter().departPos;
     329            0 :         if (transportable->getParameter().departPosProcedure == DepartPosDefinition::RANDOM) {
     330              :             // TODO we should probably use the rng of the lane here
     331            0 :             myDepartPos = RandHelper::rand(myOrigin->getLength());
     332              :         }
     333            0 :         MSStageWaiting start(myOrigin, myOriginStop, -1, transportable->getParameter().depart, myDepartPos, "start", true);
     334            0 :         result = reroute(transportable->getParameter().depart, net->getIntermodalRouter(0), transportable, &start, myOrigin, myDestination, stages);
     335            0 :     } else {
     336              :         MSStage* previous = transportable->getNextStage(-1);
     337       205506 :         myDepartPos = previous->getArrivalPos();
     338       411012 :         result = reroute(now, net->getIntermodalRouter(0), transportable, previous, myOrigin, myDestination, stages);
     339              :     }
     340              :     int idx = 1;
     341       416955 :     for (MSStage* stage : stages) {
     342       211449 :         transportable->appendStage(stage, idx++);
     343              :     }
     344       205506 :     return result;
     345       205506 : }
     346              : 
     347              : 
     348              : void
     349       205506 : MSStageTrip::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now, MSStage* /* previous */) {
     350              :     // just skip the stage, every interesting happens in setArrived
     351       205506 :     transportable->proceed(net, now);
     352       205459 : }
     353              : 
     354              : 
     355              : std::string
     356           47 : MSStageTrip::getOriginDescription() const {
     357           47 :     return (myOriginStop != nullptr
     358          101 :             ? toString(myOriginStop->getElement()) + " '" + myOriginStop->getID()
     359           87 :             : "edge '" + myOrigin->getID()) + "'";
     360              : }
     361              : 
     362              : std::string
     363           47 : MSStageTrip::getDestinationDescription() const {
     364           47 :     return (myDestinationStop != nullptr
     365          109 :             ? toString(myDestinationStop->getElement()) + " '" + myDestinationStop->getID()
     366           79 :             : "edge '" + myDestination->getID()) + "'";
     367              : }
     368              : 
     369              : std::string
     370            0 : MSStageTrip::getStageSummary(const bool) const {
     371            0 :     return "trip from " + getOriginDescription() + " to " + getDestinationDescription();
     372              : }
     373              : 
     374              : void
     375         1598 : MSStageTrip::routeOutput(const bool /*isPerson*/, OutputDevice& os, const bool /*withRouteLength*/, const MSStage* const previous) const {
     376         1598 :     if (myArrived < 0) {
     377           10 :         const bool walkFactorSet = myWalkFactor != OptionsCont::getOptions().getFloat("persontrip.walkfactor");
     378           10 :         const bool groupSet = myGroup != OptionsCont::getOptions().getString("persontrip.default.group");
     379              :         // could still be a persontrip but most likely it was a walk in the input
     380           10 :         SumoXMLTag tag = myModeSet == 0 && !walkFactorSet && !groupSet ? SUMO_TAG_WALK : SUMO_TAG_PERSONTRIP;
     381           10 :         os.openTag(tag);
     382           10 :         if (previous == nullptr || previous->getStageType() == MSStageType::WAITING_FOR_DEPART) {
     383            4 :             os.writeAttr(SUMO_ATTR_FROM, myOrigin->getID());
     384              :         }
     385           10 :         if (myDestinationStop == nullptr) {
     386           10 :             os.writeAttr(SUMO_ATTR_TO, myDestination->getID());
     387           10 :             if (wasSet(VEHPARS_ARRIVALPOS_SET)) {
     388            6 :                 os.writeAttr(SUMO_ATTR_ARRIVALPOS, myArrivalPos);
     389              :             }
     390              :         } else {
     391            0 :             os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
     392              :         }
     393              :         std::vector<std::string> modes;
     394           10 :         if ((myModeSet & SVC_PASSENGER) != 0) {
     395            4 :             modes.push_back("car");
     396              :         }
     397           10 :         if ((myModeSet & SVC_BICYCLE) != 0) {
     398            0 :             modes.push_back("bicycle");
     399              :         }
     400           10 :         if ((myModeSet & SVC_TAXI) != 0) {
     401            0 :             modes.push_back("taxi");
     402              :         }
     403           10 :         if ((myModeSet & SVC_BUS) != 0) {
     404            0 :             modes.push_back("public");
     405              :         }
     406           10 :         if (modes.size() > 0) {
     407            2 :             os.writeAttr(SUMO_ATTR_MODES, modes);
     408              :         }
     409           10 :         if (myVTypes.size() > 0) {
     410            0 :             os.writeAttr(SUMO_ATTR_VTYPES, myVTypes);
     411              :         }
     412           10 :         if (groupSet) {
     413            0 :             os.writeAttr(SUMO_ATTR_GROUP, myGroup);
     414              :         }
     415           10 :         if (walkFactorSet) {
     416            0 :             os.writeAttr(SUMO_ATTR_WALKFACTOR, myWalkFactor);
     417              :         }
     418           20 :         if (OptionsCont::getOptions().getBool("vehroute-output.cost")) {
     419            0 :             os.writeAttr(SUMO_ATTR_COST, getCosts());
     420              :         }
     421           10 :         os.closeTag();
     422           10 :     }
     423         1598 : }
     424              : 
     425              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1