LCOV - code coverage report
Current view: top level - src/duarouter - duarouter_main.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 126 138 91.3 %
Date: 2024-05-02 15:31:40 Functions: 3 3 100.0 %

          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    duarouter_main.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Thu, 06 Jun 2002
      19             : ///
      20             : // Main for DUAROUTER
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #ifdef HAVE_VERSION_H
      25             : #include <version.h>
      26             : #endif
      27             : 
      28             : #include <iostream>
      29             : #include <string>
      30             : #include <limits.h>
      31             : #include <ctime>
      32             : #include <memory>
      33             : #include <xercesc/sax/SAXException.hpp>
      34             : #include <xercesc/sax/SAXParseException.hpp>
      35             : #include <utils/common/StringUtils.h>
      36             : #include <utils/common/MsgHandler.h>
      37             : #include <utils/common/UtilExceptions.h>
      38             : #include <utils/common/SystemFrame.h>
      39             : #include <utils/common/RandHelper.h>
      40             : #include <utils/common/ToString.h>
      41             : #ifdef HAVE_FOX
      42             : #include <utils/foxtools/MsgHandlerSynchronized.h>
      43             : #endif
      44             : #include <utils/iodevices/OutputDevice.h>
      45             : #include <utils/options/Option.h>
      46             : #include <utils/options/OptionsCont.h>
      47             : #include <utils/options/OptionsIO.h>
      48             : #include <utils/router/DijkstraRouter.h>
      49             : #include <utils/router/AStarRouter.h>
      50             : #include <utils/router/CHRouter.h>
      51             : #include <utils/router/CHRouterWrapper.h>
      52             : #include <utils/xml/XMLSubSys.h>
      53             : #include <router/ROFrame.h>
      54             : #include <router/ROLoader.h>
      55             : #include <router/RONet.h>
      56             : #include <router/ROEdge.h>
      57             : #include "RODUAEdgeBuilder.h"
      58             : #include "RODUAFrame.h"
      59             : 
      60             : 
      61             : // ===========================================================================
      62             : // functions
      63             : // ===========================================================================
      64             : /* -------------------------------------------------------------------------
      65             :  * data processing methods
      66             :  * ----------------------------------------------------------------------- */
      67             : /**
      68             :  * loads the net
      69             :  * The net is in this meaning made up by the net itself and the dynamic
      70             :  * weights which may be supplied in a separate file
      71             :  */
      72             : void
      73        3609 : initNet(RONet& net, ROLoader& loader, OptionsCont& oc) {
      74             :     // load the net
      75        3609 :     RODUAEdgeBuilder builder;
      76        3609 :     ROEdge::setGlobalOptions(oc.getBool("weights.interpolate"));
      77        3609 :     loader.loadNet(net, builder);
      78             :     // load the weights when wished/available
      79        6258 :     if (oc.isSet("weight-files")) {
      80        2172 :         loader.loadWeights(net, "weight-files", oc.getString("weight-attribute"), false, oc.getBool("weights.expand"));
      81             :     }
      82        6258 :     if (oc.isSet("lane-weight-files")) {
      83           6 :         loader.loadWeights(net, "lane-weight-files", oc.getString("weight-attribute"), true, oc.getBool("weights.expand"));
      84             :     }
      85        3609 : }
      86             : 
      87             : 
      88             : /**
      89             :  * Computes the routes saving them
      90             :  */
      91             : void
      92        3129 : computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) {
      93             :     // initialise the loader
      94        3129 :     loader.openRoutes(net);
      95             :     // build the router
      96        2691 :     auto ttFunction = gWeightsRandomFactor > 1 ? &ROEdge::getTravelTimeStaticRandomized : &ROEdge::getTravelTimeStatic;
      97             :     SUMOAbstractRouter<ROEdge, ROVehicle>* router;
      98        2691 :     const std::string measure = oc.getString("weight-attribute");
      99        2735 :     const std::string routingAlgorithm = oc.getString("routing-algorithm");
     100        2691 :     const double priorityFactor = oc.getFloat("weights.priority-factor");
     101        5382 :     const SUMOTime begin = string2time(oc.getString("begin"));
     102        2887 :     const SUMOTime end = oc.isDefault("end") ? SUMOTime_MAX : string2time(oc.getString("end"));
     103             :     DijkstraRouter<ROEdge, ROVehicle>::Operation op = &ROEdge::getTravelTimeStatic;
     104             : 
     105        5394 :     if (oc.isSet("restriction-params") &&
     106           9 :             (routingAlgorithm == "CH" || routingAlgorithm == "CHWrapper")) {
     107          24 :         throw ProcessError(TLF("Routing algorithm '%' does not support restriction-params", routingAlgorithm));
     108             :     }
     109             : 
     110        2685 :     if (measure == "traveltime" && priorityFactor == 0) {
     111        2670 :         if (routingAlgorithm == "dijkstra") {
     112        2696 :             router = new DijkstraRouter<ROEdge, ROVehicle>(ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction, nullptr, false, nullptr, net.hasPermissions(), oc.isSet("restriction-params"));
     113        1322 :         } else if (routingAlgorithm == "astar") {
     114             :             typedef AStarRouter<ROEdge, ROVehicle> AStar;
     115         459 :             std::shared_ptr<const AStar::LookupTable> lookup;
     116         918 :             if (oc.isSet("astar.all-distances")) {
     117           0 :                 lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)ROEdge::getAllEdges().size());
     118         918 :             } else if (oc.isSet("astar.landmark-distances")) {
     119             :                 /* CHRouterWrapper<ROEdge, ROVehicle> chrouter(
     120             :                     ROEdge::getAllEdges(), true, &ROEdge::getTravelTimeStatic,
     121             :                     begin, end, SUMOTime_MAX, 1); */
     122          10 :                 DijkstraRouter<ROEdge, ROVehicle> forward(ROEdge::getAllEdges(), true, &ROEdge::getTravelTimeStatic);
     123             :                 std::vector<ReversedEdge<ROEdge, ROVehicle>*> reversed;
     124       20498 :                 for (ROEdge* edge : ROEdge::getAllEdges()) {
     125       20490 :                     reversed.push_back(edge->getReversedRoutingEdge());
     126             :                 }
     127       20498 :                 for (ReversedEdge<ROEdge, ROVehicle>* redge : reversed) {
     128       20488 :                     redge->init();
     129             :                 }
     130          10 :                 DijkstraRouter<ReversedEdge<ROEdge, ROVehicle>, ROVehicle> backward(reversed, true, &ReversedEdge<ROEdge, ROVehicle>::getTravelTimeStatic);
     131          12 :                 ROVehicle defaultVehicle(SUMOVehicleParameter(), nullptr, net.getVehicleTypeSecure(DEFAULT_VTYPE_ID), &net);
     132          30 :                 lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), ROEdge::getAllEdges(), &forward, &backward, &defaultVehicle,
     133          36 :                          oc.isSet("astar.save-landmark-distances") ? oc.getString("astar.save-landmark-distances") : "", oc.getInt("routing-threads"));
     134          10 :             }
     135         924 :             router = new AStar(ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction, lookup, net.hasPermissions(), oc.isSet("restriction-params"));
     136         863 :         } else if (routingAlgorithm == "CH" && !net.hasPermissions()) {
     137          65 :             const SUMOTime weightPeriod = (oc.isSet("weight-files") ?
     138          83 :                                            string2time(oc.getString("weight-period")) :
     139             :                                            SUMOTime_MAX);
     140             :             router = new CHRouter<ROEdge, ROVehicle>(
     141         130 :                 ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction, SVC_IGNORING, weightPeriod, net.hasPermissions(), oc.isSet("restriction-params"));
     142        1163 :         } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
     143             :             // use CHWrapper instead of CH if the net has permissions
     144         798 :             const SUMOTime weightPeriod = (oc.isSet("weight-files") ?
     145         820 :                                            string2time(oc.getString("weight-period")) :
     146             :                                            SUMOTime_MAX);
     147             :             router = new CHRouterWrapper<ROEdge, ROVehicle>(
     148        1596 :                 ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction,
     149        1596 :                 begin, end, weightPeriod, net.hasPermissions(), oc.getInt("routing-threads"));
     150             :         } else {
     151           0 :             throw ProcessError(TLF("Unknown routing Algorithm '%'!", routingAlgorithm));
     152             :         }
     153             :     } else {
     154          15 :         if (measure == "traveltime") {
     155           3 :             if (ROEdge::initPriorityFactor(priorityFactor)) {
     156             :                 op = &ROEdge::getTravelTimeStaticPriorityFactor;
     157             :             }
     158          12 :         } else if (measure == "CO") {
     159             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::CO>;
     160           8 :         } else if (measure == "CO2") {
     161             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::CO2>;
     162           7 :         } else if (measure == "PMx") {
     163             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::PM_X>;
     164           6 :         } else if (measure == "HC") {
     165             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::HC>;
     166           4 :         } else if (measure == "NOx") {
     167             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::NO_X>;
     168           3 :         } else if (measure == "fuel") {
     169             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::FUEL>;
     170           2 :         } else if (measure == "electricity") {
     171             :             op = &ROEdge::getEmissionEffort<PollutantsInterface::ELEC>;
     172           2 :         } else if (measure == "noise") {
     173             :             op = &ROEdge::getNoiseEffort;
     174             :         } else {
     175             :             op = &ROEdge::getStoredEffort;
     176             :         }
     177          15 :         if (measure != "traveltime" && !net.hasLoadedEffort()) {
     178           9 :             WRITE_WARNINGF(TL("No weight data was loaded for attribute '%'."), measure);
     179             :         }
     180             :         router = new DijkstraRouter<ROEdge, ROVehicle>(
     181          30 :             ROEdge::getAllEdges(), oc.getBool("ignore-errors"), op, ttFunction, false, nullptr, net.hasPermissions(), oc.isSet("restriction-params"));
     182             :     }
     183             :     int carWalk = 0;
     184        8049 :     for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) {
     185        2683 :         if (opt == "parkingAreas") {
     186        2639 :             carWalk |= ROIntermodalRouter::Network::PARKING_AREAS;
     187          44 :         } else if (opt == "ptStops") {
     188          36 :             carWalk |= ROIntermodalRouter::Network::PT_STOPS;
     189           8 :         } else if (opt == "allJunctions") {
     190           8 :             carWalk |= ROIntermodalRouter::Network::ALL_JUNCTIONS;
     191             :         }
     192             :     }
     193        5394 :     for (const std::string& opt : oc.getStringVector("persontrip.transfer.taxi-walk")) {
     194          28 :         if (opt == "ptStops") {
     195          12 :             carWalk |= ROIntermodalRouter::Network::TAXI_DROPOFF_PT;
     196          16 :         } else if (opt == "allJunctions") {
     197          16 :             carWalk |= ROIntermodalRouter::Network::TAXI_DROPOFF_ANYWHERE;
     198             :         }
     199             :     }
     200        5394 :     for (const std::string& opt : oc.getStringVector("persontrip.transfer.walk-taxi")) {
     201          28 :         if (opt == "ptStops") {
     202          12 :             carWalk |= ROIntermodalRouter::Network::TAXI_PICKUP_PT;
     203          16 :         } else if (opt == "allJunctions") {
     204          16 :             carWalk |= ROIntermodalRouter::Network::TAXI_PICKUP_ANYWHERE;
     205             :         }
     206             :     }
     207        5366 :     double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
     208             : 
     209             :     RailwayRouter<ROEdge, ROVehicle>* railRouter = nullptr;
     210        2683 :     if (net.hasBidiEdges()) {
     211          47 :         railRouter = new RailwayRouter<ROEdge, ROVehicle>(ROEdge::getAllEdges(), true, op, ttFunction, false, net.hasPermissions(),
     212         138 :                 oc.isSet("restriction-params"),
     213          94 :                 oc.getFloat("railway.max-train-length"));
     214             :     }
     215        2683 :     RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(),
     216        2683 :                               new ROIntermodalRouter(RONet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm),
     217             :                               railRouter);
     218             :     // process route definitions
     219             :     try {
     220        2683 :         net.openOutput(oc);
     221        5358 :         loader.processRoutes(begin, end, string2time(oc.getString("route-steps")), net, provider);
     222        2647 :         net.writeIntermodal(oc, provider.getIntermodalRouter());
     223             :         // end the processing
     224        2647 :         net.cleanup();
     225          36 :     } catch (ProcessError&) {
     226          36 :         net.cleanup();
     227          36 :         throw;
     228          36 :     }
     229        5330 : }
     230             : 
     231             : 
     232             : /* -------------------------------------------------------------------------
     233             :  * main
     234             :  * ----------------------------------------------------------------------- */
     235             : int
     236        4119 : main(int argc, char** argv) {
     237        4119 :     OptionsCont& oc = OptionsCont::getOptions();
     238        4119 :     oc.setApplicationDescription(TL("Shortest path router and DUE computer for the microscopic, multi-modal traffic simulation SUMO."));
     239        8238 :     oc.setApplicationName("duarouter", "Eclipse SUMO duarouter Version " VERSION_STRING);
     240             :     int ret = 0;
     241             :     RONet* net = nullptr;
     242             :     try {
     243        4119 :         XMLSubSys::init();
     244        4119 :         RODUAFrame::fillOptions();
     245        4119 :         OptionsIO::setArgs(argc, argv);
     246        4119 :         OptionsIO::getOptions();
     247        4115 :         if (oc.processMetaOptions(argc < 2)) {
     248         465 :             SystemFrame::close();
     249         465 :             return 0;
     250             :         }
     251        3650 :         SystemFrame::checkOptions(oc);
     252       10950 :         XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
     253             : #ifdef HAVE_FOX
     254        7300 :         if (oc.getInt("routing-threads") > 1) {
     255             :             // make the output aware of threading
     256             :             MsgHandler::setFactory(&MsgHandlerSynchronized::create);
     257             :         }
     258             : #endif
     259        3650 :         MsgHandler::initOutputOptions();
     260        3650 :         if (!RODUAFrame::checkOptions()) {
     261          41 :             throw ProcessError();
     262             :         }
     263        3609 :         RandHelper::initRandGlobal();
     264             :         // load data
     265        3609 :         ROLoader loader(oc, false, !oc.getBool("no-step-log"));
     266        3609 :         net = new RONet();
     267        3609 :         initNet(*net, loader, oc);
     268             :         // build routes
     269             :         try {
     270        3129 :             computeRoutes(*net, loader, oc);
     271         482 :         } catch (XERCES_CPP_NAMESPACE::SAXParseException& e) {
     272           0 :             WRITE_ERROR(toString(e.getLineNumber()));
     273             :             ret = 1;
     274           0 :         } catch (XERCES_CPP_NAMESPACE::SAXException& e) {
     275           0 :             WRITE_ERROR(StringUtils::transcode(e.getMessage()));
     276             :             ret = 1;
     277           0 :         }
     278        2647 :         if (MsgHandler::getErrorInstance()->wasInformed() || ret != 0) {
     279         172 :             throw ProcessError();
     280             :         }
     281        4788 :     } catch (const ProcessError& e) {
     282        2505 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     283         844 :             WRITE_ERROR(e.what());
     284             :         }
     285        1179 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     286             :         ret = 1;
     287             : #ifndef _DEBUG
     288        1179 :     } catch (const std::exception& e) {
     289           0 :         if (std::string(e.what()) != std::string("")) {
     290           0 :             WRITE_ERROR(e.what());
     291             :         }
     292           0 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     293             :         ret = 1;
     294           0 :     } catch (...) {
     295           0 :         MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
     296             :         ret = 1;
     297             : #endif
     298           0 :     }
     299        3654 :     delete net;
     300        3654 :     SystemFrame::close();
     301        3654 :     if (ret == 0) {
     302             :         std::cout << "Success." << std::endl;
     303             :     }
     304             :     return ret;
     305             : }
     306             : 
     307             : 
     308             : /****************************************************************************/

Generated by: LCOV version 1.14