LCOV - code coverage report
Current view: top level - src/router - ROLoader.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 113 131 86.3 %
Date: 2024-05-07 15:28:01 Functions: 10 11 90.9 %

          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    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        9472 : ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id,
      55             :         double val, double beg, double end) const {
      56        9472 :     ROEdge* e = myNet.getEdge(id);
      57        9472 :     if (e != nullptr) {
      58        9472 :         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        9472 : }
      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        5058 : ROLoader::ROLoader(OptionsCont& oc, const bool emptyDestinationsAllowed, const bool logSteps) :
      96        5058 :     myOptions(oc),
      97        5058 :     myEmptyDestinationsAllowed(emptyDestinationsAllowed),
      98        5058 :     myLogSteps(logSteps),
      99        9309 :     myLoaders(oc.exists("unsorted-input") && oc.getBool("unsorted-input") ? 0 : DELTA_T) {
     100        5058 : }
     101             : 
     102             : 
     103        5058 : ROLoader::~ROLoader() {
     104        5058 : }
     105             : 
     106             : 
     107             : void
     108        5058 : ROLoader::loadNet(RONet& toFill, ROAbstractEdgeBuilder& eb) {
     109       10116 :     std::string file = myOptions.getString("net-file");
     110        5058 :     if (file == "") {
     111          14 :         throw ProcessError(TL("Missing definition of network to load!"));
     112             :     }
     113       10102 :     if (!FileHelpers::isReadable(file)) {
     114          39 :         throw ProcessError(TLF("The network file '%' is not accessible.", file));
     115             :     }
     116       10086 :     PROGRESS_BEGIN_MESSAGE(TL("Loading net"));
     117       14327 :     RONetHandler handler(toFill, eb, !myOptions.exists("no-internal-links") || myOptions.getBool("no-internal-links"),
     118       18748 :                          myOptions.exists("weights.minor-penalty") ? myOptions.getFloat("weights.minor-penalty") : 0,
     119       25926 :                          myOptions.exists("weights.tls-penalty") ? myOptions.getFloat("weights.tls-penalty") : 0);
     120        5043 :     handler.setFileName(file);
     121        5043 :     if (!XMLSubSys::runParser(handler, file, true)) {
     122        1404 :         PROGRESS_FAILED_MESSAGE();
     123        1404 :         throw ProcessError();
     124             :     } else {
     125        3639 :         PROGRESS_DONE_MESSAGE();
     126             :     }
     127       14052 :     if (myOptions.exists("restriction-params") && myOptions.isSet("restriction-params")) {
     128          32 :         const std::vector<std::string> paramKeys = myOptions.getStringVector("restriction-params");
     129         240 :         for (auto& edgeIt : toFill.getEdgeMap()) {
     130         224 :             edgeIt.second->cacheParamRestrictions(paramKeys);
     131             :         }
     132          16 :     }
     133        3639 :     if (!deprecatedVehicleClassesSeen.empty()) {
     134           0 :         WRITE_WARNINGF(TL("Deprecated vehicle classes '%' in input network."), toString(deprecatedVehicleClassesSeen));
     135             :         deprecatedVehicleClassesSeen.clear();
     136             :     }
     137        7278 :     if (myOptions.isSet("additional-files", false)) { // dfrouter does not register this option
     138        1410 :         std::vector<std::string> files = myOptions.getStringVector("additional-files");
     139        1488 :         for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
     140        1574 :             if (!FileHelpers::isReadable(*fileIt)) {
     141           0 :                 throw ProcessError(TLF("The additional file '%' is not accessible.", *fileIt));
     142             :             }
     143        1574 :             PROGRESS_BEGIN_MESSAGE("Loading additional file '" + *fileIt + "' ");
     144         787 :             handler.setFileName(*fileIt);
     145         787 :             if (!XMLSubSys::runParser(handler, *fileIt)) {
     146           4 :                 PROGRESS_FAILED_MESSAGE();
     147           4 :                 throw ProcessError();
     148             :             } else {
     149         783 :                 PROGRESS_DONE_MESSAGE();
     150             :             }
     151             :         }
     152         705 :     }
     153       10341 :     if (myOptions.exists("junction-taz") && myOptions.getBool("junction-taz")) {
     154             :         // create a TAZ for every junction
     155          76 :         toFill.addJunctionTaz(eb);
     156             :     }
     157        3635 :     toFill.setBidiEdges(handler.getBidiMap());
     158        8678 : }
     159             : 
     160             : 
     161             : void
     162        3294 : ROLoader::openRoutes(RONet& net) {
     163             :     // build loader
     164             :     // load relevant elements from additional file
     165        3294 :     bool ok = openTypedRoutes("additional-files", net, true);
     166             :     // load sumo routes, trips, and flows
     167        3294 :     ok &= openTypedRoutes("route-files", net);
     168             :     // check
     169        3294 :     if (ok) {
     170        6552 :         myLoaders.loadNext(string2time(myOptions.getString("begin")));
     171        2898 :         if (!net.furtherStored()) {
     172          66 :             if (MsgHandler::getErrorInstance()->wasInformed()) {
     173          53 :                 throw ProcessError();
     174             :             } else {
     175          13 :                 const std::string error = "No route input specified or all routes were invalid.";
     176          26 :                 if (myOptions.getBool("ignore-errors")) {
     177          21 :                     WRITE_WARNING(error);
     178             :                 } else {
     179          18 :                     throw ProcessError(error);
     180             :                 }
     181             :             }
     182             :         }
     183             :         // skip routes prior to the begin time
     184        5672 :         if (!myOptions.getBool("unsorted-input")) {
     185        5558 :             WRITE_MESSAGE("Skipped until: " + time2string(myLoaders.getFirstLoadTime()));
     186             :         }
     187             :     }
     188        2854 : }
     189             : 
     190             : 
     191             : void
     192        2841 : ROLoader::processRoutes(const SUMOTime start, const SUMOTime end, const SUMOTime increment,
     193             :                         RONet& net, const RORouterProvider& provider) {
     194        2841 :     const SUMOTime absNo = end - start;
     195        2841 :     const bool endGiven = !OptionsCont::getOptions().isDefault("end");
     196             :     // skip routes that begin before the simulation's begin
     197             :     // loop till the end
     198             :     const SUMOTime firstStep = myLoaders.getFirstLoadTime();
     199             :     SUMOTime lastStep = firstStep;
     200             :     SUMOTime time = MIN2(firstStep, end);
     201       19312 :     while (time <= end) {
     202       19312 :         writeStats(time, start, absNo, endGiven);
     203       19312 :         myLoaders.loadNext(time);
     204       19296 :         if (!net.furtherStored() || MsgHandler::getErrorInstance()->wasInformed()) {
     205             :             break;
     206             :         }
     207       19170 :         lastStep = net.saveAndRemoveRoutesUntil(myOptions, provider, time);
     208       19154 :         if (time == end || (!net.furtherStored() && myLoaders.haveAllLoaded()) || MsgHandler::getErrorInstance()->wasInformed()) {
     209             :             break;
     210             :         }
     211       16471 :         if (time < end && time > end - increment) {
     212             :             time = end;
     213             :         } else {
     214       16409 :             time += increment;
     215             :         }
     216             :     }
     217        2809 :     if (myLogSteps) {
     218         844 :         WRITE_MESSAGEF(TL("Routes found between time steps % and %."), time2string(firstStep), time2string(lastStep));
     219             :     }
     220        2809 : }
     221             : 
     222             : 
     223             : bool
     224        6588 : ROLoader::openTypedRoutes(const std::string& optionName,
     225             :                           RONet& net, const bool readAll) {
     226             :     // check whether the current loader is wished
     227             :     //  and the file(s) can be used
     228        6588 :     if (!myOptions.isUsableFileList(optionName)) {
     229        2885 :         return !myOptions.isSet(optionName);
     230             :     }
     231        7500 :     for (const std::string& fileIt : myOptions.getStringVector(optionName)) {
     232             :         try {
     233        7594 :             RORouteHandler* handler = new RORouteHandler(net, fileIt, myOptions.getBool("repair"), myEmptyDestinationsAllowed, myOptions.getBool("ignore-errors"), !readAll);
     234        3797 :             if (readAll) {
     235         694 :                 if (!XMLSubSys::runParser(*handler, fileIt)) {
     236           0 :                     WRITE_ERRORF(TL("Loading of % failed."), fileIt);
     237           0 :                     return false;
     238             :                 }
     239         694 :                 delete handler;
     240             :             } else {
     241        3103 :                 myLoaders.add(new SUMORouteLoader(handler));
     242             :             }
     243           0 :         } catch (ProcessError& e) {
     244           0 :             WRITE_ERRORF(TL("The loader for % from file '%' could not be initialised (%)."), optionName, fileIt, e.what());
     245             :             return false;
     246           0 :         }
     247             :     }
     248             :     return true;
     249             : }
     250             : 
     251             : 
     252             : bool
     253         726 : ROLoader::loadWeights(RONet& net, const std::string& optionName,
     254             :                       const std::string& measure, const bool useLanes, const bool boundariesOverride) {
     255             :     // check whether the file exists
     256         726 :     if (!myOptions.isUsableFileList(optionName)) {
     257             :         return false;
     258             :     }
     259             :     // build and prepare the weights handler
     260             :     std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
     261             :     //  travel time, first (always used)
     262             :     EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(net);
     263         726 :     retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever));
     264             :     //  the measure to use, then
     265             :     EdgeFloatTimeLineRetriever_EdgeWeight eRetriever(net);
     266         726 :     if (measure != "traveltime") {
     267             :         std::string umeasure = measure;
     268          39 :         if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
     269          16 :             umeasure = measure + "_perVeh";
     270             :         }
     271          10 :         retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever));
     272             :     }
     273             :     //  set up handler
     274         726 :     SAXWeightsHandler handler(retrieverDefs, "");
     275             :     // go through files
     276         726 :     std::vector<std::string> files = myOptions.getStringVector(optionName);
     277        1460 :     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
     278        1468 :         PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'");
     279         734 :         if (XMLSubSys::runParser(handler, *fileIt)) {
     280         734 :             PROGRESS_DONE_MESSAGE();
     281             :         } else {
     282           0 :             WRITE_MESSAGE(TL("failed."));
     283             :             return false;
     284             :         }
     285             :     }
     286             :     // build edge-internal time lines
     287        9749 :     for (const auto& i : net.getEdgeMap()) {
     288        9023 :         i.second->buildTimeLines(measure, boundariesOverride);
     289             :     }
     290             :     return true;
     291         726 : }
     292             : 
     293             : 
     294             : void
     295       19312 : ROLoader::writeStats(const SUMOTime time, const SUMOTime start, const SUMOTime absNo, bool endGiven) {
     296       19312 :     if (myLogSteps) {
     297         852 :         if (endGiven) {
     298           0 :             const double perc = (double)(time - start) / (double) absNo;
     299           0 :             std::cout << "Reading up to time step: " + time2string(time) + "  (" + time2string(time - start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done)       \r";
     300             :         } else {
     301        1704 :             std::cout << "Reading up to time step: " + time2string(time) + "\r";
     302             :         }
     303             :     }
     304       19312 : }
     305             : 
     306             : 
     307             : /****************************************************************************/

Generated by: LCOV version 1.14