LCOV - code coverage report
Current view: top level - src/utils/handlers - RouteHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 617 0
Test Date: 2024-12-21 15:45:41 Functions: 0.0 % 27 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    RouteHandler.cpp
      15              : /// @author  Pablo Alvarez Lopez
      16              : /// @date    Jun 2021
      17              : ///
      18              : // The XML-Handler for route elements loading
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <utils/common/MsgHandler.h>
      23              : #include <utils/common/RGBColor.h>
      24              : #include <utils/common/SUMOVehicleClass.h>
      25              : #include <utils/options/OptionsCont.h>
      26              : #include <utils/shapes/Shape.h>
      27              : #include <utils/vehicle/SUMOVehicleParserHelper.h>
      28              : #include <utils/xml/SUMOSAXHandler.h>
      29              : #include <utils/xml/XMLSubSys.h>
      30              : #include <utils/xml/NamespaceIDs.h>
      31              : 
      32              : #include "RouteHandler.h"
      33              : 
      34              : 
      35              : // ===========================================================================
      36              : // method definitions
      37              : // ===========================================================================
      38              : 
      39            0 : RouteHandler::RouteHandler(const std::string& filename, const bool hardFail) :
      40            0 :     myFilename(filename),
      41            0 :     myHardFail(hardFail),
      42            0 :     myFlowBeginDefault(string2time(OptionsCont::getOptions().getString("begin"))),
      43            0 :     myFlowEndDefault(string2time(OptionsCont::getOptions().getString("end"))) {
      44            0 : }
      45              : 
      46              : 
      47            0 : RouteHandler::~RouteHandler() {}
      48              : 
      49              : 
      50              : bool
      51            0 : RouteHandler::beginParseAttributes(SumoXMLTag tag, const SUMOSAXAttributes& attrs) {
      52              :     // open SUMOBaseOBject
      53            0 :     myCommonXMLStructure.openSUMOBaseOBject();
      54              :     // check tag
      55              :     try {
      56            0 :         switch (tag) {
      57              :             // vTypes
      58            0 :             case SUMO_TAG_VTYPE:
      59            0 :                 parseVType(attrs);
      60              :                 break;
      61            0 :             case SUMO_TAG_VTYPE_DISTRIBUTION:
      62            0 :                 parseVTypeDistribution(attrs);
      63              :                 break;
      64              :             // routes
      65            0 :             case SUMO_TAG_ROUTE:
      66            0 :                 parseRoute(attrs);
      67              :                 break;
      68            0 :             case SUMO_TAG_ROUTE_DISTRIBUTION:
      69            0 :                 parseRouteDistribution(attrs);
      70              :                 break;
      71              :             // vehicles
      72            0 :             case SUMO_TAG_TRIP:
      73            0 :                 parseTrip(attrs);
      74              :                 break;
      75            0 :             case SUMO_TAG_VEHICLE:
      76            0 :                 parseVehicle(attrs);
      77              :                 break;
      78              :             // flows
      79            0 :             case SUMO_TAG_FLOW:
      80            0 :                 parseFlow(attrs);
      81              :                 break;
      82              :             // stop
      83            0 :             case SUMO_TAG_STOP:
      84            0 :                 parseStop(attrs);
      85              :                 break;
      86              :             // persons
      87            0 :             case SUMO_TAG_PERSON:
      88            0 :                 parsePerson(attrs);
      89              :                 break;
      90            0 :             case SUMO_TAG_PERSONFLOW:
      91            0 :                 parsePersonFlow(attrs);
      92              :                 break;
      93              :             // person plans
      94            0 :             case SUMO_TAG_PERSONTRIP:
      95            0 :                 parsePersonTrip(attrs);
      96              :                 break;
      97            0 :             case SUMO_TAG_RIDE:
      98            0 :                 parseRide(attrs);
      99              :                 break;
     100            0 :             case SUMO_TAG_WALK:
     101            0 :                 parseWalk(attrs);
     102              :                 break;
     103              :             // container
     104            0 :             case SUMO_TAG_CONTAINER:
     105            0 :                 parseContainer(attrs);
     106              :                 break;
     107            0 :             case SUMO_TAG_CONTAINERFLOW:
     108            0 :                 parseContainerFlow(attrs);
     109              :                 break;
     110              :             // container plans
     111            0 :             case SUMO_TAG_TRANSPORT:
     112            0 :                 parseTransport(attrs);
     113              :                 break;
     114            0 :             case SUMO_TAG_TRANSHIP:
     115            0 :                 parseTranship(attrs);
     116              :                 break;
     117              :             // parameters
     118            0 :             case SUMO_TAG_PARAM:
     119            0 :                 parseParameters(attrs);
     120              :                 break;
     121              :             // other
     122            0 :             case SUMO_TAG_INTERVAL: {
     123            0 :                 parseInterval(attrs);
     124              :                 break;
     125              :             }
     126            0 :             default:
     127              :                 // get vehicle type Base object
     128            0 :                 const auto vTypeObject = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
     129              :                 // parse embedded car following model information
     130            0 :                 if (vTypeObject && (vTypeObject->getTag() == SUMO_TAG_VTYPE)) {
     131              :                     // nested CFM attributes
     132            0 :                     return parseNestedCFM(tag, attrs, vTypeObject);
     133              :                 } else {
     134              :                     // tag cannot be parsed in routeHandler
     135            0 :                     myCommonXMLStructure.abortSUMOBaseOBject();
     136              :                     return false;
     137              :                 }
     138              :         }
     139            0 :     } catch (InvalidArgument& e) {
     140            0 :         WRITE_ERROR(e.what());
     141            0 :     }
     142              :     return true;
     143              : }
     144              : 
     145              : 
     146              : void
     147            0 : RouteHandler::endParseAttributes() {
     148              :     // get last inserted object
     149            0 :     CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
     150              :     // check tag
     151            0 :     if (obj) {
     152              :         // close SUMOBaseOBject
     153            0 :         myCommonXMLStructure.closeSUMOBaseOBject();
     154              :         // get parent tag (if exist)
     155            0 :         const auto parentTag = obj->getParentSumoBaseObject() ? obj->getParentSumoBaseObject()->getTag() : SUMO_TAG_NOTHING;
     156            0 :         switch (obj->getTag()) {
     157              :             // specia case for route (because can be embedded)
     158            0 :             case SUMO_TAG_ROUTE:
     159              :                 // only parse non-embedded and without distributionsroutes
     160            0 :                 if ((obj->getStringAttribute(SUMO_ATTR_ID).size() > 0) &&
     161              :                         (parentTag != SUMO_TAG_ROUTE_DISTRIBUTION)) {
     162              :                     // parse route and all their childrens
     163            0 :                     parseSumoBaseObject(obj);
     164              :                     // delete object (and all of their childrens)
     165            0 :                     delete obj;
     166              :                 }
     167              :                 break;
     168              :             // demand elements
     169            0 :             case SUMO_TAG_VTYPE:
     170              :                 // only parse vTypes without distributions
     171            0 :                 if (parentTag != SUMO_TAG_VTYPE_DISTRIBUTION) {
     172              :                     // parse vType and all their childrens
     173            0 :                     parseSumoBaseObject(obj);
     174              :                     // delete object (and all of their childrens)
     175            0 :                     delete obj;
     176              :                 }
     177              :                 break;
     178            0 :             case SUMO_TAG_VTYPE_DISTRIBUTION:
     179              :             case SUMO_TAG_ROUTE_DISTRIBUTION:
     180              :             case SUMO_TAG_TRIP:
     181              :             case SUMO_TAG_VEHICLE:
     182              :             case SUMO_TAG_FLOW:
     183              :             case SUMO_TAG_PERSON:
     184              :             case SUMO_TAG_PERSONFLOW:
     185              :             case SUMO_TAG_CONTAINER:
     186              :             case SUMO_TAG_CONTAINERFLOW:
     187              :                 // parse object and all their childrens
     188            0 :                 parseSumoBaseObject(obj);
     189              :                 // delete object (and all of their childrens)
     190            0 :                 delete obj;
     191              :                 break;
     192              :             default:
     193              :                 break;
     194              :         }
     195              :     }
     196            0 : }
     197              : 
     198              : 
     199              : void
     200            0 : RouteHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
     201              :     // switch tag
     202            0 :     switch (obj->getTag()) {
     203              :         // vTypes
     204            0 :         case SUMO_TAG_VTYPE:
     205            0 :             if (buildVType(obj,
     206              :                            obj->getVehicleTypeParameter())) {
     207            0 :                 obj->markAsCreated();
     208              :             }
     209              :             break;
     210            0 :         case SUMO_TAG_VTYPE_DISTRIBUTION:
     211            0 :             if (buildVTypeDistribution(obj,
     212              :                                        obj->getStringAttribute(SUMO_ATTR_ID),
     213              :                                        obj->getIntAttribute(SUMO_ATTR_DETERMINISTIC),
     214              :                                        obj->getStringListAttribute(SUMO_ATTR_VTYPES),
     215              :                                        obj->getDoubleListAttribute(SUMO_ATTR_PROBS))) {
     216            0 :                 obj->markAsCreated();
     217              :             }
     218              :             break;
     219              :         // route
     220            0 :         case SUMO_TAG_ROUTE:
     221            0 :             if (obj->getStringAttribute(SUMO_ATTR_ID).empty()) {
     222            0 :                 if (buildEmbeddedRoute(obj,
     223              :                                    obj->getStringListAttribute(SUMO_ATTR_EDGES),
     224              :                                    obj->getColorAttribute(SUMO_ATTR_COLOR),
     225              :                                    obj->getIntAttribute(SUMO_ATTR_REPEAT),
     226              :                                    obj->getTimeAttribute(SUMO_ATTR_CYCLETIME),
     227            0 :                                    obj->getParameters())) {
     228            0 :                     obj->markAsCreated();
     229              :                 }
     230              :             } else {
     231            0 :                 if (buildRoute(obj,
     232              :                                obj->getStringAttribute(SUMO_ATTR_ID),
     233              :                                obj->getVClass(),
     234              :                                obj->getStringListAttribute(SUMO_ATTR_EDGES),
     235              :                                obj->getColorAttribute(SUMO_ATTR_COLOR),
     236              :                                obj->getIntAttribute(SUMO_ATTR_REPEAT),
     237              :                                obj->getTimeAttribute(SUMO_ATTR_CYCLETIME),
     238              :                                obj->getDoubleAttribute(SUMO_ATTR_PROB),
     239            0 :                                obj->getParameters())) {
     240            0 :                     obj->markAsCreated();
     241              :                 }
     242              :             }
     243              :             break;
     244            0 :         case SUMO_TAG_ROUTE_DISTRIBUTION:
     245            0 :             if (buildRouteDistribution(obj,
     246              :                                        obj->getStringAttribute(SUMO_ATTR_ID),
     247              :                                        obj->getStringListAttribute(SUMO_ATTR_ROUTES),
     248              :                                        obj->getDoubleListAttribute(SUMO_ATTR_PROBS))) {
     249            0 :                 obj->markAsCreated();
     250              :             }
     251              :             break;
     252              :         // vehicles
     253            0 :         case SUMO_TAG_TRIP:
     254            0 :             if (obj->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) &&
     255            0 :                 obj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION)) {
     256              :                 // build trip with from-to junctions
     257            0 :                 if (buildTripJunctions(obj,
     258              :                                        obj->getVehicleParameter(),
     259              :                                        obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
     260              :                                        obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION))) {
     261            0 :                     obj->markAsCreated();
     262              :                 }
     263            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_TAZ) &&
     264            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_TAZ)) {
     265              :                 // build trip with from-to TAZs
     266            0 :                 if (buildTripTAZs(obj,
     267              :                                   obj->getVehicleParameter(),
     268              :                                   obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
     269              :                                   obj->getStringAttribute(SUMO_ATTR_TO_TAZ))) {
     270            0 :                     obj->markAsCreated();
     271              :                 }
     272              :             } else {
     273              :                 // build trip with from-to edges
     274            0 :                 if (buildTrip(obj,
     275              :                               obj->getVehicleParameter(),
     276            0 :                               obj->hasStringAttribute(SUMO_ATTR_FROM) ? obj->getStringAttribute(SUMO_ATTR_FROM) : "",
     277            0 :                               obj->hasStringAttribute(SUMO_ATTR_TO) ? obj->getStringAttribute(SUMO_ATTR_TO) : "")) {
     278            0 :                     obj->markAsCreated();
     279              :                 }
     280              :             }
     281              :             break;
     282            0 :         case SUMO_TAG_VEHICLE:
     283            0 :             if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
     284            0 :                 if (buildVehicleOverRoute(obj,
     285              :                                           obj->getVehicleParameter())) {
     286            0 :                     obj->markAsCreated();
     287              :                 }
     288              :             }
     289              :             break;
     290              :         // flows
     291            0 :         case SUMO_TAG_FLOW:
     292            0 :             if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
     293              :                 // build flow over route
     294            0 :                 if (buildFlowOverRoute(obj,
     295              :                                        obj->getVehicleParameter())) {
     296            0 :                     obj->markAsCreated();
     297              :                 }
     298            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) &&
     299            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION)) {
     300              :                 // build flow with from-to junctions
     301            0 :                 if (buildFlowJunctions(obj,
     302              :                                        obj->getVehicleParameter(),
     303              :                                        obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
     304              :                                        obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION))) {
     305            0 :                     obj->markAsCreated();
     306              :                 }
     307            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_TAZ) &&
     308            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_TAZ)) {
     309              :                 // build flow with from-to TAZs
     310            0 :                 if (buildFlowTAZs(obj,
     311              :                                   obj->getVehicleParameter(),
     312              :                                   obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
     313              :                                   obj->getStringAttribute(SUMO_ATTR_TO_TAZ))) {
     314            0 :                     obj->markAsCreated();
     315              :                 }
     316            0 :             } else if ((obj->getSumoBaseObjectChildren().size() == 0) ||
     317            0 :                        (obj->getSumoBaseObjectChildren().front()->getTag() != SUMO_TAG_ROUTE)) {
     318              :                 // build flow with from-to edges
     319            0 :                 if (buildFlow(obj,
     320              :                               obj->getVehicleParameter(),
     321            0 :                               obj->hasStringAttribute(SUMO_ATTR_FROM) ? obj->getStringAttribute(SUMO_ATTR_FROM) : "",
     322            0 :                               obj->hasStringAttribute(SUMO_ATTR_TO) ? obj->getStringAttribute(SUMO_ATTR_TO) : "")) {
     323            0 :                     obj->markAsCreated();
     324              :                 }
     325              :             }
     326              :             break;
     327              :         // persons
     328            0 :         case SUMO_TAG_PERSON:
     329            0 :             if (buildPerson(obj,
     330              :                             obj->getVehicleParameter())) {
     331            0 :                 obj->markAsCreated();
     332              :             }
     333              :             break;
     334            0 :         case SUMO_TAG_PERSONFLOW:
     335            0 :             if (buildPersonFlow(obj,
     336              :                                 obj->getVehicleParameter())) {
     337            0 :                 obj->markAsCreated();
     338              :             }
     339              :             break;
     340              :         // person plans
     341            0 :         case SUMO_TAG_PERSONTRIP:
     342            0 :             if (buildPersonTrip(obj,
     343              :                                 obj->getPlanParameters(),
     344              :                                 obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     345              :                                 obj->getStringListAttribute(SUMO_ATTR_VTYPES),
     346              :                                 obj->getStringListAttribute(SUMO_ATTR_MODES),
     347              :                                 obj->getStringListAttribute(SUMO_ATTR_LINES),
     348              :                                 obj->getDoubleAttribute(SUMO_ATTR_WALKFACTOR),
     349              :                                 obj->getStringAttribute(SUMO_ATTR_GROUP))) {
     350            0 :                 obj->markAsCreated();
     351              :             }
     352              :             break;
     353            0 :         case SUMO_TAG_RIDE:
     354            0 :             if (buildRide(obj,
     355              :                           obj->getPlanParameters(),
     356              :                           obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     357              :                           obj->getStringListAttribute(SUMO_ATTR_LINES),
     358              :                           obj->getStringAttribute(SUMO_ATTR_GROUP))) {
     359            0 :                 obj->markAsCreated();
     360              :             }
     361              :             break;
     362            0 :         case SUMO_TAG_WALK:
     363            0 :             if (buildWalk(obj,
     364              :                           obj->getPlanParameters(),
     365              :                           obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     366              :                           obj->getDoubleAttribute(SUMO_ATTR_SPEED),
     367              :                           obj->getTimeAttribute(SUMO_ATTR_DURATION))) {
     368            0 :                 obj->markAsCreated();
     369              :             }
     370              :             break;
     371              :         // container
     372            0 :         case SUMO_TAG_CONTAINER:
     373            0 :             if (buildContainer(obj,
     374              :                               obj->getVehicleParameter())) {
     375            0 :                 obj->markAsCreated();
     376              :             }
     377              :             break;
     378            0 :         case SUMO_TAG_CONTAINERFLOW:
     379            0 :             if (buildContainerFlow(obj,
     380              :                                    obj->getVehicleParameter())) {
     381            0 :                 obj->markAsCreated();
     382              :             }
     383              :             break;
     384              :         // container plans
     385            0 :         case SUMO_TAG_TRANSPORT:
     386            0 :             if (buildTransport(obj,
     387              :                                obj->getPlanParameters(),
     388              :                                obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     389              :                                obj->getStringListAttribute(SUMO_ATTR_LINES),
     390              :                                obj->getStringAttribute(SUMO_ATTR_GROUP))) {
     391            0 :                 obj->markAsCreated();
     392              :             }
     393              :             break;
     394            0 :         case SUMO_TAG_TRANSHIP:
     395            0 :             if (buildTranship(obj,
     396              :                               obj->getPlanParameters(),
     397              :                               obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     398              :                               obj->getDoubleAttribute(SUMO_ATTR_DEPARTPOS),
     399              :                               obj->getDoubleAttribute(SUMO_ATTR_SPEED),
     400              :                               obj->getTimeAttribute(SUMO_ATTR_DURATION))) {
     401            0 :                 obj->markAsCreated();
     402              :             }
     403              :             break;
     404              :         // stops
     405            0 :         case SUMO_TAG_STOP:
     406            0 :             if (buildStop(obj,
     407              :                           obj->getPlanParameters(),
     408              :                           obj->getStopParameter())) {
     409            0 :                 obj->markAsCreated();
     410              :             }
     411              :             break;
     412              :         default:
     413              :             break;
     414              :     }
     415              :     // now iterate over childrens
     416            0 :     for (const auto& child : obj->getSumoBaseObjectChildren()) {
     417              :         // call this function recursively
     418            0 :         parseSumoBaseObject(child);
     419              :     }
     420            0 : }
     421              : 
     422              : 
     423              : void
     424            0 : RouteHandler::parseVType(const SUMOSAXAttributes& attrs) {
     425              :     // parse vehicleType
     426            0 :     SUMOVTypeParameter* vehicleTypeParameter = SUMOVehicleParserHelper::beginVTypeParsing(attrs, myHardFail, myFilename);
     427            0 :     if (vehicleTypeParameter) {
     428              :         // set tag
     429            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE);
     430              :         // add all attributes
     431            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleTypeParameter(vehicleTypeParameter);
     432              :         // delete vehicleType parameter (because in XMLStructure we have a copy)
     433            0 :         delete vehicleTypeParameter;
     434              :     } else {
     435            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     436              :     }
     437            0 : }
     438              : 
     439              : 
     440              : void
     441            0 : RouteHandler::parseVTypeDistribution(const SUMOSAXAttributes& attrs) {
     442              :     // declare Ok Flag
     443            0 :     bool parsedOk = true;
     444              :     // needed attributes
     445            0 :     const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
     446              :     // optional attributes
     447            0 :     const int deterministic = attrs.getOpt<int>(SUMO_ATTR_DETERMINISTIC, id.c_str(), parsedOk, -1);
     448            0 :     const std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, id.c_str(), parsedOk);
     449            0 :     const std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
     450              :     // check distribution
     451            0 :     if (vTypes.size() != probabilities.size()) {
     452            0 :         parsedOk = writeErrorInvalidDistribution(SUMO_TAG_VTYPE_DISTRIBUTION, id);
     453              :     }
     454            0 :     if (parsedOk) {
     455              :         // set tag
     456            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE_DISTRIBUTION);
     457              :         // add all attributes
     458            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     459            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_DETERMINISTIC, deterministic);
     460            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VTYPES, vTypes);
     461            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleListAttribute(SUMO_ATTR_PROBS, probabilities);
     462              :     } else {
     463            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     464              :     }
     465            0 : }
     466              : 
     467              : 
     468              : void
     469            0 : RouteHandler::parseRoute(const SUMOSAXAttributes& attrs) {
     470              :     // get embedded route flag
     471            0 :     const bool embeddedRoute = isEmbeddedRoute(attrs);
     472              :     // first check if this is an embedded route
     473            0 :     if ((embeddedRoute && attrs.hasAttribute(SUMO_ATTR_ID)) || (!embeddedRoute && !attrs.hasAttribute(SUMO_ATTR_ID))) {
     474            0 :         writeError(TL("a route must be defined either within a vehicle/flow or with an ID attribute"));
     475              :     } else {
     476              :         // declare Ok Flag
     477            0 :         bool parsedOk = true;
     478              :         // special case for ID
     479            0 :         const std::string id = attrs.getOpt<std::string>(SUMO_ATTR_ID, "", parsedOk, "");
     480              :         // needed attributes
     481            0 :         const std::vector<std::string> edges = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), parsedOk);
     482              :         // optional attributes
     483            0 :         SUMOVehicleClass vClass = SUMOVehicleParserHelper::parseVehicleClass(attrs, id);
     484            0 :         const RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), parsedOk, RGBColor::INVISIBLE);
     485            0 :         const int repeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, id.c_str(), parsedOk, 0);
     486            0 :         const SUMOTime cycleTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CYCLETIME, id.c_str(), parsedOk, 0);
     487            0 :         const double probability = attrs.getOpt<double>(SUMO_ATTR_PROB, id.c_str(), parsedOk, 0);
     488              :         // check attributes
     489            0 :         if (!checkNegative(SUMO_TAG_ROUTE, id, SUMO_ATTR_CYCLETIME, cycleTime, true)) {
     490            0 :             parsedOk = false;
     491              :         }
     492            0 :         if (parsedOk) {
     493              :             // set tag
     494            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
     495              :             // add all attributes
     496            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     497            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setVClass(vClass);
     498            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_EDGES, edges);
     499            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addColorAttribute(SUMO_ATTR_COLOR, color);
     500            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_REPEAT, repeat);
     501            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_CYCLETIME, cycleTime);
     502            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probability);
     503              :         } else {
     504            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     505              :         }
     506            0 :     }
     507            0 : }
     508              : 
     509              : 
     510              : void
     511            0 : RouteHandler::parseRouteDistribution(const SUMOSAXAttributes& attrs) {
     512              :     // declare Ok Flag
     513            0 :     bool parsedOk = true;
     514              :     // needed attributes
     515            0 :     const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
     516              :     // optional attributes
     517            0 :     const std::vector<std::string> routes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_ROUTES, id.c_str(), parsedOk);
     518            0 :     const std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
     519              :     // check distribution
     520            0 :     if (routes.size() != probabilities.size()) {
     521            0 :         parsedOk = writeErrorInvalidDistribution(SUMO_TAG_ROUTE_DISTRIBUTION, id);
     522              :     }
     523            0 :     if (parsedOk) {
     524              :         // set tag
     525            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE_DISTRIBUTION);
     526              :         // add all attributes
     527            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     528            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_ROUTES, routes);
     529            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleListAttribute(SUMO_ATTR_PROBS, probabilities);
     530              :     } else {
     531            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     532              :     }
     533            0 : }
     534              : 
     535              : 
     536              : void
     537            0 : RouteHandler::parseTrip(const SUMOSAXAttributes& attrs) {
     538              :     // declare Ok Flag
     539            0 :     bool parsedOk = true;
     540              :     // parse vehicle
     541            0 :     SUMOVehicleParameter* tripParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_TRIP, attrs, myHardFail);
     542            0 :     if (tripParameter) {
     543              :         // check from/to edge/junction
     544            0 :         if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
     545            0 :             writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
     546            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     547            0 :         } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
     548            0 :             writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
     549            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     550            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
     551              :             // from-to attributes
     552            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_JUNCTION, tripParameter->id.c_str(), parsedOk);
     553            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_JUNCTION, tripParameter->id.c_str(), parsedOk);
     554            0 :             if (parsedOk) {
     555              :                 // set tag
     556            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
     557              :                 // set vehicle parameters
     558            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
     559              :                 // add other attributes
     560            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
     561            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
     562              :             } else {
     563            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     564              :             }
     565            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
     566              :             // from-to attributes
     567            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, tripParameter->id.c_str(), parsedOk);
     568            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, tripParameter->id.c_str(), parsedOk);
     569            0 :             if (parsedOk) {
     570              :                 // set tag
     571            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
     572              :                 // set vehicle parameters
     573            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
     574              :                 // add other attributes
     575            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_TAZ, fromJunction);
     576            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
     577              :             } else {
     578            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     579              :             }
     580              :         } else {
     581              :             // from-to attributes
     582            0 :             const std::string from = attrs.getOpt<std::string>(SUMO_ATTR_FROM, tripParameter->id.c_str(), parsedOk, "");
     583            0 :             const std::string to = attrs.getOpt<std::string>(SUMO_ATTR_TO, tripParameter->id.c_str(), parsedOk, "");
     584              :             // optional attributes
     585            0 :             const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, tripParameter->id.c_str(), parsedOk);
     586            0 :             if (parsedOk) {
     587              :                 // set tag
     588            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
     589              :                 // set vehicle parameters
     590            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
     591              :                 // add other attributes
     592            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
     593            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
     594            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
     595              :             } else {
     596            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     597              :             }
     598            0 :         }
     599              :         // delete trip parameter (because in XMLStructure we have a copy)
     600            0 :         delete tripParameter;
     601              :     } else {
     602            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     603              :     }
     604            0 : }
     605              : 
     606              : 
     607              : void
     608            0 : RouteHandler::parseVehicle(const SUMOSAXAttributes& attrs) {
     609              :     // first parse vehicle
     610            0 :     SUMOVehicleParameter* vehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_VEHICLE, attrs, myHardFail);
     611            0 :     if (vehicleParameter) {
     612              :         // set tag
     613            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VEHICLE);
     614              :         // set vehicle parameters
     615            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(vehicleParameter);
     616              :         // delete vehicle parameter (because in XMLStructure we have a copy)
     617            0 :         delete vehicleParameter;
     618              :     } else {
     619            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     620              :     }
     621            0 : }
     622              : 
     623              : 
     624              : void
     625            0 : RouteHandler::parseFlow(const SUMOSAXAttributes& attrs) {
     626              :     // declare Ok Flag
     627            0 :     bool parsedOk = true;
     628              :     // first parse flow
     629            0 :     SUMOVehicleParameter* flowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     630            0 :     if (flowParameter) {
     631              :         // set vehicle parameters
     632            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(flowParameter);
     633              :         // check from/to edge/junction
     634            0 :         if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
     635            0 :             writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
     636            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     637            0 :         } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
     638            0 :             writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
     639            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     640            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
     641              :             // from-to attributes
     642            0 :             const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, flowParameter->id.c_str(), parsedOk);
     643            0 :             const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, flowParameter->id.c_str(), parsedOk);
     644              :             // optional attributes
     645            0 :             const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, flowParameter->id.c_str(), parsedOk);
     646            0 :             if (parsedOk) {
     647              :                 // set tag
     648            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     649              :                 // add other attributes
     650            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
     651            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
     652            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
     653              :             } else {
     654            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     655              :             }
     656            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
     657              :             // from-to attributes
     658            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_JUNCTION, flowParameter->id.c_str(), parsedOk);
     659            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_JUNCTION, flowParameter->id.c_str(), parsedOk);
     660            0 :             if (parsedOk) {
     661              :                 // set tag
     662            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     663              :                 // add other attributes
     664            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
     665            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
     666              :             } else {
     667            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     668              :             }
     669            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
     670              :             // from-to attributes
     671            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, flowParameter->id.c_str(), parsedOk);
     672            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, flowParameter->id.c_str(), parsedOk);
     673            0 :             if (parsedOk) {
     674              :                 // set tag
     675            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     676              :                 // add other attributes
     677            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_TAZ, fromJunction);
     678            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
     679              :             } else {
     680            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     681              :             }
     682            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
     683              :             // from-to attributes
     684            0 :             const std::string route = attrs.get<std::string>(SUMO_ATTR_ROUTE, flowParameter->id.c_str(), parsedOk);
     685            0 :             if (parsedOk) {
     686              :                 // set tag
     687            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     688              :                 // add other attributes
     689            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ROUTE, route);
     690              :             } else {
     691            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     692              :             }
     693              :         } else {
     694              :             // set tag
     695            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     696              :         }
     697              :         // delete flow parameter (because in XMLStructure we have a copy)
     698            0 :         delete flowParameter;
     699              :     } else {
     700            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     701              :     }
     702            0 : }
     703              : 
     704              : 
     705              : void
     706            0 : RouteHandler::parseStop(const SUMOSAXAttributes& attrs) {
     707              :     // declare Ok Flag
     708            0 :     bool parsedOk = true;
     709              :     // declare stop
     710            0 :     SUMOVehicleParameter::Stop stop;
     711              :     // plan parameters
     712            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     713              :     // get parents
     714              :     std::vector<SumoXMLTag> stopParents;
     715            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::routes.begin(), NamespaceIDs::routes.end());
     716            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::vehicles.begin(), NamespaceIDs::vehicles.end());
     717            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::persons.begin(), NamespaceIDs::persons.end());
     718            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::containers.begin(), NamespaceIDs::containers.end());
     719              :     //  check parents
     720            0 :     checkParsedParent(SUMO_TAG_STOP, stopParents, parsedOk);
     721              :     // parse stop
     722            0 :     if (parsedOk && parseStopParameters(stop, attrs)) {
     723              :         // set tag
     724            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_STOP);
     725              :         // add stop attributes
     726            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     727            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setStopParameter(stop);
     728              :     } else {
     729            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     730              :     }
     731            0 : }
     732              : 
     733              : 
     734              : void
     735            0 : RouteHandler::parsePerson(const SUMOSAXAttributes& attrs) {
     736              :     // first parse vehicle
     737            0 :     SUMOVehicleParameter* personParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_PERSON, attrs, myHardFail);
     738            0 :     if (personParameter) {
     739              :         // set tag
     740            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSON);
     741              :         // set vehicle parameter
     742            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personParameter);
     743              :         // delete person parameter (because in XMLStructure we have a copy)
     744            0 :         delete personParameter;
     745              :     } else {
     746            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     747              :     }
     748            0 : }
     749              : 
     750              : 
     751              : void
     752            0 : RouteHandler::parsePersonFlow(const SUMOSAXAttributes& attrs) {
     753              :     // first parse flow
     754            0 :     SUMOVehicleParameter* personFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_PERSONFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     755            0 :     if (personFlowParameter) {
     756              :         // set tag
     757            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONFLOW);
     758              :         // set vehicle parameter
     759            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personFlowParameter);
     760              :         // delete person flow parameter (because in XMLStructure we have a copy)
     761            0 :         delete personFlowParameter;
     762              :     } else {
     763            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     764              :     }
     765            0 : }
     766              : 
     767              : 
     768              : void
     769            0 : RouteHandler::parsePersonTrip(const SUMOSAXAttributes& attrs) {
     770              :     // declare Ok Flag
     771            0 :     bool parsedOk = true;
     772              :     // plan parameters
     773            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     774              :     // optional attributes
     775            0 :     const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, "", parsedOk);
     776            0 :     const std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, "", parsedOk);
     777            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     778            0 :     std::vector<std::string> modes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_MODES, "", parsedOk);
     779            0 :     const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     780            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     781            0 :     const double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, "", parsedOk, 0);
     782            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     783              :     // check modes
     784              :     SVCPermissions dummyModeSet;
     785              :     std::string dummyError;
     786            0 :     if (!SUMOVehicleParameter::parsePersonModes(toString(modes), toString(SUMO_TAG_PERSONTRIP), "", dummyModeSet, dummyError)) {
     787            0 :         WRITE_WARNING(dummyError);
     788              :         modes.clear();
     789              :     }
     790              :     // check parents
     791            0 :     checkParsedParent(SUMO_TAG_PERSONTRIP, NamespaceIDs::persons, parsedOk);
     792            0 :     if (parsedOk) {
     793              :         // set tag
     794            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONTRIP);
     795              :         // add all attributes
     796            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     797            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VTYPES, vTypes);
     798            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_MODES, modes);
     799            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     800            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     801            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     802            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_WALKFACTOR, walkFactor);
     803            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     804              :     } else {
     805            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     806              :     }
     807            0 : }
     808              : 
     809              : 
     810              : void
     811            0 : RouteHandler::parseWalk(const SUMOSAXAttributes& attrs) {
     812            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
     813            0 :         writeError(TL("Speed and duration attributes cannot be defined together in walks"));
     814            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     815              :     } else {
     816              :         // declare Ok Flag
     817            0 :         bool parsedOk = true;
     818              :         // plan parameters
     819            0 :         const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     820              :         // optional attributes
     821            0 :         const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     822            0 :         const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     823            0 :         const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
     824            0 :         const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
     825              :         // check parents
     826            0 :         checkParsedParent(SUMO_TAG_WALK, NamespaceIDs::persons, parsedOk);
     827            0 :         if (parsedOk) {
     828              :             // set tag
     829            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_WALK);
     830              :             // add all attributes
     831            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     832            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     833            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     834            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
     835            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
     836              :         } else {
     837            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     838              :         }
     839            0 :     }
     840            0 : }
     841              : 
     842              : 
     843              : void
     844            0 : RouteHandler::parseRide(const SUMOSAXAttributes& attrs) {
     845              :     // declare Ok Flag
     846            0 :     bool parsedOk = true;
     847              :     // plan parameters
     848            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     849              :     // optional attributes
     850            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     851            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     852            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     853              :     // check parents
     854            0 :     checkParsedParent(SUMO_TAG_RIDE, NamespaceIDs::persons, parsedOk);
     855            0 :     if (parsedOk) {
     856              :         // set tag
     857            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_RIDE);
     858              :         // add all attributes
     859            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     860            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     861            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     862            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     863              :     } else {
     864            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     865              :     }
     866            0 : }
     867              : 
     868              : 
     869              : void
     870            0 : RouteHandler::parseContainer(const SUMOSAXAttributes& attrs) {
     871              :     // first parse container
     872            0 :     SUMOVehicleParameter* containerParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_CONTAINER, attrs, myHardFail);
     873            0 :     if (containerParameter) {
     874              :         // set tag
     875            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINER);
     876              :         // set vehicle parameter
     877            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerParameter);
     878              :         // delete container parameter (because in XMLStructure we have a copy)
     879            0 :         delete containerParameter;
     880              :     } else {
     881            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     882              :     }
     883            0 : }
     884              : 
     885              : 
     886              : void
     887            0 : RouteHandler::parseContainerFlow(const SUMOSAXAttributes& attrs) {
     888              :     // first parse flow
     889            0 :     SUMOVehicleParameter* containerFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_CONTAINERFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     890            0 :     if (containerFlowParameter) {
     891              :         // set tag
     892            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINERFLOW);
     893              :         // set vehicle parameter
     894            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerFlowParameter);
     895              :         // delete container flow parameter (because in XMLStructure we have a copy)
     896            0 :         delete containerFlowParameter;
     897              :     } else {
     898            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     899              :     }
     900            0 : }
     901              : 
     902              : 
     903              : void
     904            0 : RouteHandler::parseTransport(const SUMOSAXAttributes& attrs) {
     905              :     // declare Ok Flag
     906            0 :     bool parsedOk = true;
     907              :     // plan parameters
     908            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     909              :     // optional attributes
     910            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     911            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     912            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     913              :     // check parents
     914            0 :     checkParsedParent(SUMO_TAG_TRANSPORT, NamespaceIDs::containers, parsedOk);
     915            0 :     if (parsedOk) {
     916              :         // set tag
     917            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSPORT);
     918              :         // add all attributes
     919            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     920            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     921            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     922            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     923              :     } else {
     924            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     925              :     }
     926            0 : }
     927              : 
     928              : 
     929              : void
     930            0 : RouteHandler::parseTranship(const SUMOSAXAttributes& attrs) {
     931            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
     932            0 :         writeError(TL("Speed and duration attributes cannot be defined together in tranships"));
     933            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     934              :     } else {
     935              :         // declare Ok Flag
     936            0 :         bool parsedOk = true;
     937              :         // plan parameters
     938            0 :         const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     939              :         // optional attributes
     940            0 :         const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     941            0 :         const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     942            0 :         const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
     943            0 :         const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
     944              :         // check parents
     945            0 :         checkParsedParent(SUMO_TAG_TRANSHIP, NamespaceIDs::containers, parsedOk);
     946            0 :         if (parsedOk) {
     947              :             // set tag
     948            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSHIP);
     949              :             // add all attributes
     950            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     951            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     952            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     953            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
     954            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
     955              :         } else {
     956            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_NOTHING);
     957              :         }
     958            0 :     }
     959            0 : }
     960              : 
     961              : 
     962              : void
     963            0 : RouteHandler::parseInterval(const SUMOSAXAttributes& attrs) {
     964              :     // declare Ok Flag
     965            0 :     bool parsedOk = true;
     966              :     // just parse begin and end default
     967            0 :     myFlowBeginDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, parsedOk);
     968            0 :     myFlowEndDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, parsedOk);
     969            0 : }
     970              : 
     971              : 
     972              : bool
     973            0 : RouteHandler::parseNestedCFM(const SumoXMLTag tag, const SUMOSAXAttributes& attrs, CommonXMLStructure::SumoBaseObject* vTypeObject) {
     974              :     // write warning info
     975            0 :     WRITE_WARNINGF(TL("Defining car-following parameters in a nested element is deprecated in vType '%', use attributes instead!"), vTypeObject->getStringAttribute(SUMO_ATTR_ID));
     976              :     // get vType to modify it
     977            0 :     auto vType = vTypeObject->getVehicleTypeParameter();
     978              :     // parse nested CFM attributes
     979            0 :     if (SUMOVehicleParserHelper::parseCFMParams(&vType, tag, attrs, true)) {
     980            0 :         vTypeObject->setVehicleTypeParameter(&vType);
     981              :         return true;
     982            0 :     } else if (myHardFail) {
     983            0 :         throw ProcessError(TL("Invalid parsing embedded VType"));
     984              :     } else {
     985            0 :         return writeError(TL("Invalid parsing embedded VType"));
     986              :     }
     987              :     return false;
     988            0 : }
     989              : 
     990              : 
     991              : bool
     992            0 : RouteHandler::parseStopParameters(SUMOVehicleParameter::Stop& stop, const SUMOSAXAttributes& attrs) {
     993              :     // check stop parameters
     994            0 :     if (attrs.hasAttribute(SUMO_ATTR_ARRIVAL)) {
     995            0 :         stop.parametersSet |= STOP_ARRIVAL_SET;
     996              :     }
     997            0 :     if (attrs.hasAttribute(SUMO_ATTR_DURATION)) {
     998            0 :         stop.parametersSet |= STOP_DURATION_SET;
     999              :     }
    1000            0 :     if (attrs.hasAttribute(SUMO_ATTR_UNTIL)) {
    1001            0 :         stop.parametersSet |= STOP_UNTIL_SET;
    1002              :     }
    1003            0 :     if (attrs.hasAttribute(SUMO_ATTR_STARTED)) {
    1004            0 :         stop.parametersSet |= STOP_STARTED_SET;
    1005              :     }
    1006            0 :     if (attrs.hasAttribute(SUMO_ATTR_ENDED)) {
    1007            0 :         stop.parametersSet |= STOP_ENDED_SET;
    1008              :     }
    1009            0 :     if (attrs.hasAttribute(SUMO_ATTR_EXTENSION)) {
    1010            0 :         stop.parametersSet |= STOP_EXTENSION_SET;
    1011              :     }
    1012            0 :     if (attrs.hasAttribute(SUMO_ATTR_ENDPOS)) {
    1013            0 :         stop.parametersSet |= STOP_END_SET;
    1014              :     }
    1015            0 :     if (attrs.hasAttribute(SUMO_ATTR_STARTPOS)) {
    1016            0 :         stop.parametersSet |= STOP_START_SET;
    1017              :     }
    1018            0 :     if (attrs.hasAttribute(SUMO_ATTR_POSITION_LAT)) {
    1019            0 :         stop.parametersSet |= STOP_POSLAT_SET;
    1020              :     }
    1021            0 :     if (attrs.hasAttribute(SUMO_ATTR_TRIGGERED)) {
    1022            0 :         stop.parametersSet |= STOP_TRIGGER_SET;
    1023              :     }
    1024              :     // legacy attribute
    1025            0 :     if (attrs.hasAttribute(SUMO_ATTR_CONTAINER_TRIGGERED)) {
    1026            0 :         stop.parametersSet |= STOP_TRIGGER_SET;
    1027              :     }
    1028            0 :     if (attrs.hasAttribute(SUMO_ATTR_PARKING)) {
    1029            0 :         stop.parametersSet |= STOP_PARKING_SET;
    1030              :     }
    1031            0 :     if (attrs.hasAttribute(SUMO_ATTR_EXPECTED)) {
    1032            0 :         stop.parametersSet |= STOP_EXPECTED_SET;
    1033              :     }
    1034            0 :     if (attrs.hasAttribute(SUMO_ATTR_PERMITTED)) {
    1035            0 :         stop.parametersSet |= STOP_PERMITTED_SET;
    1036              :     }
    1037            0 :     if (attrs.hasAttribute(SUMO_ATTR_EXPECTED_CONTAINERS)) {
    1038            0 :         stop.parametersSet |= STOP_EXPECTED_CONTAINERS_SET;
    1039              :     }
    1040            0 :     if (attrs.hasAttribute(SUMO_ATTR_TRIP_ID)) {
    1041            0 :         stop.parametersSet |= STOP_TRIP_ID_SET;
    1042              :     }
    1043            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPLIT)) {
    1044            0 :         stop.parametersSet |= STOP_SPLIT_SET;
    1045              :     }
    1046            0 :     if (attrs.hasAttribute(SUMO_ATTR_JOIN)) {
    1047            0 :         stop.parametersSet |= STOP_JOIN_SET;
    1048              :     }
    1049            0 :     if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
    1050            0 :         stop.parametersSet |= STOP_LINE_SET;
    1051              :     }
    1052            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
    1053            0 :         stop.parametersSet |= STOP_SPEED_SET;
    1054              :     }
    1055            0 :     if (attrs.hasAttribute(SUMO_ATTR_ONDEMAND)) {
    1056            0 :         stop.parametersSet |= STOP_ONDEMAND_SET;
    1057              :     }
    1058            0 :     if (attrs.hasAttribute(SUMO_ATTR_JUMP)) {
    1059            0 :         stop.parametersSet |= STOP_JUMP_SET;
    1060              :     }
    1061              :     // get parameters
    1062            0 :     bool ok = true;
    1063              :     // edge/lane
    1064            0 :     stop.edge = attrs.getOpt<std::string>(SUMO_ATTR_EDGE, nullptr, ok, "");
    1065            0 :     stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, ok, stop.busstop);
    1066              :     // check errors
    1067            0 :     if (!stop.edge.empty() && !stop.lane.empty()) {
    1068            0 :         return writeError(TL("A stop must be defined either with an edge or with an lane, not both"));
    1069              :     }
    1070              :     // stopping places
    1071            0 :     stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
    1072              :     if (stop.busstop.empty()) {
    1073            0 :         stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, nullptr, ok, stop.busstop);
    1074              :     }
    1075            0 :     stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
    1076            0 :     stop.overheadWireSegment = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, nullptr, ok, "");
    1077            0 :     stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
    1078            0 :     stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
    1079              :     //check stopping places
    1080            0 :     const int numStoppingPlaces = !stop.busstop.empty() + !stop.chargingStation.empty() + !stop.overheadWireSegment.empty() +
    1081            0 :                                   !stop.containerstop.empty() + !stop.parkingarea.empty();
    1082            0 :     if (numStoppingPlaces > 1) {
    1083            0 :         return writeError(TL("A stop must be defined only in a StoppingPlace"));
    1084            0 :     } else if ((numStoppingPlaces == 0) && stop.edge.empty() && stop.lane.empty()) {
    1085            0 :         return writeError(TL("A stop must be defined in an edge, a lane, or in a StoppingPlace"));
    1086              :     }
    1087              :     // declare error suffix
    1088              :     std::string errorSuffix;
    1089            0 :     if (stop.busstop != "") {
    1090            0 :         errorSuffix = " at '" + stop.busstop + "'" + errorSuffix;
    1091            0 :     } else if (stop.chargingStation != "") {
    1092            0 :         errorSuffix = " at '" + stop.chargingStation + "'" + errorSuffix;
    1093            0 :     } else if (stop.overheadWireSegment != "") {
    1094            0 :         errorSuffix = " at '" + stop.overheadWireSegment + "'" + errorSuffix;
    1095            0 :     } else if (stop.containerstop != "") {
    1096            0 :         errorSuffix = " at '" + stop.containerstop + "'" + errorSuffix;
    1097            0 :     } else if (stop.parkingarea != "") {
    1098            0 :         errorSuffix = " at '" + stop.parkingarea + "'" + errorSuffix;
    1099            0 :     } else if (stop.edge != "") {
    1100            0 :         errorSuffix = " at '" + stop.edge + "'" + errorSuffix;
    1101              :     } else {
    1102            0 :         errorSuffix = " on lane '" + stop.lane + "'" + errorSuffix;
    1103              :     }
    1104              :     // speed for counting as stopped
    1105            0 :     stop.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, 0);
    1106            0 :     if (stop.speed < 0) {
    1107            0 :         return writeError("Speed cannot be negative for stop" + errorSuffix);
    1108              :         return false;
    1109              :     }
    1110              :     // get the standing duration
    1111            0 :     bool expectTrigger = !attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL) && !attrs.hasAttribute(SUMO_ATTR_SPEED);
    1112            0 :     std::vector<std::string> triggers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_TRIGGERED, nullptr, ok);
    1113              :     // legacy
    1114            0 :     if (attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, false)) {
    1115            0 :         triggers.push_back(toString(SUMO_TAG_CONTAINER));
    1116              :     };
    1117            0 :     SUMOVehicleParameter::parseStopTriggers(triggers, expectTrigger, stop);
    1118            0 :     stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, ok, 0);
    1119            0 :     stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, ok, 0);
    1120            0 :     stop.friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
    1121            0 :     stop.arrival = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ARRIVAL, nullptr, ok, -1);
    1122            0 :     stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, nullptr, ok, -1);
    1123            0 :     stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, -1);
    1124            0 :     if (!expectTrigger && (!ok || (stop.duration < 0 && stop.until < 0 && stop.speed == 0))) {
    1125            0 :         return writeError("Invalid duration or end time is given for a stop" + errorSuffix);
    1126              :         return false;
    1127              :     }
    1128            0 :     stop.extension = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EXTENSION, nullptr, ok, -1);
    1129            0 :     const bool defaultParking = (stop.triggered || stop.containerTriggered || stop.parkingarea != "");
    1130            0 :     stop.parking = attrs.getOpt<ParkingType>(SUMO_ATTR_PARKING, nullptr, ok, defaultParking ? ParkingType::OFFROAD : ParkingType::ONROAD);
    1131            0 :     if ((stop.parkingarea != "") && (stop.parking == ParkingType::ONROAD)) {
    1132            0 :         WRITE_WARNING("Stop at parkingarea overrides attribute 'parking' for stop" + errorSuffix);
    1133            0 :         stop.parking = ParkingType::OFFROAD;
    1134              :     }
    1135            0 :     if (!ok) {
    1136            0 :         return writeError("Invalid bool for 'triggered', 'containerTriggered' or 'parking' for stop" + errorSuffix);
    1137              :         return false;
    1138              :     }
    1139              :     // expected persons
    1140            0 :     const std::vector<std::string>& expected = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED, nullptr, ok);
    1141              :     stop.awaitedPersons.insert(expected.begin(), expected.end());
    1142            0 :     if (stop.awaitedPersons.size() > 0 && (stop.parametersSet & STOP_TRIGGER_SET) == 0) {
    1143            0 :         stop.triggered = true;
    1144            0 :         if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
    1145            0 :             stop.parking = ParkingType::OFFROAD;
    1146              :         }
    1147              :     }
    1148              :     // permitted transportables
    1149            0 :     const std::vector<std::string>& permitted = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_PERMITTED, nullptr, ok);
    1150              :     stop.permitted.insert(permitted.begin(), permitted.end());
    1151              :     // expected containers
    1152            0 :     const std::vector<std::string>& expectedContainers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED_CONTAINERS, nullptr, ok);
    1153              :     stop.awaitedContainers.insert(expectedContainers.begin(), expectedContainers.end());
    1154            0 :     if (stop.awaitedContainers.size() > 0 && (stop.parametersSet & STOP_CONTAINER_TRIGGER_SET) == 0) {
    1155            0 :         stop.containerTriggered = true;
    1156            0 :         if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
    1157            0 :             stop.parking = ParkingType::OFFROAD;
    1158              :         }
    1159              :     }
    1160              :     // public transport trip id
    1161            0 :     stop.tripId = attrs.getOpt<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok, "");
    1162            0 :     stop.split = attrs.getOpt<std::string>(SUMO_ATTR_SPLIT, nullptr, ok, "");
    1163            0 :     stop.join = attrs.getOpt<std::string>(SUMO_ATTR_JOIN, nullptr, ok, "");
    1164            0 :     stop.line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, nullptr, ok, "");
    1165              :     // index
    1166            0 :     const std::string idx = attrs.getOpt<std::string>(SUMO_ATTR_INDEX, nullptr, ok, "end");
    1167            0 :     if (idx == "end") {
    1168            0 :         stop.index = STOP_INDEX_END;
    1169            0 :     } else if (idx == "fit") {
    1170            0 :         stop.index = STOP_INDEX_FIT;
    1171              :     } else {
    1172            0 :         stop.index = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
    1173            0 :         if (!ok || stop.index < 0) {
    1174            0 :             return writeError("Invalid 'index' for stop" + errorSuffix);
    1175              :             return false;
    1176              :         }
    1177              :     }
    1178            0 :     stop.started = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STARTED, nullptr, ok, -1);
    1179            0 :     stop.ended = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ENDED, nullptr, ok, -1);
    1180            0 :     stop.posLat = attrs.getOpt<double>(SUMO_ATTR_POSITION_LAT, nullptr, ok, INVALID_DOUBLE);
    1181            0 :     stop.actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, nullptr, ok, "");
    1182            0 :     stop.onDemand = attrs.getOpt<bool>(SUMO_ATTR_ONDEMAND, nullptr, ok, false);
    1183            0 :     stop.jump = attrs.getOptSUMOTimeReporting(SUMO_ATTR_JUMP, nullptr, ok, -1);
    1184            0 :     return true;
    1185            0 : }
    1186              : 
    1187              : 
    1188              : bool
    1189            0 : RouteHandler::isEmbeddedRoute(const SUMOSAXAttributes& attrs) const {
    1190              :     // check conditions
    1191            0 :     if (attrs.hasAttribute(SUMO_ATTR_ID)) {
    1192              :         return false;
    1193            0 :     } else if (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject() == nullptr) {
    1194              :         return false;
    1195            0 :     } else if (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ROUTE)) {
    1196              :         return false;
    1197            0 :     } else if (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getTag() == SUMO_TAG_FLOW) {
    1198              :         return true;
    1199            0 :     } else if (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getTag() == SUMO_TAG_VEHICLE) {
    1200              :         return true;
    1201              :     } else {
    1202              :         return false;
    1203              :     }
    1204              : }
    1205              : 
    1206              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1