LCOV - code coverage report
Current view: top level - src/router - ROLoader.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 87.1 % 139 121
Test Date: 2025-05-17 15:32:44 Functions: 91.7 % 12 11

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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    ROLoader.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Sascha Krieg
      18              : /// @author  Michael Behrisch
      19              : /// @author  Christian Roessel
      20              : /// @date    Sept 2002
      21              : ///
      22              : // Loader for networks and route imports
      23              : /****************************************************************************/
      24              : #include <config.h>
      25              : 
      26              : #include <iostream>
      27              : #include <string>
      28              : #include <iomanip>
      29              : #include <utils/options/OptionsCont.h>
      30              : #include <utils/common/ToString.h>
      31              : #include <utils/common/StringTokenizer.h>
      32              : #include <utils/common/MsgHandler.h>
      33              : #include <utils/common/UtilExceptions.h>
      34              : #include <utils/common/FileHelpers.h>
      35              : #include <utils/xml/XMLSubSys.h>
      36              : #include <utils/xml/SAXWeightsHandler.h>
      37              : #include <utils/vehicle/SUMORouteLoader.h>
      38              : #include <utils/vehicle/SUMORouteLoaderControl.h>
      39              : #include "RONet.h"
      40              : #include "RONetHandler.h"
      41              : #include "ROLoader.h"
      42              : #include "ROLane.h"
      43              : #include "ROEdge.h"
      44              : #include "RORouteHandler.h"
      45              : 
      46              : 
      47              : // ===========================================================================
      48              : // method definitions
      49              : // ===========================================================================
      50              : // ---------------------------------------------------------------------------
      51              : // ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
      52              : // ---------------------------------------------------------------------------
      53              : void
      54         5262 : ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id,
      55              :         double val, double beg, double end) const {
      56         5262 :     ROEdge* e = myNet.getEdge(id);
      57         5262 :     if (e != nullptr) {
      58         5262 :         e->addTravelTime(val, beg, end);
      59              :     } else {
      60            0 :         if (id[0] != ':') {
      61            0 :             if (OptionsCont::getOptions().getBool("ignore-errors")) {
      62            0 :                 WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
      63              :             } else {
      64            0 :                 WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
      65              :             }
      66              :         }
      67              :     }
      68         5262 : }
      69              : 
      70              : 
      71              : // ---------------------------------------------------------------------------
      72              : // ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight - methods
      73              : // ---------------------------------------------------------------------------
      74              : void
      75          189 : ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight::addEdgeWeight(const std::string& id,
      76              :         double val, double beg, double end) const {
      77          189 :     ROEdge* e = myNet.getEdge(id);
      78          189 :     if (e != nullptr) {
      79          189 :         e->addEffort(val, beg, end);
      80              :     } else {
      81            0 :         if (id[0] != ':') {
      82            0 :             if (OptionsCont::getOptions().getBool("ignore-errors")) {
      83            0 :                 WRITE_WARNINGF(TL("Trying to set a weight for the unknown edge '%'."), id);
      84              :             } else {
      85            0 :                 WRITE_ERRORF(TL("Trying to set a weight for the unknown edge '%'."), id);
      86              :             }
      87              :         }
      88              :     }
      89          189 : }
      90              : 
      91              : 
      92              : // ---------------------------------------------------------------------------
      93              : // ROLoader - methods
      94              : // ---------------------------------------------------------------------------
      95        10102 : ROLoader::ROLoader(OptionsCont& oc, const bool emptyDestinationsAllowed, const bool logSteps) :
      96        10102 :     myOptions(oc),
      97        10102 :     myEmptyDestinationsAllowed(emptyDestinationsAllowed),
      98        10102 :     myLogSteps(logSteps),
      99        19666 :     myLoaders(oc.exists("unsorted-input") && oc.getBool("unsorted-input") ? 0 : DELTA_T) {
     100        10102 : }
     101              : 
     102              : 
     103        10102 : ROLoader::~ROLoader() {
     104        10102 : }
     105              : 
     106              : 
     107              : void
     108        10102 : ROLoader::loadNet(RONet& toFill, ROAbstractEdgeBuilder& eb) {
     109        10102 :     std::string file = myOptions.getString("net-file");
     110        10102 :     if (file == "") {
     111           14 :         throw ProcessError(TL("Missing definition of network to load!"));
     112              :     }
     113        20190 :     if (!FileHelpers::isReadable(file)) {
     114           24 :         throw ProcessError(TLF("The network file '%' is not accessible.", file));
     115              :     }
     116        20174 :     PROGRESS_BEGIN_MESSAGE(TL("Loading net"));
     117        29728 :     RONetHandler handler(toFill, eb, !myOptions.exists("no-internal-links") || myOptions.getBool("no-internal-links"),
     118        39480 :                          myOptions.exists("weights.minor-penalty") ? myOptions.getFloat("weights.minor-penalty") : 0,
     119        39480 :                          myOptions.exists("weights.tls-penalty") ? myOptions.getFloat("weights.tls-penalty") : 0,
     120        60809 :                          myOptions.exists("weights.turnaround-penalty") ? myOptions.getFloat("weights.turnaround-penalty") : 0);
     121        10087 :     handler.setFileName(file);
     122        10087 :     if (!XMLSubSys::runParser(handler, file, true)) {
     123          702 :         PROGRESS_FAILED_MESSAGE();
     124          702 :         throw ProcessError();
     125              :     } else {
     126         9385 :         PROGRESS_DONE_MESSAGE();
     127              :     }
     128         9385 :     if (!deprecatedVehicleClassesSeen.empty()) {
     129            0 :         WRITE_WARNINGF(TL("Deprecated vehicle classes '%' in input network."), toString(deprecatedVehicleClassesSeen));
     130              :         deprecatedVehicleClassesSeen.clear();
     131              :     }
     132        18770 :     if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
     133        13576 :         std::vector<std::string> files = myOptions.getStringVector("additional-files");
     134        13645 :         for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
     135        13722 :             if (!FileHelpers::isReadable(*fileIt)) {
     136            0 :                 throw ProcessError(TLF("The additional file '%' is not accessible.", *fileIt));
     137              :             }
     138        20583 :             PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
     139         6861 :             handler.setFileName(*fileIt);
     140         6861 :             if (!XMLSubSys::runParser(handler, *fileIt)) {
     141            4 :                 PROGRESS_FAILED_MESSAGE();
     142            4 :                 throw ProcessError();
     143              :             } else {
     144         6857 :                 PROGRESS_DONE_MESSAGE();
     145              :             }
     146              :         }
     147         6788 :     }
     148        18562 :     if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
     149              :         // create a TAZ for every junction
     150           91 :         toFill.addJunctionTaz(eb);
     151              :     }
     152         9381 :     toFill.setBidiEdges(handler.getBidiMap());
     153        18562 :     if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
     154           40 :         const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
     155          316 :         for (auto& edgeIt : toFill.getEdgeMap()) {
     156          296 :             edgeIt.second->cacheParamRestrictions(paramKeys);
     157              :         }
     158           20 :     }
     159         9381 :     if (toFill.hasRestrictions()) {
     160           71 :         for (auto& edgeIt : toFill.getEdgeMap()) {
     161           66 :             edgeIt.second->setRestrictions(toFill.getRestrictions(edgeIt.second->getType()));
     162              :         }
     163              :     }
     164        19468 : }
     165              : 
     166              : 
     167              : void
     168         9075 : ROLoader::openRoutes(RONet& net) {
     169              :     // build loader
     170              :     // load relevant elements from additional file
     171         9075 :     bool ok = openTypedRoutes("additional-files", net, true);
     172              :     // load sumo routes, trips, and flows
     173         9075 :     ok &= openTypedRoutes("route-files", net);
     174              :     // check
     175         9075 :     if (ok) {
     176         9058 :         myLoaders.loadNext(string2time(myOptions.getString("begin")));
     177         7145 :         if (!net.furtherStored()) {
     178          942 :             if (MsgHandler::getErrorInstance()->wasInformed()) {
     179          929 :                 throw ProcessError();
     180              :             } else {
     181           13 :                 const std::string error = "No route input specified or all routes were invalid.";
     182           26 :                 if (myOptions.getBool("ignore-errors")) {
     183           21 :                     WRITE_WARNING(error);
     184              :                 } else {
     185           18 :                     throw ProcessError(error);
     186              :                 }
     187              :             }
     188              :         }
     189              :         // skip routes prior to the begin time
     190        12414 :         if (!myOptions.getBool("unsorted-input")) {
     191        18468 :             WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
     192              :         }
     193              :     }
     194         6224 : }
     195              : 
     196              : 
     197              : void
     198         6205 : ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
     199              :                         RONet& net, const RORouterProvider& provider) {
     200         6205 :     const SUMOTime absNo = end - start;
     201         6205 :     const bool endGiven = !OptionsCont::getOptions().isDefault("end");
     202              :     // skip routes that begin before the simulation's begin
     203              :     // loop till the end
     204              :     const SUMOTime firstStep = myLoaders.getFirstLoadTime();
     205              :     SUMOTime lastStep = firstStep;
     206              :     SUMOTime time = MIN2(firstStep, end);
     207        25304 :     while (time <= end) {
     208        25304 :         writeStats(time, start, absNo, endGiven);
     209        25304 :         myLoaders.loadNext(time);
     210        25288 :         if (!net.furtherStored() || MsgHandler::getErrorInstance()->wasInformed()) {
     211              :             break;
     212              :         }
     213        25163 :         lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
     214        25147 :         if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
     215              :             break;
     216              :         }
     217        19099 :         if (time < end && time > end - increment) {
     218              :             time = end;
     219              :         } else {
     220        19041 :             time += increment;
     221              :         }
     222              :     }
     223         6173 :     if (myLogSteps) {
     224          432 :         WRITE_MESSAGEF(TL("Routes found between time steps % and %."), time2string(firstStep), time2string(lastStep));
     225              :     }
     226         6173 : }
     227              : 
     228              : 
     229              : bool
     230        18150 : ROLoader::openTypedRoutes(const std::string& optionName,
     231              :                           RONet& net, const bool readAll) {
     232              :     // check whether the current loader is wished
     233              :     //  and the file(s) can be used
     234        18150 :     if (!myOptions.isUsableFileList(optionName)) {
     235         2500 :         return !myOptions.isSet(optionName);
     236              :     }
     237        31385 :     for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
     238              :         try {
     239        31470 :             RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
     240        15735 :             if (readAll) {
     241         6762 :                 if (!XMLSubSys::runParser(*handler, fileIt)) {
     242            0 :                     WRITE_ERRORF(TL("Loading of % failed."), fileIt);
     243            0 :                     return false;
     244              :                 }
     245         6762 :                 delete handler;
     246              :             } else {
     247         8973 :                 myLoaders.add(new SUMORouteLoader(handler));
     248              :             }
     249            0 :         } catch (ProcessError& e) {
     250            0 :             WRITE_ERRORF(TL("The loader for % from file '%' could not be initialised (%)."), optionName, fileIt, e.what());
     251              :             return false;
     252            0 :         }
     253              :     }
     254              :     return true;
     255              : }
     256              : 
     257              : 
     258              : bool
     259          408 : ROLoader::loadWeights(RONet& net, const std::string& optionName,
     260              :                       const std::string& measure, const bool useLanes, const bool boundariesOverride) {
     261              :     // check whether the file exists
     262          408 :     if (!myOptions.isUsableFileList(optionName)) {
     263              :         return false;
     264              :     }
     265              :     // build and prepare the weights handler
     266              :     std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
     267              :     //  travel time, first (always used)
     268              :     EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(net);
     269          816 :     retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
     270              :     //  the measure to use, then
     271              :     EdgeFloatTimeLineRetriever_EdgeWeight eRetriever(net);
     272          408 :     if (measure != "traveltime") {
     273              :         std::string umeasure = measure;
     274           10 :         if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
     275           16 :             umeasure = measure + "_perVeh";
     276              :         }
     277           10 :         retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
     278              :     }
     279              :     //  set up handler
     280          408 :     SAXWeightsHandler handler(retrieverDefs, "");
     281              :     // go through files
     282          408 :     std::vector<std::string> files = myOptions.getStringVector(optionName);
     283          820 :     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
     284         1236 :         PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
     285          412 :         if (XMLSubSys::runParser(handler, *fileIt)) {
     286          412 :             PROGRESS_DONE_MESSAGE();
     287              :         } else {
     288            0 :             WRITE_MESSAGE(TL("failed."));
     289              :             return false;
     290              :         }
     291              :     }
     292              :     // build edge-internal time lines
     293         5523 :     for (const auto& i : net.getEdgeMap()) {
     294         5115 :         i.second->buildTimeLines(measure, boundariesOverride);
     295              :     }
     296              :     return true;
     297          408 : }
     298              : 
     299              : 
     300              : void
     301        25304 : ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
     302        25304 :     if (myLogSteps) {
     303          437 :         if (endGiven) {
     304            0 :             const double perc = (double)(time - start) / (double) absNo;
     305            0 :             std::cout << "Reading up to time step: " + time2string(time) + "  (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done)       \r";
     306              :         } else {
     307          874 :             std::cout << "Reading up to time step: " + time2string(time) + "\r";
     308              :         }
     309              :     }
     310        25304 : }
     311              : 
     312              : SUMORouteHandler*
     313           20 : ROLoader::getRouteHandler() {
     314           20 :     auto loader = myLoaders.getFirstLoader();
     315           20 :     if (loader != nullptr) {
     316           20 :         return loader->getRouteHandler();
     317              :     } else {
     318              :         return nullptr;
     319              :     }
     320              : }
     321              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1