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

Generated by: LCOV version 2.0-1