LCOV - code coverage report
Current view: top level - src/jtrrouter - ROJTRTurnDefLoader.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 76.7 % 103 79
Test Date: 2024-11-22 15:46:21 Functions: 85.7 % 7 6

            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    ROJTRTurnDefLoader.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Tue, 20 Jan 2004
      19              : ///
      20              : // Loader for the of turning percentages and source/sink definitions
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <set>
      25              : #include <string>
      26              : #include <utils/common/FileHelpers.h>
      27              : #include <utils/xml/XMLSubSys.h>
      28              : #include <utils/common/UtilExceptions.h>
      29              : #include <utils/common/MsgHandler.h>
      30              : #include <utils/common/StringUtils.h>
      31              : #include <utils/common/ToString.h>
      32              : #include <utils/options/OptionsCont.h>
      33              : #include <utils/xml/SUMOXMLDefinitions.h>
      34              : #include <utils/vehicle/SUMOVehicleParserHelper.h>
      35              : #include <router/RONet.h>
      36              : #include "ROJTREdge.h"
      37              : #include "ROJTRTurnDefLoader.h"
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // method definitions
      42              : // ===========================================================================
      43           56 : ROJTRTurnDefLoader::ROJTRTurnDefLoader(RONet& net) :
      44           56 :     SUMOSAXHandler("turn-ratio-file"), myNet(net),
      45           56 :     myIntervalBegin(0), myIntervalEnd(STEPS2TIME(SUMOTime_MAX)),
      46           56 :     myEdge(nullptr),
      47           56 :     mySourcesAreSinks(OptionsCont::getOptions().getBool("sources-are-sinks")),
      48           56 :     myDiscountSources(OptionsCont::getOptions().getBool("discount-sources")),
      49          112 :     myHaveWarnedAboutDeprecatedFormat(false)
      50           56 : {}
      51              : 
      52              : 
      53           56 : ROJTRTurnDefLoader::~ROJTRTurnDefLoader() {}
      54              : 
      55              : 
      56              : void
      57         1620 : ROJTRTurnDefLoader::myStartElement(int element,
      58              :                                    const SUMOSAXAttributes& attrs) {
      59         1620 :     bool ok = true;
      60         1620 :     switch (element) {
      61           34 :         case SUMO_TAG_INTERVAL:
      62           34 :             myIntervalBegin = attrs.get<double>(SUMO_ATTR_BEGIN, nullptr, ok);
      63           34 :             myIntervalEnd = attrs.get<double>(SUMO_ATTR_END, nullptr, ok);
      64           34 :             break;
      65           58 :         case SUMO_TAG_FROMEDGE:
      66           58 :             if (!myHaveWarnedAboutDeprecatedFormat) {
      67            7 :                 myHaveWarnedAboutDeprecatedFormat = true;
      68           14 :                 WRITE_WARNINGF(TL("The turn-file format with elements %, % is deprecated, please use % instead."),
      69              :                                toString(SUMO_TAG_FROMEDGE), toString(SUMO_TAG_TOEDGE), toString(SUMO_TAG_EDGEREL));
      70              :             }
      71           58 :             beginFromEdge(attrs);
      72              :             break;
      73          173 :         case SUMO_TAG_TOEDGE:
      74          173 :             addToEdge(attrs);
      75              :             break;
      76         1012 :         case SUMO_TAG_EDGEREL:
      77         1012 :             addEdgeRel(attrs);
      78              :             break;
      79            9 :         case SUMO_TAG_SINK:
      80            9 :             if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
      81            9 :                 std::string edges = attrs.get<std::string>(SUMO_ATTR_EDGES, nullptr, ok);
      82           21 :                 StringTokenizer st(edges, StringTokenizer::WHITECHARS);
      83           17 :                 while (st.hasNext()) {
      84           11 :                     std::string id = st.next();
      85           11 :                     ROEdge* edge = myNet.getEdge(id);
      86            8 :                     if (edge == nullptr) {
      87            9 :                         throw ProcessError(TLF("The edge '%' declared as a sink is not known.", id));
      88              :                     }
      89              :                     edge->setSink();
      90              :                 }
      91            9 :             }
      92              :             break;
      93          276 :         case SUMO_TAG_FLOW: {
      94          276 :             const std::string flowID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
      95          276 :             if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
      96          276 :                 const std::string edgeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
      97          276 :                 ROEdge* edge = myNet.getEdge(edgeID);
      98          276 :                 if (edge == nullptr) {
      99            0 :                     throw ProcessError("The from-edge '" + edgeID + "' in flow '" + flowID + "' is not known.");
     100              :                 }
     101          276 :                 if (mySourcesAreSinks) {
     102              :                     edge->setSink();
     103              :                 }
     104          276 :                 if (myDiscountSources) {
     105          184 :                     SUMOVehicleParameter* pars = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, true, true, 0, TIME2STEPS(3600 * 24));
     106              :                     int numVehs = 0;
     107          184 :                     if (pars->repetitionProbability > 0) {
     108            0 :                         numVehs = int(STEPS2TIME(pars->repetitionEnd - pars->depart) * pars->repetitionProbability);
     109              :                     } else {
     110          184 :                         numVehs = pars->repetitionNumber;
     111              :                     }
     112          184 :                     delete pars;
     113              :                     static_cast<ROJTREdge*>(edge)->changeSourceFlow(numVehs);
     114              :                 }
     115              :             } else {
     116            0 :                 WRITE_WARNINGF(TL("Ignoring flow '%' without 'from'"), flowID);
     117              :             }
     118              :             break;
     119              :         }
     120            0 :         case SUMO_TAG_SOURCE:
     121            0 :             if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
     122            0 :                 std::string edges = attrs.get<std::string>(SUMO_ATTR_EDGES, nullptr, ok);
     123            0 :                 StringTokenizer st(edges, StringTokenizer::WHITECHARS);
     124            0 :                 while (st.hasNext()) {
     125            0 :                     std::string id = st.next();
     126            0 :                     ROEdge* edge = myNet.getEdge(id);
     127            0 :                     if (edge == nullptr) {
     128            0 :                         throw ProcessError(TLF("The edge '%' declared as a source is not known.", id));
     129              :                     }
     130              :                     edge->setSource();
     131              :                 }
     132            0 :             }
     133              :             break;
     134              :         default:
     135              :             break;
     136              :     }
     137         1617 : }
     138              : 
     139              : 
     140              : void
     141           58 : ROJTRTurnDefLoader::beginFromEdge(const SUMOSAXAttributes& attrs) {
     142           58 :     myEdge = nullptr;
     143           58 :     bool ok = true;
     144              :     // get the id, report an error if not given or empty...
     145           58 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     146           58 :     if (!ok) {
     147              :         return;
     148              :     }
     149              :     //
     150           58 :     myEdge = static_cast<ROJTREdge*>(myNet.getEdge(id));
     151           58 :     if (myEdge == nullptr) {
     152            0 :         WRITE_ERRORF(TL("The edge '%' is not known within the network (within a 'from-edge' tag)."), id);
     153            0 :         return;
     154              :     }
     155              : }
     156              : 
     157              : 
     158              : void
     159          173 : ROJTRTurnDefLoader::addToEdge(const SUMOSAXAttributes& attrs) {
     160          173 :     if (myEdge == nullptr) {
     161            0 :         return;
     162              :     }
     163          173 :     bool ok = true;
     164              :     // get the id, report an error if not given or empty...
     165          173 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     166          173 :     if (!ok) {
     167              :         return;
     168              :     }
     169              :     //
     170          173 :     ROJTREdge* edge = static_cast<ROJTREdge*>(myNet.getEdge(id));
     171          173 :     if (edge == nullptr) {
     172            0 :         WRITE_ERRORF(TL("The edge '%' is not known within the network (within a 'to-edge' tag)."), id);
     173            0 :         return;
     174              :     }
     175          173 :     const double probability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
     176          173 :     if (ok) {
     177          173 :         if (probability < 0) {
     178            0 :             WRITE_ERRORF(TL("'probability' must be positive (in definition of to-edge '%')."), id);
     179              :         } else {
     180          173 :             myEdge->addFollowerProbability(edge, myIntervalBegin, myIntervalEnd, probability);
     181              :         }
     182              :     }
     183              : }
     184              : 
     185              : 
     186              : void
     187         1012 : ROJTRTurnDefLoader::addEdgeRel(const SUMOSAXAttributes& attrs) {
     188         1012 :     bool ok = true;
     189              :     // get the id, report an error if not given or empty...
     190         1012 :     std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
     191         1012 :     std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
     192         2024 :     double probability = attrs.get<double>(
     193         1564 :                              attrs.hasAttribute(SUMO_ATTR_COUNT) && !attrs.hasAttribute(SUMO_ATTR_PROB) ? SUMO_ATTR_COUNT : SUMO_ATTR_PROB,
     194         1012 :                              (fromID + "->" + toID).c_str(), ok);
     195         1012 :     if (!ok) {
     196              :         return;
     197              :     }
     198              :     //
     199         1012 :     ROJTREdge* from = static_cast<ROJTREdge*>(myNet.getEdge(fromID));
     200         1012 :     if (from == nullptr) {
     201            0 :         WRITE_ERRORF(TL("The edge '%' is not known."), fromID);
     202            0 :         return;
     203              :     }
     204              :     ROJTREdge* to = static_cast<ROJTREdge*>(myNet.getEdge(toID));
     205         1012 :     if (to == nullptr) {
     206            0 :         WRITE_ERRORF(TL("The edge '%' is not known."), toID);
     207            0 :         return;
     208              :     }
     209         1012 :     if (probability < 0) {
     210            0 :         WRITE_ERRORF(TL("'probability' must be positive (in edgeRelation from '%' to '%'."), fromID, toID);
     211              :     } else {
     212         1012 :         from->addFollowerProbability(to, myIntervalBegin, myIntervalEnd, probability);
     213              :     }
     214              : }
     215              : 
     216              : 
     217              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1