LCOV - code coverage report
Current view: top level - src/router - RONetHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.8 % 307 294
Test Date: 2026-03-02 16:00:03 Functions: 93.3 % 15 14

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-2026 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    RONetHandler.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Christian Roessel
      18              : /// @author  Michael Behrisch
      19              : /// @author  Yun-Pang Floetteroed
      20              : /// @date    Sept 2002
      21              : ///
      22              : // The handler for SUMO-Networks
      23              : /****************************************************************************/
      24              : #include <config.h>
      25              : 
      26              : #include <string>
      27              : #include <utils/common/MsgHandler.h>
      28              : #include <utils/common/StringTokenizer.h>
      29              : #include <utils/common/UtilExceptions.h>
      30              : #include <utils/common/ToString.h>
      31              : #include <utils/common/StringUtils.h>
      32              : #include <utils/geom/PositionVector.h>
      33              : #include <utils/geom/GeoConvHelper.h>
      34              : #include <utils/vehicle/SUMORouteHandler.h>
      35              : #include <utils/xml/SUMOSAXHandler.h>
      36              : #include <utils/xml/SUMOXMLDefinitions.h>
      37              : #include "ROEdge.h"
      38              : #include "ROLane.h"
      39              : #include "RONode.h"
      40              : #include "RONet.h"
      41              : #include "RONetHandler.h"
      42              : #include "ROAbstractEdgeBuilder.h"
      43              : 
      44              : 
      45              : // ===========================================================================
      46              : // method definitions
      47              : // ===========================================================================
      48         4297 : RONetHandler::RONetHandler(RONet& net, ROAbstractEdgeBuilder& eb, const bool ignoreInternal, const double minorPenalty, double tlsPenalty, double turnaroundPenalty) :
      49              :     SUMOSAXHandler("sumo-network"),
      50         4297 :     myNet(net),
      51              :     myNetworkVersion(0, 0),
      52         4297 :     myEdgeBuilder(eb), myIgnoreInternal(ignoreInternal),
      53         4297 :     myCurrentName(), myCurrentEdge(nullptr), myCurrentStoppingPlace(nullptr),
      54         4297 :     myMinorPenalty(minorPenalty),
      55         4297 :     myTLSPenalty(tlsPenalty),
      56         8594 :     myTurnaroundPenalty(turnaroundPenalty)
      57         4297 : {}
      58              : 
      59              : 
      60         8594 : RONetHandler::~RONetHandler() {}
      61              : 
      62              : 
      63              : void
      64      1611380 : RONetHandler::myStartElement(int element,
      65              :                              const SUMOSAXAttributes& attrs) {
      66      1611380 :     switch (element) {
      67         4297 :         case SUMO_TAG_LOCATION:
      68         4297 :             setLocation(attrs);
      69         4297 :             break;
      70         4297 :         case SUMO_TAG_NET: {
      71              :             bool ok;
      72         8594 :             myNetworkVersion = StringUtils::toVersion(attrs.get<std::string>(SUMO_ATTR_VERSION, nullptr, ok, false));
      73              :             break;
      74              :         }
      75       325674 :         case SUMO_TAG_EDGE:
      76              :             // in the first step, we do need the name to allocate the edge
      77              :             // in the second, we need it to know to which edge we have to add
      78              :             //  the following edges to
      79       325674 :             parseEdge(attrs);
      80       325662 :             break;
      81       368586 :         case SUMO_TAG_LANE:
      82       368586 :             parseLane(attrs);
      83       368586 :             break;
      84       100330 :         case SUMO_TAG_JUNCTION:
      85       100330 :             parseJunction(attrs);
      86       100330 :             break;
      87       479182 :         case SUMO_TAG_CONNECTION:
      88       479182 :             parseConnection(attrs);
      89       478864 :             break;
      90         1968 :         case SUMO_TAG_BUS_STOP:
      91              :         case SUMO_TAG_TRAIN_STOP:
      92              :         case SUMO_TAG_CONTAINER_STOP:
      93              :         case SUMO_TAG_PARKING_AREA:
      94              :         case SUMO_TAG_CHARGING_STATION:
      95              :         case SUMO_TAG_OVERHEAD_WIRE_SEGMENT:
      96         1968 :             parseStoppingPlace(attrs, (SumoXMLTag)element);
      97         1968 :             break;
      98         2076 :         case SUMO_TAG_ACCESS:
      99         2076 :             parseAccess(attrs);
     100         2076 :             break;
     101          383 :         case SUMO_TAG_TAZ:
     102          383 :             parseDistrict(attrs);
     103          383 :             break;
     104          126 :         case SUMO_TAG_TAZSOURCE:
     105          126 :             parseDistrictEdge(attrs, true);
     106          126 :             break;
     107          127 :         case SUMO_TAG_TAZSINK:
     108          127 :             parseDistrictEdge(attrs, false);
     109          127 :             break;
     110         2205 :         case SUMO_TAG_TYPE: {
     111         2205 :             bool ok = true;
     112         4410 :             myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     113              :             break;
     114              :         }
     115           17 :         case SUMO_TAG_RESTRICTION: {
     116           17 :             bool ok = true;
     117           34 :             const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
     118           17 :             const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
     119           17 :             if (ok) {
     120           17 :                 myNet.addSpeedRestriction(myCurrentTypeID, svc, speed);
     121              :             }
     122              :             break;
     123              :         }
     124           40 :         case SUMO_TAG_PREFERENCE: {
     125           40 :             bool ok = true;
     126           40 :             const std::string routingType = attrs.get<std::string>(SUMO_ATTR_ROUTINGTYPE, nullptr, ok);
     127           40 :             const double prio = attrs.get<double>(SUMO_ATTR_PRIORITY, routingType.c_str(), ok);
     128           40 :             if (prio <= 0) {
     129            0 :                 throw InvalidArgument("In preference for routingType '" + routingType + "', priority must be positve");
     130              :             }
     131           40 :             if (attrs.hasAttribute(SUMO_ATTR_VCLASSES)) {
     132            8 :                 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VCLASSES, routingType.c_str(), ok));
     133           32 :                 for (std::string className : st.getVector()) {
     134           24 :                     myNet.addPreference(routingType, getVehicleClassID(className), prio);
     135            8 :                 }
     136           40 :             } else if (!attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
     137              :                 // general preferenze applying to all types and vClasses
     138           48 :                 myNet.addPreference(routingType, "", prio);
     139              :             }
     140           40 :             if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
     141            8 :                 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VTYPES, routingType.c_str(), ok));
     142           16 :                 for (std::string typeName : st.getVector()) {
     143           24 :                     myNet.addPreference(routingType, typeName, prio);
     144            8 :                 }
     145            8 :             }
     146              :             break;
     147              :         }
     148            8 :         case SUMO_TAG_REROUTER: {
     149            8 :             bool ok = true;
     150           16 :             myRerouterID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     151              :             break;
     152              :         }
     153            8 :         case SUMO_TAG_INTERVAL:
     154            8 :             if (myRerouterID != "") {
     155            8 :                 bool ok = true;
     156            8 :                 myIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, myRerouterID.c_str(), ok, -1);
     157            8 :                 myIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, myRerouterID.c_str(), ok, SUMOTime_MAX);
     158            8 :                 if (myIntervalEnd <= myIntervalBegin) {
     159            0 :                     throw ProcessError(TLF("Invalid rerouter interval from % to %", time2string(myIntervalBegin), time2string(myIntervalEnd)));
     160              :                 }
     161              :             }
     162              :             break;
     163            4 :         case SUMO_TAG_CLOSING_REROUTE: {
     164            4 :             const std::string& closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
     165            4 :             ROEdge* closedEdge = myNet.getEdge(closed_id);
     166            4 :             if (closedEdge == nullptr) {
     167            0 :                 throw ProcessError(TLF("rerouter '%': Edge '%' to close is not known.", myRerouterID, closed_id));
     168              :             }
     169              :             bool ok;
     170            4 :             const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, myRerouterID.c_str(), ok, "", false);
     171            4 :             const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, myRerouterID.c_str(), ok, "");
     172            4 :             RouterProhibition prohibition;
     173            4 :             prohibition.permissions = parseVehicleClasses(allow, disallow);
     174            4 :             prohibition.begin = STEPS2TIME(myIntervalBegin);
     175            4 :             prohibition.end = STEPS2TIME(attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, myIntervalEnd));
     176            4 :             myNet.addProhibition(closedEdge, prohibition);
     177              :             break;
     178              :         }
     179            4 :         case SUMO_TAG_CLOSING_LANE_REROUTE: {
     180            4 :             const std::string& closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
     181            4 :             ROLane* closedLane = myNet.getLane(closed_id);
     182            4 :             if (closedLane == nullptr) {
     183            0 :                 throw ProcessError(TLF("rerouter '%': Lane '%' to close is not known.", myRerouterID, closed_id));
     184              :             }
     185              :             bool ok;
     186            4 :             const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, myRerouterID.c_str(), ok, "", false);
     187            4 :             const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, myRerouterID.c_str(), ok, "");
     188            4 :             RouterProhibition prohibition;
     189            4 :             prohibition.permissions = parseVehicleClasses(allow, disallow);
     190            4 :             prohibition.begin = STEPS2TIME(myIntervalBegin);
     191            4 :             prohibition.end = STEPS2TIME(attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, myIntervalEnd));
     192            4 :             myNet.addLaneProhibition(closedLane, prohibition);
     193              :             break;
     194              :         }
     195       104588 :         case SUMO_TAG_PARAM:
     196       104588 :             addParam(attrs);
     197       104588 :             break;
     198              :         default:
     199              :             break;
     200              :     }
     201      1611050 : }
     202              : 
     203              : 
     204              : void
     205      1610285 : RONetHandler::myEndElement(int element) {
     206      1610285 :     switch (element) {
     207            8 :         case SUMO_TAG_REROUTER:
     208            8 :             myRerouterID = "";
     209              :             break;
     210         3712 :         case SUMO_TAG_NET:
     211              :             // build junction graph
     212         3790 :             for (std::set<std::string>::const_iterator it = myUnseenNodeIDs.begin(); it != myUnseenNodeIDs.end(); ++it) {
     213          234 :                 WRITE_ERRORF(TL("Unknown node '%'."), *it);
     214              :             }
     215              :             break;
     216              :         default:
     217              :             break;
     218              :     }
     219      1610285 : }
     220              : 
     221              : 
     222              : void
     223       104588 : RONetHandler::addParam(const SUMOSAXAttributes& attrs) {
     224       104588 :     bool ok = true;
     225       104588 :     const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
     226              :     // circumventing empty string test
     227       104588 :     const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
     228              :     // add parameter in current created element, or in myLoadedParameterised
     229       104588 :     if (myCurrentEdge != nullptr) {
     230       104588 :         myCurrentEdge->setParameter(key, val);
     231              :     }
     232       104588 : }
     233              : 
     234              : 
     235              : void
     236       325674 : RONetHandler::parseEdge(const SUMOSAXAttributes& attrs) {
     237              :     // get the id, report an error if not given or empty...
     238       325674 :     bool ok = true;
     239       325674 :     myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     240       325674 :     if (!ok) {
     241           12 :         throw ProcessError();
     242              :     }
     243       325662 :     const SumoXMLEdgeFunc func = attrs.getOpt<SumoXMLEdgeFunc>(SUMO_ATTR_FUNCTION, myCurrentName.c_str(), ok, SumoXMLEdgeFunc::NORMAL);
     244       325662 :     if (!ok) {
     245           54 :         return;
     246              :     }
     247              :     // get the edge
     248              :     std::string from;
     249              :     std::string to;
     250              :     int priority;
     251       325656 :     myCurrentEdge = nullptr;
     252       325656 :     if (func == SumoXMLEdgeFunc::INTERNAL || func == SumoXMLEdgeFunc::CROSSING || func == SumoXMLEdgeFunc::WALKINGAREA) {
     253              :         assert(myCurrentName[0] == ':');
     254       418372 :         const std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(myCurrentName);
     255              :         from = junctionID;
     256              :         to = junctionID;
     257              :         priority = -1;
     258       209186 :     } else {
     259       232940 :         from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
     260       232940 :         to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
     261       116470 :         priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
     262       116470 :         if (!ok) {
     263              :             return;
     264              :         }
     265              :     }
     266       325608 :     RONode* fromNode = myNet.getNode(from);
     267       273899 :     if (fromNode == nullptr) {
     268              :         myUnseenNodeIDs.insert(from);
     269        51709 :         fromNode = new RONode(from);
     270        51709 :         myNet.addNode(fromNode);
     271              :     }
     272       325608 :     RONode* toNode = myNet.getNode(to);
     273       303633 :     if (toNode == nullptr) {
     274              :         myUnseenNodeIDs.insert(to);
     275        21975 :         toNode = new RONode(to);
     276        21975 :         myNet.addNode(toNode);
     277              :     }
     278       325608 :     const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, myCurrentName.c_str(), ok, "");
     279       325608 :     const std::string routingType = attrs.getOpt<std::string>(SUMO_ATTR_ROUTINGTYPE, myCurrentName.c_str(), ok, "");
     280              :     // build the edge
     281       325608 :     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority, type, routingType);
     282              :     myCurrentEdge->setFunction(func);
     283              : 
     284       325608 :     if (myNet.addEdge(myCurrentEdge)) {
     285       325596 :         fromNode->addOutgoing(myCurrentEdge);
     286       325596 :         toNode->addIncoming(myCurrentEdge);
     287       651192 :         const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, myCurrentName.c_str(), ok, "");
     288       325596 :         if (bidi != "") {
     289        12028 :             myBidiEdges[myCurrentEdge] = bidi;
     290              :         }
     291              :     } else {
     292           12 :         myCurrentEdge = nullptr;
     293              :     }
     294              : }
     295              : 
     296              : 
     297              : void
     298       368586 : RONetHandler::parseLane(const SUMOSAXAttributes& attrs) {
     299       368586 :     if (myCurrentEdge == nullptr) {
     300              :         // was an internal edge to skip or an error occurred
     301          282 :         return;
     302              :     }
     303       368460 :     bool ok = true;
     304              :     // get the id, report an error if not given or empty...
     305       368460 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     306       368460 :     if (!ok) {
     307              :         return;
     308              :     }
     309              :     // get the speed
     310       368436 :     double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
     311       368436 :     double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
     312       368436 :     std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
     313       736872 :     std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
     314       368436 :     const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
     315       368436 :     if (!ok) {
     316              :         return;
     317              :     }
     318       368328 :     if (shape.size() < 2) {
     319           72 :         WRITE_ERRORF(TL("Ignoring lane '%' with broken shape."), id);
     320           24 :         return;
     321              :     }
     322              :     // get the length
     323              :     // get the vehicle classes
     324       368304 :     SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
     325       368304 :     if (permissions != SVCAll) {
     326       253001 :         myNet.setPermissionsFound();
     327              :     }
     328              :     // add when both values are valid
     329       368304 :     if (maxSpeed > 0 && length > 0 && id.length() > 0) {
     330       368304 :         myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions, shape));
     331              :     } else {
     332            0 :         WRITE_WARNING("Ignoring lane '" + id + "' with speed " + toString(maxSpeed) + " and length " + toString(length));
     333              :     }
     334       368436 : }
     335              : 
     336              : 
     337              : void
     338       100330 : RONetHandler::parseJunction(const SUMOSAXAttributes& attrs) {
     339       100330 :     bool ok = true;
     340              :     // get the id, report an error if not given or empty...
     341       100330 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     342       100330 :     const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
     343       100330 :     if (type == SumoXMLNodeType::INTERNAL) {
     344              :         return;
     345              :     }
     346              :     myUnseenNodeIDs.erase(id);
     347              :     // get the position of the node
     348        73176 :     const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
     349        73176 :     const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
     350        73176 :     const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
     351        73176 :     if (!ok) {
     352              :         return;
     353              :     }
     354        73131 :     RONode* n = myNet.getNode(id);
     355        73027 :     if (n == nullptr) {
     356          312 :         WRITE_WARNINGF(TL("Skipping isolated junction '%'."), id);
     357              :     } else {
     358        73027 :         n->setPosition(Position(x, y, z));
     359              :     }
     360              : }
     361              : 
     362              : 
     363              : void
     364       479182 : RONetHandler::parseConnection(const SUMOSAXAttributes& attrs) {
     365       479182 :     bool ok = true;
     366       479182 :     std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
     367       479182 :     std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
     368       479182 :     const int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
     369       479182 :     const int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
     370       479182 :     std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok);
     371       479500 :     std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
     372       479500 :     std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
     373       479182 :     ROEdge* from = myNet.getEdge(fromID);
     374              :     ROEdge* to = myNet.getEdge(toID);
     375       479182 :     if (from == nullptr) {
     376          207 :         throw ProcessError(TLF("unknown from-edge '%' in connection", fromID));
     377              :     }
     378       479113 :     if (to == nullptr) {
     379          207 :         throw ProcessError(TLF("unknown to-edge '%' in connection", toID));
     380              :     }
     381       479044 :     if ((int)from->getLanes().size() <= fromLane) {
     382          270 :         throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
     383              :     }
     384       478954 :     if ((int)to->getLanes().size() <= toLane) {
     385          270 :         throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
     386              :     }
     387       478864 :     if (myIgnoreInternal || viaID == "") {
     388       315210 :         std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
     389       315210 :         std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
     390              :         ROEdge* dummyVia = nullptr;
     391              :         SVCPermissions permissions;
     392       315210 :         if (allow == "" && disallow == "") {
     393              :             permissions = SVC_UNSPECIFIED;
     394              :         } else {
     395           13 :             myNet.setPermissionsFound();
     396              :             // dummyVia is only needed to hold permissions
     397           13 :             permissions = parseVehicleClasses(allow, disallow);
     398           13 :             dummyVia = new ROEdge("dummyVia_" + from->getLanes()[fromLane]->getID() + "->" + to->getLanes()[toLane]->getID(),
     399           26 :                                   from->getToJunction(), from->getToJunction(), permissions);
     400           13 :             myNet.addEdge(dummyVia);
     401              :         }
     402       315210 :         from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], dummyVia);
     403       945630 :         from->addSuccessor(to, nullptr, dir);
     404              :     } else {
     405       163654 :         ROEdge* const via = myNet.getEdge(SUMOXMLDefinitions::getEdgeIDFromLane(viaID));
     406       163654 :         if (via == nullptr) {
     407            0 :             throw ProcessError(TLF("unknown via-edge '%' in connection", viaID));
     408              :         }
     409       163654 :         from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], via);
     410       327308 :         from->addSuccessor(to, via, dir);
     411       327308 :         via->addSuccessor(to, nullptr, dir);
     412       163654 :         LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
     413       163654 :         if (state == LINKSTATE_MINOR || state == LINKSTATE_EQUAL || state == LINKSTATE_STOP || state == LINKSTATE_ALLWAY_STOP) {
     414        94968 :             via->setTimePenalty(myMinorPenalty);
     415              :         }
     416       291048 :         if (dir == toString(LinkDirection::TURN) || dir == toString(LinkDirection::TURN_LEFTHAND)) {
     417        36582 :             via->setTimePenalty(myTurnaroundPenalty);
     418              :         }
     419       163654 :         if (tlID != "") {
     420        14332 :             via->setTimePenalty(myTLSPenalty);
     421              :         }
     422              :     }
     423       478864 :     if (to->isCrossing()) {
     424        12216 :         to->setTimePenalty(myTLSPenalty);
     425              :     }
     426       478864 : }
     427              : 
     428              : 
     429              : void
     430         1968 : RONetHandler::parseStoppingPlace(const SUMOSAXAttributes& attrs, const SumoXMLTag element) {
     431         1968 :     bool ok = true;
     432         1968 :     myCurrentStoppingPlace = new SUMOVehicleParameter::Stop();
     433              :     // get the id, throw if not given or empty...
     434         1968 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, toString(element).c_str(), ok);
     435              :     // get the lane
     436         1968 :     myCurrentStoppingPlace->lane = attrs.get<std::string>(SUMO_ATTR_LANE, toString(element).c_str(), ok);
     437         1968 :     if (!ok) {
     438            0 :         throw ProcessError();
     439              :     }
     440         1968 :     const ROEdge* edge = myNet.getEdgeForLaneID(myCurrentStoppingPlace->lane);
     441         1968 :     if (edge == nullptr) {
     442            0 :         throw InvalidArgument("Unknown lane '" + myCurrentStoppingPlace->lane + "' for " + toString(element) + " '" + id + "'.");
     443              :     }
     444              :     // get the positions
     445         1968 :     myCurrentStoppingPlace->startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0.);
     446         1968 :     myCurrentStoppingPlace->endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
     447         1968 :     const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
     448         1968 :     if (!ok || (SUMORouteHandler::checkStopPos(myCurrentStoppingPlace->startPos, myCurrentStoppingPlace->endPos, edge->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
     449            0 :         throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
     450              :     }
     451              :     // this is a hack: the busstop attribute is meant to hold the id within the simulation context but this is not used within the router context
     452         1968 :     myCurrentStoppingPlace->busstop = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
     453              :     // this is a hack: the actType is not used when using this to encode a stopping place
     454         1968 :     myCurrentStoppingPlace->actType = toString(element);
     455         1968 :     myNet.addStoppingPlace(id, element, myCurrentStoppingPlace);
     456         1968 : }
     457              : 
     458              : 
     459              : void
     460         2076 : RONetHandler::parseAccess(const SUMOSAXAttributes& attrs) {
     461         2076 :     bool ok = true;
     462         2076 :     const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
     463         2076 :     const ROEdge* edge = myNet.getEdgeForLaneID(lane);
     464         2076 :     if (edge == nullptr) {
     465            0 :         throw InvalidArgument("Unknown lane '" + lane + "' for access.");
     466              :     }
     467         2076 :     if ((edge->getPermissions() & SVC_PEDESTRIAN) == 0) {
     468            0 :         WRITE_WARNINGF(TL("Ignoring invalid access from non-pedestrian edge '%'."), edge->getID());
     469              :         return;
     470              :     }
     471         2076 :     const bool random = attrs.getOpt<std::string>(SUMO_ATTR_POSITION, "access", ok) == "random";
     472         2076 :     double pos = random ? edge->getLength() / 2. : attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0.);
     473         2076 :     double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
     474         2076 :     const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
     475         2076 :     if (!ok || (SUMORouteHandler::checkStopPos(pos, pos, edge->getLength(), 0., friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
     476            0 :         throw InvalidArgument("Invalid position " + toString(pos) + " for access on lane '" + lane + "'.");
     477              :     }
     478              :     if (!ok) {
     479              :         throw ProcessError();
     480              :     }
     481         2076 :     if (length < 0) {
     482          568 :         const Position accPos = myNet.getLane(lane)->geometryPositionAtOffset(pos);
     483          568 :         const double stopCenter = (myCurrentStoppingPlace->startPos + myCurrentStoppingPlace->endPos) / 2;
     484          568 :         const Position stopPos = myNet.getLane(myCurrentStoppingPlace->lane)->geometryPositionAtOffset(stopCenter);
     485          568 :         length  = accPos.distanceTo(stopPos);
     486              :     }
     487         4152 :     myCurrentStoppingPlace->accessPos.push_back(std::make_tuple(lane, pos, length));
     488              : }
     489              : 
     490              : 
     491              : void
     492          383 : RONetHandler::parseDistrict(const SUMOSAXAttributes& attrs) {
     493          383 :     myCurrentEdge = nullptr;
     494          383 :     bool ok = true;
     495          383 :     myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     496          383 :     if (!ok) {
     497            0 :         return;
     498              :     }
     499          766 :     ROEdge* const sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", nullptr, nullptr, 0, "", "");
     500          766 :     ROEdge* const source = myEdgeBuilder.buildEdge(myCurrentName + "-source", nullptr, nullptr, 0, "", "");
     501          383 :     myNet.addDistrict(myCurrentName, source, sink);
     502          383 :     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
     503          244 :         const std::vector<std::string>& desc = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentName.c_str(), ok);
     504          809 :         for (const std::string& eID : desc) {
     505         1695 :             myNet.addDistrictEdge(myCurrentName, eID, true);
     506         1695 :             myNet.addDistrictEdge(myCurrentName, eID, false);
     507              :         }
     508          244 :     }
     509              : }
     510              : 
     511              : 
     512              : void
     513          253 : RONetHandler::parseDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
     514          253 :     bool ok = true;
     515          253 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
     516          759 :     myNet.addDistrictEdge(myCurrentName, id, isSource);
     517          253 : }
     518              : 
     519              : void
     520         4297 : RONetHandler::setLocation(const SUMOSAXAttributes& attrs) {
     521         4297 :     bool ok = true;
     522         4297 :     PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
     523         4297 :     Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
     524         4297 :     Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
     525         4297 :     std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
     526         4297 :     if (ok) {
     527         4297 :         Position networkOffset = s[0];
     528         4297 :         GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
     529              :     }
     530         4297 : }
     531              : 
     532              : 
     533              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1