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

          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          65 : ROJTRTurnDefLoader::ROJTRTurnDefLoader(RONet& net) :
      44          65 :     SUMOSAXHandler("turn-ratio-file"), myNet(net),
      45          65 :     myIntervalBegin(0), myIntervalEnd(STEPS2TIME(SUMOTime_MAX)),
      46          65 :     myEdge(nullptr),
      47          65 :     mySourcesAreSinks(OptionsCont::getOptions().getBool("sources-are-sinks")),
      48          65 :     myDiscountSources(OptionsCont::getOptions().getBool("discount-sources")),
      49         130 :     myHaveWarnedAboutDeprecatedFormat(false)
      50          65 : {}
      51             : 
      52             : 
      53          65 : ROJTRTurnDefLoader::~ROJTRTurnDefLoader() {}
      54             : 
      55             : 
      56             : void
      57        2507 : ROJTRTurnDefLoader::myStartElement(int element,
      58             :                                    const SUMOSAXAttributes& attrs) {
      59        2507 :     bool ok = true;
      60        2507 :     switch (element) {
      61          40 :         case SUMO_TAG_INTERVAL:
      62          40 :             myIntervalBegin = attrs.get<double>(SUMO_ATTR_BEGIN, nullptr, ok);
      63          40 :             myIntervalEnd = attrs.get<double>(SUMO_ATTR_END, nullptr, ok);
      64          40 :             break;
      65          76 :         case SUMO_TAG_FROMEDGE:
      66          76 :             if (!myHaveWarnedAboutDeprecatedFormat) {
      67           9 :                 myHaveWarnedAboutDeprecatedFormat = true;
      68          18 :                 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          76 :             beginFromEdge(attrs);
      72             :             break;
      73         229 :         case SUMO_TAG_TOEDGE:
      74         229 :             addToEdge(attrs);
      75             :             break;
      76        1564 :         case SUMO_TAG_EDGEREL:
      77        1564 :             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          12 :                         throw ProcessError(TLF("The edge '%' declared as a sink is not known.", id));
      88             :                     }
      89             :                     edge->setSink();
      90             :                 }
      91           9 :             }
      92             :             break;
      93         522 :         case SUMO_TAG_FLOW: {
      94         522 :             const std::string flowID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
      95         522 :             if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
      96         522 :                 const std::string edgeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
      97         522 :                 ROEdge* edge = myNet.getEdge(edgeID);
      98         522 :                 if (edge == nullptr) {
      99           0 :                     throw ProcessError("The from-edge '" + edgeID + "' in flow '" + flowID + "' is not known.");
     100             :                 }
     101         522 :                 if (mySourcesAreSinks) {
     102             :                     edge->setSink();
     103             :                 }
     104         522 :                 if (myDiscountSources) {
     105         348 :                     SUMOVehicleParameter* pars = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, true, true, 0, TIME2STEPS(3600 * 24));
     106             :                     int numVehs = 0;
     107         348 :                     if (pars->repetitionProbability > 0) {
     108           0 :                         numVehs = int(STEPS2TIME(pars->repetitionEnd - pars->depart) * pars->repetitionProbability);
     109             :                     } else {
     110         348 :                         numVehs = pars->repetitionNumber;
     111             :                     }
     112         348 :                     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        2504 : }
     138             : 
     139             : 
     140             : void
     141          76 : ROJTRTurnDefLoader::beginFromEdge(const SUMOSAXAttributes& attrs) {
     142          76 :     myEdge = nullptr;
     143          76 :     bool ok = true;
     144             :     // get the id, report an error if not given or empty...
     145          76 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     146          76 :     if (!ok) {
     147             :         return;
     148             :     }
     149             :     //
     150          76 :     myEdge = static_cast<ROJTREdge*>(myNet.getEdge(id));
     151          76 :     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         229 : ROJTRTurnDefLoader::addToEdge(const SUMOSAXAttributes& attrs) {
     160         229 :     if (myEdge == nullptr) {
     161           0 :         return;
     162             :     }
     163         229 :     bool ok = true;
     164             :     // get the id, report an error if not given or empty...
     165         229 :     std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     166         229 :     if (!ok) {
     167             :         return;
     168             :     }
     169             :     //
     170         229 :     ROJTREdge* edge = static_cast<ROJTREdge*>(myNet.getEdge(id));
     171         229 :     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         229 :     const double probability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
     176         229 :     if (ok) {
     177         229 :         if (probability < 0) {
     178           0 :             WRITE_ERRORF(TL("'probability' must be positive (in definition of to-edge '%')."), id);
     179             :         } else {
     180         229 :             myEdge->addFollowerProbability(edge, myIntervalBegin, myIntervalEnd, probability);
     181             :         }
     182             :     }
     183             : }
     184             : 
     185             : 
     186             : void
     187        1564 : ROJTRTurnDefLoader::addEdgeRel(const SUMOSAXAttributes& attrs) {
     188        1564 :     bool ok = true;
     189             :     // get the id, report an error if not given or empty...
     190        1564 :     std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
     191        1564 :     std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
     192        2668 :     double probability = attrs.get<double>(
     193        2668 :                              attrs.hasAttribute(SUMO_ATTR_COUNT) && !attrs.hasAttribute(SUMO_ATTR_PROB) ? SUMO_ATTR_COUNT : SUMO_ATTR_PROB,
     194        3128 :                              (fromID + "->" + toID).c_str(), ok);
     195        1564 :     if (!ok) {
     196             :         return;
     197             :     }
     198             :     //
     199        1564 :     ROJTREdge* from = static_cast<ROJTREdge*>(myNet.getEdge(fromID));
     200        1564 :     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        1564 :     if (to == nullptr) {
     206           0 :         WRITE_ERRORF(TL("The edge '%' is not known."), toID);
     207           0 :         return;
     208             :     }
     209        1564 :     if (probability < 0) {
     210           0 :         WRITE_ERRORF(TL("'probability' must be positive (in edgeRelation from '%' to '%'."), fromID, toID);
     211             :     } else {
     212        1564 :         from->addFollowerProbability(to, myIntervalBegin, myIntervalEnd, probability);
     213             :     }
     214             : }
     215             : 
     216             : 
     217             : /****************************************************************************/

Generated by: LCOV version 1.14