LCOV - code coverage report
Current view: top level - src/utils/handlers - RouteHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 634 0
Test Date: 2024-10-24 15:46:30 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              :                 // nested CFM attributes
     128            0 :                 return parseNestedCFM(tag, attrs);
     129              :         }
     130            0 :     } catch (InvalidArgument& e) {
     131            0 :         WRITE_ERROR(e.what());
     132            0 :     }
     133              :     return true;
     134              : }
     135              : 
     136              : 
     137              : void
     138            0 : RouteHandler::endParseAttributes() {
     139              :     // get last inserted object
     140            0 :     CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
     141              :     // close SUMOBaseOBject
     142            0 :     myCommonXMLStructure.closeSUMOBaseOBject();
     143              :     // check tag
     144            0 :     if (obj) {
     145            0 :         switch (obj->getTag()) {
     146              :             // specia case for route (because can be embedded)
     147            0 :             case SUMO_TAG_ROUTE:
     148              :                 // only parse non-embedded and without distributionsroutes
     149            0 :                 if ((obj->getStringAttribute(SUMO_ATTR_ID).size() > 0) &&
     150            0 :                         obj->getParentSumoBaseObject() &&
     151            0 :                         (obj->getParentSumoBaseObject()->getTag() != SUMO_TAG_ROUTE_DISTRIBUTION)) {
     152              :                     // parse route and all their childrens
     153            0 :                     parseSumoBaseObject(obj);
     154              :                     // delete object (and all of their childrens)
     155            0 :                     delete obj;
     156              :                 }
     157              :                 break;
     158              :             // demand elements
     159            0 :             case SUMO_TAG_VTYPE:
     160              :                 // only parse vTypes without distributions
     161            0 :                 if (obj->getParentSumoBaseObject() &&
     162            0 :                         (obj->getParentSumoBaseObject()->getTag() != SUMO_TAG_VTYPE_DISTRIBUTION)) {
     163              :                     // parse vType and all their childrens
     164            0 :                     parseSumoBaseObject(obj);
     165              :                     // delete object (and all of their childrens)
     166            0 :                     delete obj;
     167              :                 }
     168              :                 break;
     169            0 :             case SUMO_TAG_VTYPE_DISTRIBUTION:
     170              :             case SUMO_TAG_ROUTE_DISTRIBUTION:
     171              :             case SUMO_TAG_TRIP:
     172              :             case SUMO_TAG_VEHICLE:
     173              :             case SUMO_TAG_FLOW:
     174              :             case SUMO_TAG_PERSON:
     175              :             case SUMO_TAG_PERSONFLOW:
     176              :             case SUMO_TAG_CONTAINER:
     177              :             case SUMO_TAG_CONTAINERFLOW:
     178              :                 // parse object and all their childrens
     179            0 :                 parseSumoBaseObject(obj);
     180              :                 // delete object (and all of their childrens)
     181            0 :                 delete obj;
     182              :                 break;
     183              :             default:
     184              :                 break;
     185              :         }
     186              :     }
     187            0 : }
     188              : 
     189              : 
     190              : void
     191            0 : RouteHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
     192              :     // switch tag
     193            0 :     switch (obj->getTag()) {
     194              :         // vTypes
     195            0 :         case SUMO_TAG_VTYPE:
     196            0 :             buildVType(obj,
     197              :                        obj->getVehicleTypeParameter());
     198            0 :             break;
     199            0 :         case SUMO_TAG_VTYPE_DISTRIBUTION:
     200            0 :             buildVTypeDistribution(obj,
     201              :                                    obj->getStringAttribute(SUMO_ATTR_ID),
     202              :                                    obj->getIntAttribute(SUMO_ATTR_DETERMINISTIC),
     203              :                                    obj->getStringListAttribute(SUMO_ATTR_VTYPES),
     204              :                                    obj->getDoubleListAttribute(SUMO_ATTR_PROBS));
     205            0 :             break;
     206              :         // route
     207            0 :         case SUMO_TAG_ROUTE:
     208            0 :             if (obj->getStringAttribute(SUMO_ATTR_ID).empty()) {
     209            0 :                 buildEmbeddedRoute(obj,
     210              :                                    obj->getStringListAttribute(SUMO_ATTR_EDGES),
     211              :                                    obj->getColorAttribute(SUMO_ATTR_COLOR),
     212              :                                    obj->getIntAttribute(SUMO_ATTR_REPEAT),
     213              :                                    obj->getTimeAttribute(SUMO_ATTR_CYCLETIME),
     214            0 :                                    obj->getParameters());
     215              :             } else {
     216            0 :                 buildRoute(obj,
     217              :                            obj->getStringAttribute(SUMO_ATTR_ID),
     218              :                            obj->getVClass(),
     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              :                            obj->getDoubleAttribute(SUMO_ATTR_PROB),
     224            0 :                            obj->getParameters());
     225              :             }
     226              :             break;
     227            0 :         case SUMO_TAG_ROUTE_DISTRIBUTION:
     228            0 :             buildRouteDistribution(obj,
     229              :                                    obj->getStringAttribute(SUMO_ATTR_ID),
     230              :                                    obj->getStringListAttribute(SUMO_ATTR_ROUTES),
     231              :                                    obj->getDoubleListAttribute(SUMO_ATTR_PROBS));
     232            0 :             break;
     233              :         // vehicles
     234            0 :         case SUMO_TAG_TRIP:
     235            0 :             if (obj->hasStringAttribute(SUMO_ATTR_FROM) &&
     236            0 :                     obj->hasStringAttribute(SUMO_ATTR_TO)) {
     237              :                 // build trip with from-to edges
     238            0 :                 buildTrip(obj,
     239              :                           obj->getVehicleParameter(),
     240              :                           obj->getStringAttribute(SUMO_ATTR_FROM),
     241              :                           obj->getStringAttribute(SUMO_ATTR_TO));
     242            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) &&
     243            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION)) {
     244              :                 // build trip with from-to junctions
     245            0 :                 buildTripJunctions(obj,
     246              :                                    obj->getVehicleParameter(),
     247              :                                    obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
     248              :                                    obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION));
     249            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_TAZ) &&
     250            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_TAZ)) {
     251              :                 // build trip with from-to TAZs
     252            0 :                 buildTripTAZs(obj,
     253              :                               obj->getVehicleParameter(),
     254              :                               obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
     255              :                               obj->getStringAttribute(SUMO_ATTR_TO_TAZ));
     256              :             } else {
     257            0 :                 throw ProcessError("Invalid from-to values in trips");
     258              :             }
     259              :             break;
     260            0 :         case SUMO_TAG_VEHICLE:
     261            0 :             if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
     262            0 :                 buildVehicleOverRoute(obj,
     263              :                                       obj->getVehicleParameter());
     264              :             }
     265              :             break;
     266              :         // flows
     267            0 :         case SUMO_TAG_FLOW:
     268            0 :             if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
     269              :                 // build flow over route
     270            0 :                 buildFlowOverRoute(obj,
     271              :                                    obj->getVehicleParameter());
     272            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM) &&
     273            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO)) {
     274              :                 // build flow with from-to edges
     275            0 :                 buildFlow(obj,
     276              :                           obj->getVehicleParameter(),
     277              :                           obj->getStringAttribute(SUMO_ATTR_FROM),
     278              :                           obj->getStringAttribute(SUMO_ATTR_TO));
     279            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) &&
     280            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION)) {
     281              :                 // build flow with from-to junctions
     282            0 :                 buildFlowJunctions(obj,
     283              :                                    obj->getVehicleParameter(),
     284              :                                    obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
     285              :                                    obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION));
     286            0 :             } else if (obj->hasStringAttribute(SUMO_ATTR_FROM_TAZ) &&
     287            0 :                        obj->hasStringAttribute(SUMO_ATTR_TO_TAZ)) {
     288              :                 // build flow with from-to TAZs
     289            0 :                 buildFlowTAZs(obj,
     290              :                               obj->getVehicleParameter(),
     291              :                               obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
     292              :                               obj->getStringAttribute(SUMO_ATTR_TO_TAZ));
     293              :             }
     294              :             break;
     295              :         // persons
     296            0 :         case SUMO_TAG_PERSON:
     297            0 :             buildPerson(obj,
     298              :                         obj->getVehicleParameter());
     299            0 :             break;
     300            0 :         case SUMO_TAG_PERSONFLOW:
     301            0 :             buildPersonFlow(obj,
     302              :                             obj->getVehicleParameter());
     303            0 :             break;
     304              :         // person plans
     305            0 :         case SUMO_TAG_PERSONTRIP:
     306            0 :             buildPersonTrip(obj,
     307              :                             obj->getPlanParameters(),
     308              :                             obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     309              :                             obj->getStringListAttribute(SUMO_ATTR_VTYPES),
     310              :                             obj->getStringListAttribute(SUMO_ATTR_MODES),
     311              :                             obj->getStringListAttribute(SUMO_ATTR_LINES),
     312              :                             obj->getDoubleAttribute(SUMO_ATTR_WALKFACTOR),
     313              :                             obj->getStringAttribute(SUMO_ATTR_GROUP));
     314            0 :             break;
     315            0 :         case SUMO_TAG_RIDE:
     316            0 :             buildRide(obj,
     317              :                       obj->getPlanParameters(),
     318              :                       obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     319              :                       obj->getStringListAttribute(SUMO_ATTR_LINES),
     320              :                       obj->getStringAttribute(SUMO_ATTR_GROUP));
     321            0 :             break;
     322            0 :         case SUMO_TAG_WALK:
     323            0 :             buildWalk(obj,
     324              :                       obj->getPlanParameters(),
     325              :                       obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     326              :                       obj->getDoubleAttribute(SUMO_ATTR_SPEED),
     327              :                       obj->getTimeAttribute(SUMO_ATTR_DURATION));
     328            0 :             break;
     329              :         // container
     330            0 :         case SUMO_TAG_CONTAINER:
     331            0 :             buildContainer(obj,
     332              :                            obj->getVehicleParameter());
     333            0 :             break;
     334            0 :         case SUMO_TAG_CONTAINERFLOW:
     335            0 :             buildContainerFlow(obj,
     336              :                                obj->getVehicleParameter());
     337            0 :             break;
     338              :         // container plans
     339            0 :         case SUMO_TAG_TRANSPORT:
     340            0 :             buildTransport(obj,
     341              :                            obj->getPlanParameters(),
     342              :                            obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     343              :                            obj->getStringListAttribute(SUMO_ATTR_LINES),
     344              :                            obj->getStringAttribute(SUMO_ATTR_GROUP));
     345            0 :             break;
     346            0 :         case SUMO_TAG_TRANSHIP:
     347            0 :             buildTranship(obj,
     348              :                           obj->getPlanParameters(),
     349              :                           obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
     350              :                           obj->getDoubleAttribute(SUMO_ATTR_DEPARTPOS),
     351              :                           obj->getDoubleAttribute(SUMO_ATTR_SPEED),
     352              :                           obj->getTimeAttribute(SUMO_ATTR_DURATION));
     353            0 :             break;
     354              :         // stopss
     355            0 :         case SUMO_TAG_STOP:
     356            0 :             buildStop(obj,
     357              :                       obj->getPlanParameters(),
     358              :                       obj->getStopParameter());
     359            0 :             break;
     360              :         default:
     361              :             break;
     362              :     }
     363              :     // now iterate over childrens
     364            0 :     for (const auto& child : obj->getSumoBaseObjectChildren()) {
     365              :         // call this function recursively
     366            0 :         parseSumoBaseObject(child);
     367              :     }
     368            0 : }
     369              : 
     370              : 
     371              : bool
     372            0 : RouteHandler::isErrorCreatingElement() const {
     373            0 :     return myErrorCreatingElement;
     374              : }
     375              : 
     376              : 
     377              : void
     378            0 : RouteHandler::writeError(const std::string& error) {
     379            0 :     WRITE_ERROR(error);
     380            0 :     myErrorCreatingElement = true;
     381            0 : }
     382              : 
     383              : 
     384              : void
     385            0 : RouteHandler::writeErrorInvalidID(const SumoXMLTag tag, const std::string& id) {
     386            0 :     WRITE_ERRORF(TL("Could not build % with ID '%' in netedit; ID contains invalid characters."), toString(tag), id);
     387            0 :     myErrorCreatingElement = true;
     388            0 : }
     389              : 
     390              : 
     391              : void
     392            0 : RouteHandler::writeErrorInvalidDistribution(const SumoXMLTag tag, const std::string& id) {
     393            0 :     WRITE_ERRORF(TL("Could not build % with ID '%' in netedit; Distinct number of distribution values and probabilities."), toString(tag), id);
     394            0 :     myErrorCreatingElement = true;
     395            0 : }
     396              : 
     397              : 
     398              : void
     399            0 : RouteHandler::parseVType(const SUMOSAXAttributes& attrs) {
     400              :     // parse vehicleType
     401            0 :     SUMOVTypeParameter* vehicleTypeParameter = SUMOVehicleParserHelper::beginVTypeParsing(attrs, myHardFail, myFilename);
     402            0 :     if (vehicleTypeParameter) {
     403              :         // set tag
     404            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE);
     405              :         // add all attributes
     406            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleTypeParameter(vehicleTypeParameter);
     407              :         // delete vehicleType parameter (because in XMLStructure we have a copy)
     408            0 :         delete vehicleTypeParameter;
     409              :     }
     410            0 : }
     411              : 
     412              : 
     413              : void
     414            0 : RouteHandler::parseVTypeDistribution(const SUMOSAXAttributes& attrs) {
     415              :     // declare Ok Flag
     416            0 :     bool parsedOk = true;
     417              :     // needed attributes
     418            0 :     const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
     419              :     // optional attributes
     420            0 :     const int deterministic = attrs.getOpt<int>(SUMO_ATTR_DETERMINISTIC, id.c_str(), parsedOk, -1);
     421            0 :     const std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, id.c_str(), parsedOk);
     422            0 :     const std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
     423            0 :     if (parsedOk) {
     424            0 :         if (!SUMOXMLDefinitions::isValidVehicleID(id)) {
     425            0 :             writeErrorInvalidID(SUMO_TAG_VTYPE_DISTRIBUTION, id);
     426            0 :         } else if (vTypes.size() != probabilities.size()) {
     427            0 :             writeErrorInvalidDistribution(SUMO_TAG_VTYPE_DISTRIBUTION, id);
     428              :         } else {
     429              :             // set tag
     430            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE_DISTRIBUTION);
     431              :             // add all attributes
     432            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     433            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_DETERMINISTIC, deterministic);
     434            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VTYPES, vTypes);
     435            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleListAttribute(SUMO_ATTR_PROBS, probabilities);
     436              :         }
     437              :     }
     438            0 : }
     439              : 
     440              : 
     441              : void
     442            0 : RouteHandler::parseRoute(const SUMOSAXAttributes& attrs) {
     443              :     // get embedded route flag
     444            0 :     const bool embeddedRoute = isEmbeddedRoute(attrs);
     445              :     // first check if this is an embedded route
     446            0 :     if ((embeddedRoute && attrs.hasAttribute(SUMO_ATTR_ID)) || (!embeddedRoute && !attrs.hasAttribute(SUMO_ATTR_ID))) {
     447            0 :         writeError(TL("a route must be defined either within a vehicle/flow or with an ID attribute"));
     448              :     } else {
     449              :         // declare Ok Flag
     450            0 :         bool parsedOk = true;
     451              :         // special case for ID
     452            0 :         const std::string id = attrs.getOpt<std::string>(SUMO_ATTR_ID, "", parsedOk, "");
     453              :         // needed attributes
     454            0 :         const std::vector<std::string> edges = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), parsedOk);
     455              :         // optional attributes
     456            0 :         SUMOVehicleClass vClass = SUMOVehicleParserHelper::parseVehicleClass(attrs, id);
     457            0 :         const RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), parsedOk, RGBColor::INVISIBLE);
     458            0 :         const int repeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, id.c_str(), parsedOk, 0);
     459            0 :         const SUMOTime cycleTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CYCLETIME, id.c_str(), parsedOk, 0);
     460            0 :         const double probability = attrs.getOpt<double>(SUMO_ATTR_PROB, id.c_str(), parsedOk, 0);
     461            0 :         if (parsedOk) {
     462            0 :             if (!id.empty() && !SUMOXMLDefinitions::isValidVehicleID(id)) {
     463            0 :                 writeErrorInvalidID(SUMO_TAG_ROUTE, id);
     464            0 :             } else if (cycleTime < 0) {
     465            0 :                 writeError(TLF("cycleTime of % must be equal or greater than 0", toString(SUMO_TAG_DEST_PROB_REROUTE)));
     466              :             } else {
     467              :                 // set tag
     468            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
     469              :                 // add all attributes
     470            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     471            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVClass(vClass);
     472            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_EDGES, edges);
     473            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addColorAttribute(SUMO_ATTR_COLOR, color);
     474            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_REPEAT, repeat);
     475            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_CYCLETIME, cycleTime);
     476            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probability);
     477              :             }
     478              :         }
     479            0 :     }
     480            0 : }
     481              : 
     482              : 
     483              : void
     484            0 : RouteHandler::parseRouteDistribution(const SUMOSAXAttributes& attrs) {
     485              :     // declare Ok Flag
     486            0 :     bool parsedOk = true;
     487              :     // needed attributes
     488            0 :     const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
     489              :     // optional attributes
     490            0 :     const std::vector<std::string> routes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_ROUTES, id.c_str(), parsedOk);
     491            0 :     const std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
     492            0 :     if (parsedOk) {
     493            0 :         if (!SUMOXMLDefinitions::isValidVehicleID(id)) {
     494            0 :             writeErrorInvalidID(SUMO_TAG_ROUTE_DISTRIBUTION, id);
     495            0 :         } else if (routes.size() != probabilities.size()) {
     496            0 :             writeErrorInvalidDistribution(SUMO_TAG_ROUTE_DISTRIBUTION, id);
     497              :         } else {
     498              :             // set tag
     499            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE_DISTRIBUTION);
     500              :             // add all attributes
     501            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
     502            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_ROUTES, routes);
     503            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleListAttribute(SUMO_ATTR_PROBS, probabilities);
     504              :         }
     505              :     }
     506            0 : }
     507              : 
     508              : 
     509              : void
     510            0 : RouteHandler::parseTrip(const SUMOSAXAttributes& attrs) {
     511              :     // declare Ok Flag
     512            0 :     bool parsedOk = true;
     513              :     // parse vehicle
     514            0 :     SUMOVehicleParameter* tripParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_TRIP, attrs, myHardFail);
     515            0 :     if (tripParameter) {
     516              :         // check from/to edge/junction
     517            0 :         if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
     518            0 :             writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
     519            0 :         } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
     520            0 :             writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
     521            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
     522              :             // from-to attributes
     523            0 :             const std::string from = attrs.getOpt<std::string>(SUMO_ATTR_FROM, tripParameter->id.c_str(), parsedOk, "");
     524            0 :             const std::string to = attrs.getOpt<std::string>(SUMO_ATTR_TO, tripParameter->id.c_str(), parsedOk, "");
     525              :             // optional attributes
     526            0 :             const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, tripParameter->id.c_str(), parsedOk);
     527            0 :             if (parsedOk) {
     528              :                 // set tag
     529            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
     530              :                 // set vehicle parameters
     531            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
     532              :                 // add other attributes
     533            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
     534            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
     535            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
     536              :             }
     537            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
     538              :             // from-to attributes
     539            0 :             const std::string fromJunction = attrs.getOpt<std::string>(SUMO_ATTR_FROM_JUNCTION, tripParameter->id.c_str(), parsedOk, "");
     540            0 :             const std::string toJunction = attrs.getOpt<std::string>(SUMO_ATTR_TO_JUNCTION, tripParameter->id.c_str(), parsedOk, "");
     541            0 :             if (parsedOk) {
     542              :                 // set tag
     543            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
     544              :                 // set vehicle parameters
     545            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
     546              :                 // add other attributes
     547            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
     548            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
     549              :             }
     550            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
     551              :             // from-to attributes
     552            0 :             const std::string fromJunction = attrs.getOpt<std::string>(SUMO_ATTR_FROM_TAZ, tripParameter->id.c_str(), parsedOk, "");
     553            0 :             const std::string toJunction = attrs.getOpt<std::string>(SUMO_ATTR_TO_TAZ, 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_TAZ, fromJunction);
     561            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
     562              :             }
     563              :         } else {
     564            0 :             writeError(TL("trip definition needs either 'from/to' or 'fromJunction/toJunction' or 'fromTaz/toTaz'"));
     565              :         }
     566              :         // delete trip parameter (because in XMLStructure we have a copy)
     567            0 :         delete tripParameter;
     568              :     }
     569            0 : }
     570              : 
     571              : 
     572              : void
     573            0 : RouteHandler::parseVehicle(const SUMOSAXAttributes& attrs) {
     574              :     // first parse vehicle
     575            0 :     SUMOVehicleParameter* vehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_VEHICLE, attrs, myHardFail);
     576            0 :     if (vehicleParameter) {
     577              :         // set tag
     578            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VEHICLE);
     579              :         // set vehicle parameters
     580            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(vehicleParameter);
     581              :         // delete vehicle parameter (because in XMLStructure we have a copy)
     582            0 :         delete vehicleParameter;
     583              :     }
     584            0 : }
     585              : 
     586              : 
     587              : void
     588            0 : RouteHandler::parseFlow(const SUMOSAXAttributes& attrs) {
     589              :     // declare Ok Flag
     590            0 :     bool parsedOk = true;
     591              :     // first parse flow
     592            0 :     SUMOVehicleParameter* flowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     593            0 :     if (flowParameter) {
     594              :         // set vehicle parameters
     595            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(flowParameter);
     596              :         // check from/to edge/junction
     597            0 :         if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
     598            0 :             writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
     599            0 :         } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
     600            0 :             writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
     601            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
     602              :             // from-to attributes
     603            0 :             const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, flowParameter->id.c_str(), parsedOk);
     604            0 :             const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, flowParameter->id.c_str(), parsedOk);
     605              :             // optional attributes
     606            0 :             const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, flowParameter->id.c_str(), parsedOk);
     607            0 :             if (parsedOk) {
     608              :                 // set tag
     609            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     610              :                 // add other attributes
     611            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
     612            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
     613            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
     614              :             }
     615            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
     616              :             // from-to attributes
     617            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_JUNCTION, flowParameter->id.c_str(), parsedOk);
     618            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_JUNCTION, flowParameter->id.c_str(), parsedOk);
     619            0 :             if (parsedOk) {
     620              :                 // set tag
     621            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     622              :                 // add other attributes
     623            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
     624            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
     625              :             }
     626            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
     627              :             // from-to attributes
     628            0 :             const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, flowParameter->id.c_str(), parsedOk);
     629            0 :             const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, flowParameter->id.c_str(), parsedOk);
     630            0 :             if (parsedOk) {
     631              :                 // set tag
     632            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     633              :                 // add other attributes
     634            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_TAZ, fromJunction);
     635            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
     636              :             }
     637            0 :         } else if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
     638              :             // from-to attributes
     639            0 :             const std::string route = attrs.get<std::string>(SUMO_ATTR_ROUTE, flowParameter->id.c_str(), parsedOk);
     640            0 :             if (parsedOk) {
     641              :                 // set tag
     642            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     643              :                 // add other attributes
     644            0 :                 myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ROUTE, route);
     645              :             }
     646              :         } else {
     647              :             // set tag
     648            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
     649              :         }
     650              :         // delete flow parameter (because in XMLStructure we have a copy)
     651            0 :         delete flowParameter;
     652              :     }
     653            0 : }
     654              : 
     655              : 
     656              : void
     657            0 : RouteHandler::parseStop(const SUMOSAXAttributes& attrs) {
     658              :     // declare Ok Flag
     659            0 :     bool parsedOk = true;
     660              :     // declare stop
     661            0 :     SUMOVehicleParameter::Stop stop;
     662              :     // plan parameters
     663            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     664              :     // get parents
     665              :     std::vector<SumoXMLTag> stopParents;
     666            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::vehicles.begin(), NamespaceIDs::vehicles.end());
     667            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::routes.begin(), NamespaceIDs::routes.end());
     668            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::persons.begin(), NamespaceIDs::persons.end());
     669            0 :     stopParents.insert(stopParents.end(), NamespaceIDs::containers.begin(), NamespaceIDs::containers.end());
     670              :     //  check parents
     671            0 :     checkParent(SUMO_TAG_STOP, stopParents, parsedOk);
     672              :     // parse stop
     673            0 :     if (parsedOk && parseStopParameters(stop, attrs)) {
     674              :         // set tag
     675            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_STOP);
     676              :         // add stop attributes
     677            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     678            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setStopParameter(stop);
     679              :     }
     680            0 : }
     681              : 
     682              : 
     683              : void
     684            0 : RouteHandler::parsePerson(const SUMOSAXAttributes& attrs) {
     685              :     // first parse vehicle
     686            0 :     SUMOVehicleParameter* personParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_PERSON, attrs, myHardFail);
     687            0 :     if (personParameter) {
     688              :         // set tag
     689            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSON);
     690              :         // set vehicle parameter
     691            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personParameter);
     692              :         // delete person parameter (because in XMLStructure we have a copy)
     693            0 :         delete personParameter;
     694              :     }
     695            0 : }
     696              : 
     697              : 
     698              : void
     699            0 : RouteHandler::parsePersonFlow(const SUMOSAXAttributes& attrs) {
     700              :     // first parse flow
     701            0 :     SUMOVehicleParameter* personFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_PERSONFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     702            0 :     if (personFlowParameter) {
     703              :         // set tag
     704            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONFLOW);
     705              :         // set vehicle parameter
     706            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personFlowParameter);
     707              :         // delete person flow parameter (because in XMLStructure we have a copy)
     708            0 :         delete personFlowParameter;
     709              :     }
     710            0 : }
     711              : 
     712              : 
     713              : void
     714            0 : RouteHandler::parsePersonTrip(const SUMOSAXAttributes& attrs) {
     715              :     // declare Ok Flag
     716            0 :     bool parsedOk = true;
     717              :     // plan parameters
     718            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     719              :     // optional attributes
     720            0 :     const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, "", parsedOk);
     721            0 :     const std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, "", parsedOk);
     722            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     723            0 :     std::vector<std::string> modes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_MODES, "", parsedOk);
     724            0 :     const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     725            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     726            0 :     const double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, "", parsedOk, 0);
     727            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     728              :     // check modes
     729              :     SVCPermissions dummyModeSet;
     730              :     std::string dummyError;
     731            0 :     if (!SUMOVehicleParameter::parsePersonModes(toString(modes), toString(SUMO_TAG_PERSONTRIP), "", dummyModeSet, dummyError)) {
     732            0 :         WRITE_WARNING(dummyError);
     733              :         modes.clear();
     734              :     }
     735            0 :     if (parsedOk) {
     736              :         // set tag
     737            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONTRIP);
     738              :         // add all attributes
     739            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     740            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VTYPES, vTypes);
     741            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_MODES, modes);
     742            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     743            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     744            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     745            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_WALKFACTOR, walkFactor);
     746            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     747              :     }
     748            0 : }
     749              : 
     750              : 
     751              : void
     752            0 : RouteHandler::parseWalk(const SUMOSAXAttributes& attrs) {
     753            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
     754            0 :         WRITE_ERROR(TL("Speed and duration attributes cannot be defined together in walks"));
     755              :     } else {
     756              :         // declare Ok Flag
     757            0 :         bool parsedOk = true;
     758              :         // plan parameters
     759            0 :         const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     760              :         // optional attributes
     761            0 :         const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     762            0 :         const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     763            0 :         const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
     764            0 :         const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
     765            0 :         if (parsedOk) {
     766              :             // set tag
     767            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_WALK);
     768              :             // add all attributes
     769            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     770            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     771            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     772            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
     773            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
     774              :         }
     775            0 :     }
     776            0 : }
     777              : 
     778              : 
     779              : void
     780            0 : RouteHandler::parseRide(const SUMOSAXAttributes& attrs) {
     781              :     // declare Ok Flag
     782            0 :     bool parsedOk = true;
     783              :     // plan parameters
     784            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     785              :     // optional attributes
     786            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     787            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     788            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     789            0 :     if (parsedOk) {
     790              :         // set tag
     791            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_RIDE);
     792              :         // add all attributes
     793            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     794            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     795            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     796            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     797              :     }
     798            0 : }
     799              : 
     800              : 
     801              : void
     802            0 : RouteHandler::parseContainer(const SUMOSAXAttributes& attrs) {
     803              :     // first parse container
     804            0 :     SUMOVehicleParameter* containerParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_CONTAINER, attrs, myHardFail);
     805            0 :     if (containerParameter) {
     806              :         // set tag
     807            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINER);
     808              :         // set vehicle parameter
     809            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerParameter);
     810              :         // delete container parameter (because in XMLStructure we have a copy)
     811            0 :         delete containerParameter;
     812              :     }
     813            0 : }
     814              : 
     815              : 
     816              : void
     817            0 : RouteHandler::parseContainerFlow(const SUMOSAXAttributes& attrs) {
     818              :     // first parse flow
     819            0 :     SUMOVehicleParameter* containerFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_CONTAINERFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
     820            0 :     if (containerFlowParameter) {
     821              :         // set tag
     822            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINERFLOW);
     823              :         // set vehicle parameter
     824            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerFlowParameter);
     825              :         // delete container flow parameter (because in XMLStructure we have a copy)
     826            0 :         delete containerFlowParameter;
     827              :     }
     828            0 : }
     829              : 
     830              : 
     831              : void
     832            0 : RouteHandler::parseTransport(const SUMOSAXAttributes& attrs) {
     833              :     // declare Ok Flag
     834            0 :     bool parsedOk = true;
     835              :     // plan parameters
     836            0 :     const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     837              :     // optional attributes
     838            0 :     const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
     839            0 :     const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     840            0 :     const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
     841            0 :     if (parsedOk) {
     842              :         // set tag
     843            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSPORT);
     844              :         // add all attributes
     845            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     846            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
     847            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     848            0 :         myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
     849              :     }
     850            0 : }
     851              : 
     852              : 
     853              : void
     854            0 : RouteHandler::parseTranship(const SUMOSAXAttributes& attrs) {
     855            0 :     if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
     856            0 :         WRITE_ERROR(TL("Speed and duration attributes cannot be defined together in walks"));
     857              :     } else {
     858              :         // declare Ok Flag
     859            0 :         bool parsedOk = true;
     860              :         // plan parameters
     861            0 :         const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
     862              :         // optional attributes
     863            0 :         const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
     864            0 :         const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
     865            0 :         const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
     866            0 :         const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
     867            0 :         if (parsedOk) {
     868              :             // set tag
     869            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSHIP);
     870              :             // add all attributes
     871            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
     872            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
     873            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
     874            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
     875            0 :             myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
     876              :         }
     877            0 :     }
     878            0 : }
     879              : 
     880              : 
     881              : void
     882            0 : RouteHandler::parseInterval(const SUMOSAXAttributes& attrs) {
     883              :     // declare Ok Flag
     884            0 :     bool parsedOk = true;
     885              :     // just parse begin and end default
     886            0 :     myFlowBeginDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, parsedOk);
     887            0 :     myFlowEndDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, parsedOk);
     888            0 : }
     889              : 
     890              : 
     891              : void
     892            0 : RouteHandler::parseParameters(const SUMOSAXAttributes& attrs) {
     893              :     // declare Ok Flag
     894            0 :     bool parsedOk = true;
     895              :     // get key
     896            0 :     const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, parsedOk);
     897              :     // get SumoBaseObject parent
     898            0 :     CommonXMLStructure::SumoBaseObject* SumoBaseObjectParent = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
     899              :     // check parent
     900            0 :     if (SumoBaseObjectParent == nullptr) {
     901            0 :         writeError(TL("Parameters must be defined within an object"));
     902            0 :     } else if (SumoBaseObjectParent->getTag() == SUMO_TAG_ROOTFILE) {
     903            0 :         writeError(TL("Parameters cannot be defined in the additional file's root."));
     904            0 :     } else if (SumoBaseObjectParent->getTag() == SUMO_TAG_PARAM) {
     905            0 :         writeError(TL("Parameters cannot be defined within another parameter."));
     906            0 :     } else if (parsedOk) {
     907              :         // get tag str
     908            0 :         const std::string parentTagStr = toString(SumoBaseObjectParent->getTag());
     909              :         // circumventing empty string value
     910            0 :         const std::string value = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
     911              :         // show warnings if values are invalid
     912            0 :         if (key.empty()) {
     913            0 :             WRITE_WARNINGF(TL("Error parsing key from % generic parameter. Key cannot be empty"), parentTagStr);
     914            0 :         } else if (!SUMOXMLDefinitions::isValidParameterKey(key)) {
     915            0 :             WRITE_WARNINGF(TL("Error parsing key from % generic parameter. Key contains invalid characters"), parentTagStr);
     916              :         } else {
     917            0 :             WRITE_DEBUG("Inserting generic parameter '" + key + "|" + value + "' into " + parentTagStr);
     918              :             // insert parameter in SumoBaseObjectParent
     919            0 :             SumoBaseObjectParent->addParameter(key, value);
     920              :         }
     921              :     }
     922            0 : }
     923              : 
     924              : 
     925              : bool
     926            0 : RouteHandler::parseNestedCFM(const SumoXMLTag tag, const SUMOSAXAttributes& attrs) {
     927              :     // get vehicle type Base object
     928            0 :     const auto vTypeObject = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
     929              :     // parse embedded car following model information
     930            0 :     if (vTypeObject && (vTypeObject->getTag() == SUMO_TAG_VTYPE)) {
     931            0 :         WRITE_WARNINGF(TL("Defining car-following parameters in a nested element is deprecated in vType '%', use attributes instead!"), vTypeObject->getStringAttribute(SUMO_ATTR_ID));
     932              :         // get vType to modify it
     933            0 :         auto vType = vTypeObject->getVehicleTypeParameter();
     934              :         // parse nested CFM attributes
     935            0 :         if (SUMOVehicleParserHelper::parseCFMParams(&vType, tag, attrs, true)) {
     936            0 :             vTypeObject->setVehicleTypeParameter(&vType);
     937              :             return true;
     938            0 :         } else if (myHardFail) {
     939            0 :             throw ProcessError(TL("Invalid parsing embedded VType"));
     940              :         } else {
     941            0 :             writeError(TL("Invalid parsing embedded VType"));
     942              :         }
     943            0 :     }
     944              :     return false;
     945              : }
     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