LCOV - code coverage report
Current view: top level - src/router - RONetHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 96.4 % 251 242
Test Date: 2024-12-21 15:45:41 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-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    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        10018 : RONetHandler::RONetHandler(RONet& net, ROAbstractEdgeBuilder& eb, const bool ignoreInternal, const double minorPenalty, double tlsPenalty, double turnaroundPenalty) :
      49              :     SUMOSAXHandler("sumo-network"),
      50        10018 :     myNet(net),
      51              :     myNetworkVersion(0, 0),
      52        10018 :     myEdgeBuilder(eb), myIgnoreInternal(ignoreInternal),
      53        10018 :     myCurrentName(), myCurrentEdge(nullptr), myCurrentStoppingPlace(nullptr),
      54        10018 :     myMinorPenalty(minorPenalty),
      55        10018 :     myTLSPenalty(tlsPenalty),
      56        20036 :     myTurnaroundPenalty(turnaroundPenalty)
      57        10018 : {}
      58              : 
      59              : 
      60        20036 : RONetHandler::~RONetHandler() {}
      61              : 
      62              : 
      63              : void
      64      2359592 : RONetHandler::myStartElement(int element,
      65              :                              const SUMOSAXAttributes& attrs) {
      66      2359592 :     switch (element) {
      67        10018 :         case SUMO_TAG_LOCATION:
      68        10018 :             setLocation(attrs);
      69        10018 :             break;
      70        10018 :         case SUMO_TAG_NET: {
      71              :             bool ok;
      72        20036 :             myNetworkVersion = StringUtils::toVersion(attrs.get<std::string>(SUMO_ATTR_VERSION, nullptr, ok, false));
      73              :             break;
      74              :         }
      75       451220 :         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       451220 :             parseEdge(attrs);
      80       451208 :             break;
      81       601658 :         case SUMO_TAG_LANE:
      82       601658 :             parseLane(attrs);
      83       601658 :             break;
      84       149248 :         case SUMO_TAG_JUNCTION:
      85       149248 :             parseJunction(attrs);
      86       149248 :             break;
      87       718377 :         case SUMO_TAG_CONNECTION:
      88       718377 :             parseConnection(attrs);
      89       718059 :             break;
      90         1590 :         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         1590 :             parseStoppingPlace(attrs, (SumoXMLTag)element);
      97         1590 :             break;
      98         1088 :         case SUMO_TAG_ACCESS:
      99         1088 :             parseAccess(attrs);
     100         1088 :             break;
     101        12631 :         case SUMO_TAG_TAZ:
     102        12631 :             parseDistrict(attrs);
     103        12631 :             break;
     104          116 :         case SUMO_TAG_TAZSOURCE:
     105          116 :             parseDistrictEdge(attrs, true);
     106          116 :             break;
     107          117 :         case SUMO_TAG_TAZSINK:
     108          117 :             parseDistrictEdge(attrs, false);
     109          117 :             break;
     110         1782 :         case SUMO_TAG_TYPE: {
     111         1782 :             bool ok = true;
     112         3564 :             myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     113              :             break;
     114              :         }
     115            1 :         case SUMO_TAG_RESTRICTION: {
     116            1 :             bool ok = true;
     117            2 :             const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
     118            1 :             const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
     119            1 :             if (ok) {
     120            1 :                 myNet.addRestriction(myCurrentTypeID, svc, speed);
     121              :             }
     122              :             break;
     123              :         }
     124        52055 :         case SUMO_TAG_PARAM:
     125        52055 :             addParam(attrs);
     126        52055 :             break;
     127              :         default:
     128              :             break;
     129              :     }
     130      2359262 : }
     131              : 
     132              : 
     133              : void
     134      2358497 : RONetHandler::myEndElement(int element) {
     135      2358497 :     switch (element) {
     136         9433 :         case SUMO_TAG_NET:
     137              :             // build junction graph
     138         9511 :             for (std::set<std::string>::const_iterator it = myUnseenNodeIDs.begin(); it != myUnseenNodeIDs.end(); ++it) {
     139          234 :                 WRITE_ERRORF(TL("Unknown node '%'."), *it);
     140              :             }
     141              :             break;
     142              :         default:
     143              :             break;
     144              :     }
     145      2358497 : }
     146              : 
     147              : 
     148              : void
     149        52055 : RONetHandler::addParam(const SUMOSAXAttributes& attrs) {
     150        52055 :     bool ok = true;
     151        52055 :     const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
     152              :     // circumventing empty string test
     153        52055 :     const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
     154              :     // add parameter in current created element, or in myLoadedParameterised
     155        52055 :     if (myCurrentEdge != nullptr) {
     156        52055 :         myCurrentEdge->setParameter(key, val);
     157              :     }
     158        52055 : }
     159              : 
     160              : 
     161              : void
     162       451220 : RONetHandler::parseEdge(const SUMOSAXAttributes& attrs) {
     163              :     // get the id, report an error if not given or empty...
     164       451220 :     bool ok = true;
     165       451220 :     myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     166       451220 :     if (!ok) {
     167           12 :         throw ProcessError();
     168              :     }
     169       451208 :     const SumoXMLEdgeFunc func = attrs.getOpt<SumoXMLEdgeFunc>(SUMO_ATTR_FUNCTION, myCurrentName.c_str(), ok, SumoXMLEdgeFunc::NORMAL);
     170       451208 :     if (!ok) {
     171           54 :         return;
     172              :     }
     173              :     // get the edge
     174              :     std::string from;
     175              :     std::string to;
     176              :     int priority;
     177       451202 :     myCurrentEdge = nullptr;
     178       451202 :     if (func == SumoXMLEdgeFunc::INTERNAL || func == SumoXMLEdgeFunc::CROSSING || func == SumoXMLEdgeFunc::WALKINGAREA) {
     179              :         assert(myCurrentName[0] == ':');
     180       598874 :         const std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(myCurrentName);
     181              :         from = junctionID;
     182              :         to = junctionID;
     183              :         priority = -1;
     184       299437 :     } else {
     185       303530 :         from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
     186       303530 :         to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
     187       151765 :         priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
     188       151765 :         if (!ok) {
     189              :             return;
     190              :         }
     191              :     }
     192       451154 :     RONode* fromNode = myNet.getNode(from);
     193       362691 :     if (fromNode == nullptr) {
     194              :         myUnseenNodeIDs.insert(from);
     195        88463 :         fromNode = new RONode(from);
     196        88463 :         myNet.addNode(fromNode);
     197              :     }
     198       451154 :     RONode* toNode = myNet.getNode(to);
     199       432439 :     if (toNode == nullptr) {
     200              :         myUnseenNodeIDs.insert(to);
     201        18715 :         toNode = new RONode(to);
     202        18715 :         myNet.addNode(toNode);
     203              :     }
     204              :     // build the edge
     205       451154 :     myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
     206              :     // set the type
     207       451154 :     myCurrentEdge->setRestrictions(myNet.getRestrictions(attrs.getOpt<std::string>(SUMO_ATTR_TYPE, myCurrentName.c_str(), ok, "")));
     208       451154 :     myCurrentEdge->setFunction(func);
     209              : 
     210       451154 :     if (myNet.addEdge(myCurrentEdge)) {
     211       451142 :         fromNode->addOutgoing(myCurrentEdge);
     212       451142 :         toNode->addIncoming(myCurrentEdge);
     213       902284 :         const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, myCurrentName.c_str(), ok, "");
     214       451142 :         if (bidi != "") {
     215         6444 :             myBidiEdges[myCurrentEdge] = bidi;
     216              :         }
     217              :     } else {
     218           12 :         myCurrentEdge = nullptr;
     219              :     }
     220              : }
     221              : 
     222              : 
     223              : void
     224       601658 : RONetHandler::parseLane(const SUMOSAXAttributes& attrs) {
     225       601658 :     if (myCurrentEdge == nullptr) {
     226              :         // was an internal edge to skip or an error occurred
     227          282 :         return;
     228              :     }
     229       601532 :     bool ok = true;
     230              :     // get the id, report an error if not given or empty...
     231       601532 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     232       601532 :     if (!ok) {
     233              :         return;
     234              :     }
     235              :     // get the speed
     236       601508 :     double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
     237       601508 :     double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
     238       601508 :     std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
     239      1203016 :     std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
     240       601508 :     const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
     241       601508 :     if (!ok) {
     242              :         return;
     243              :     }
     244       601400 :     if (shape.size() < 2) {
     245           72 :         WRITE_ERRORF(TL("Ignoring lane '%' with broken shape."), id);
     246           24 :         return;
     247              :     }
     248              :     // get the length
     249              :     // get the vehicle classes
     250       601376 :     SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
     251       601376 :     if (permissions != SVCAll) {
     252       139172 :         myNet.setPermissionsFound();
     253              :     }
     254              :     // add when both values are valid
     255       601376 :     if (maxSpeed > 0 && length > 0 && id.length() > 0) {
     256       601376 :         myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions, shape));
     257              :     } else {
     258            0 :         WRITE_WARNING("Ignoring lane '" + id + "' with speed " + toString(maxSpeed) + " and length " + toString(length));
     259              :     }
     260       601508 : }
     261              : 
     262              : 
     263              : void
     264       149248 : RONetHandler::parseJunction(const SUMOSAXAttributes& attrs) {
     265       149248 :     bool ok = true;
     266              :     // get the id, report an error if not given or empty...
     267       149248 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     268       149248 :     const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
     269       149248 :     if (type == SumoXMLNodeType::INTERNAL) {
     270              :         return;
     271              :     }
     272              :     myUnseenNodeIDs.erase(id);
     273              :     // get the position of the node
     274       106670 :     const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
     275       106670 :     const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
     276       106670 :     const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
     277       106670 :     if (!ok) {
     278              :         return;
     279              :     }
     280       106625 :     RONode* n = myNet.getNode(id);
     281       106521 :     if (n == nullptr) {
     282          312 :         WRITE_WARNINGF(TL("Skipping isolated junction '%'."), id);
     283              :     } else {
     284       106521 :         n->setPosition(Position(x, y, z));
     285              :     }
     286              : }
     287              : 
     288              : 
     289              : void
     290       718377 : RONetHandler::parseConnection(const SUMOSAXAttributes& attrs) {
     291       718377 :     bool ok = true;
     292       718377 :     std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
     293       718377 :     std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
     294       718377 :     const int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
     295       718377 :     const int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
     296       718377 :     std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok);
     297       718695 :     std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
     298       718695 :     std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
     299       718377 :     ROEdge* from = myNet.getEdge(fromID);
     300              :     ROEdge* to = myNet.getEdge(toID);
     301       718377 :     if (from == nullptr) {
     302          207 :         throw ProcessError(TLF("unknown from-edge '%' in connection", fromID));
     303              :     }
     304       718308 :     if (to == nullptr) {
     305          207 :         throw ProcessError(TLF("unknown to-edge '%' in connection", toID));
     306              :     }
     307       718239 :     if ((int)from->getLanes().size() <= fromLane) {
     308          180 :         throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
     309              :     }
     310       718149 :     if ((int)to->getLanes().size() <= toLane) {
     311          180 :         throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
     312              :     }
     313       718059 :     if (myIgnoreInternal || viaID == "") {
     314       395286 :         std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
     315       395286 :         std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
     316              :         ROEdge* dummyVia = nullptr;
     317              :         SVCPermissions permissions;
     318       395286 :         if (allow == "" && disallow == "") {
     319              :             permissions = SVC_UNSPECIFIED;
     320              :         } else {
     321           13 :             myNet.setPermissionsFound();
     322              :             // dummyVia is only needed to hold permissions
     323           13 :             permissions = parseVehicleClasses(allow, disallow);
     324           26 :             dummyVia = new ROEdge("dummyVia_" + from->getLanes()[fromLane]->getID() + "->" + to->getLanes()[toLane]->getID(),
     325           26 :                     from->getToJunction(), from->getToJunction(), permissions);
     326              :         }
     327       395286 :         from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], dummyVia);
     328      1185858 :         from->addSuccessor(to, nullptr, dir);
     329              :     } else {
     330       322773 :         ROEdge* const via = myNet.getEdge(SUMOXMLDefinitions::getEdgeIDFromLane(viaID));
     331       322773 :         if (via == nullptr) {
     332            0 :             throw ProcessError(TLF("unknown via-edge '%' in connection", viaID));
     333              :         }
     334       322773 :         from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], via);
     335       645546 :         from->addSuccessor(to, via, dir);
     336       645546 :         via->addSuccessor(to, nullptr, dir);
     337       322773 :         LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
     338       322773 :         if (state == LINKSTATE_MINOR || state == LINKSTATE_EQUAL || state == LINKSTATE_STOP || state == LINKSTATE_ALLWAY_STOP) {
     339       159171 :             via->setTimePenalty(myMinorPenalty);
     340              :         }
     341       573865 :         if (dir == toString(LinkDirection::TURN) || dir == toString(LinkDirection::TURN_LEFTHAND)) {
     342        71999 :             via->setTimePenalty(myTurnaroundPenalty);
     343              :         }
     344       322773 :         if (tlID != "") {
     345         7747 :             via->setTimePenalty(myTLSPenalty);
     346              :         }
     347              :     }
     348       718059 :     if (to->isCrossing()) {
     349         6226 :         to->setTimePenalty(myTLSPenalty);
     350              :     }
     351       718059 : }
     352              : 
     353              : 
     354              : void
     355         1590 : RONetHandler::parseStoppingPlace(const SUMOSAXAttributes& attrs, const SumoXMLTag element) {
     356         1590 :     bool ok = true;
     357         1590 :     myCurrentStoppingPlace = new SUMOVehicleParameter::Stop();
     358              :     // get the id, throw if not given or empty...
     359         1590 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, toString(element).c_str(), ok);
     360              :     // get the lane
     361         1590 :     myCurrentStoppingPlace->lane = attrs.get<std::string>(SUMO_ATTR_LANE, toString(element).c_str(), ok);
     362         1590 :     if (!ok) {
     363            0 :         throw ProcessError();
     364              :     }
     365         1590 :     const ROEdge* edge = myNet.getEdgeForLaneID(myCurrentStoppingPlace->lane);
     366         1590 :     if (edge == nullptr) {
     367            0 :         throw InvalidArgument("Unknown lane '" + myCurrentStoppingPlace->lane + "' for " + toString(element) + " '" + id + "'.");
     368              :     }
     369              :     // get the positions
     370         1590 :     myCurrentStoppingPlace->startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0.);
     371         1590 :     myCurrentStoppingPlace->endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
     372         1590 :     const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
     373         1590 :     if (!ok || (SUMORouteHandler::checkStopPos(myCurrentStoppingPlace->startPos, myCurrentStoppingPlace->endPos, edge->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
     374            0 :         throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
     375              :     }
     376              :     // 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
     377         1590 :     myCurrentStoppingPlace->busstop = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
     378              :     // this is a hack: the actType is not used when using this to encode a stopping place
     379         1590 :     myCurrentStoppingPlace->actType = toString(element);
     380         1590 :     myNet.addStoppingPlace(id, element, myCurrentStoppingPlace);
     381         1590 : }
     382              : 
     383              : 
     384              : void
     385         1088 : RONetHandler::parseAccess(const SUMOSAXAttributes& attrs) {
     386         1088 :     bool ok = true;
     387         1088 :     const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
     388         1088 :     const ROEdge* edge = myNet.getEdgeForLaneID(lane);
     389         1088 :     if (edge == nullptr) {
     390            0 :         throw InvalidArgument("Unknown lane '" + lane + "' for access.");
     391              :     }
     392         1088 :     if ((edge->getPermissions() & SVC_PEDESTRIAN) == 0) {
     393            0 :         WRITE_WARNINGF(TL("Ignoring invalid access from non-pedestrian edge '%'."), edge->getID());
     394              :         return;
     395              :     }
     396         1088 :     const bool random = attrs.getOpt<std::string>(SUMO_ATTR_POSITION, "access", ok) == "random";
     397         1088 :     double pos = random ? edge->getLength() / 2. : attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0.);
     398         1088 :     double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
     399         1088 :     const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
     400         1088 :     if (!ok || (SUMORouteHandler::checkStopPos(pos, pos, edge->getLength(), 0., friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
     401            0 :         throw InvalidArgument("Invalid position " + toString(pos) + " for access on lane '" + lane + "'.");
     402              :     }
     403              :     if (!ok) {
     404              :         throw ProcessError();
     405              :     }
     406         1088 :     if (length < 0) {
     407          568 :         const Position accPos = myNet.getLane(lane)->geometryPositionAtOffset(pos);
     408          568 :         const double stopCenter = (myCurrentStoppingPlace->startPos + myCurrentStoppingPlace->endPos) / 2;
     409          568 :         const Position stopPos = myNet.getLane(myCurrentStoppingPlace->lane)->geometryPositionAtOffset(stopCenter);
     410          568 :         length  = accPos.distanceTo(stopPos);
     411              :     }
     412         2176 :     myCurrentStoppingPlace->accessPos.push_back(std::make_tuple(lane, pos, length));
     413              : }
     414              : 
     415              : 
     416              : void
     417        12631 : RONetHandler::parseDistrict(const SUMOSAXAttributes& attrs) {
     418        12631 :     myCurrentEdge = nullptr;
     419        12631 :     bool ok = true;
     420        12631 :     myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     421        12631 :     if (!ok) {
     422            0 :         return;
     423              :     }
     424        12631 :     ROEdge* const sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", nullptr, nullptr, 0);
     425        12631 :     ROEdge* const source = myEdgeBuilder.buildEdge(myCurrentName + "-source", nullptr, nullptr, 0);
     426        12631 :     myNet.addDistrict(myCurrentName, source, sink);
     427        12631 :     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
     428        12502 :         const std::vector<std::string>& desc = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentName.c_str(), ok);
     429        31434 :         for (const std::string& eID : desc) {
     430        56796 :             myNet.addDistrictEdge(myCurrentName, eID, true);
     431        56796 :             myNet.addDistrictEdge(myCurrentName, eID, false);
     432              :         }
     433        12502 :     }
     434              : }
     435              : 
     436              : 
     437              : void
     438          233 : RONetHandler::parseDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
     439          233 :     bool ok = true;
     440          233 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
     441          699 :     myNet.addDistrictEdge(myCurrentName, id, isSource);
     442          233 : }
     443              : 
     444              : void
     445        10018 : RONetHandler::setLocation(const SUMOSAXAttributes& attrs) {
     446        10018 :     bool ok = true;
     447        10018 :     PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
     448        10018 :     Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
     449        10018 :     Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
     450        10018 :     std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
     451        10018 :     if (ok) {
     452        10018 :         Position networkOffset = s[0];
     453        10018 :         GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
     454              :     }
     455        10018 : }
     456              : 
     457              : 
     458              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1