LCOV - code coverage report
Current view: top level - src/dfrouter - dfrouter_main.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 119 147 81.0 %
Date: 2024-09-16 15:39:55 Functions: 4 4 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    dfrouter_main.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Eric Nicolay
      17             : /// @author  Jakob Erdmann
      18             : /// @author  Sascha Krieg
      19             : /// @author  Michael Behrisch
      20             : /// @author  Laura Bieker
      21             : /// @date    Thu, 16.03.2006
      22             : ///
      23             : // Main for the DFROUTER
      24             : /****************************************************************************/
      25             : #include <config.h>
      26             : 
      27             : #ifdef HAVE_VERSION_H
      28             : #include <version.h>
      29             : #endif
      30             : 
      31             : #include <iostream>
      32             : #include <string>
      33             : #include <limits.h>
      34             : #include <ctime>
      35             : #include <xercesc/sax/SAXException.hpp>
      36             : #include <xercesc/sax/SAXParseException.hpp>
      37             : #include <utils/common/StringUtils.h>
      38             : #include <utils/common/MsgHandler.h>
      39             : #include <utils/common/UtilExceptions.h>
      40             : #include <utils/common/SystemFrame.h>
      41             : #include <utils/common/ToString.h>
      42             : #include <utils/common/FileHelpers.h>
      43             : #include <utils/options/Option.h>
      44             : #include <utils/options/OptionsCont.h>
      45             : #include <utils/options/OptionsIO.h>
      46             : #include <utils/iodevices/OutputDevice.h>
      47             : #include <utils/xml/XMLSubSys.h>
      48             : #include <router/ROLoader.h>
      49             : #include <router/RONet.h>
      50             : #include "RODFEdgeBuilder.h"
      51             : #include "RODFFrame.h"
      52             : #include "RODFNet.h"
      53             : #include "RODFEdge.h"
      54             : #include "RODFDetector.h"
      55             : #include "RODFDetectorHandler.h"
      56             : #include "RODFRouteCont.h"
      57             : #include "RODFDetectorFlow.h"
      58             : #include "RODFDetFlowLoader.h"
      59             : 
      60             : 
      61             : // ===========================================================================
      62             : // functions
      63             : // ===========================================================================
      64             : /* -------------------------------------------------------------------------
      65             :  * data processing methods
      66             :  * ----------------------------------------------------------------------- */
      67             : void
      68         244 : readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
      69         488 :     if (!oc.isSet("detector-files")) {
      70           2 :         throw ProcessError(TL("No detector file given (use --detector-files <FILE>)."));
      71             :     }
      72             :     // read definitions stored in XML-format
      73         486 :     std::vector<std::string> files = oc.getStringVector("detector-files");
      74         467 :     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
      75         488 :         if (!FileHelpers::isReadable(*fileIt)) {
      76          22 :             throw ProcessError(TLF("Could not open detector file '%'", *fileIt));
      77             :         }
      78         478 :         PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
      79         239 :         RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
      80         239 :         if (XMLSubSys::runParser(handler, *fileIt)) {
      81         224 :             PROGRESS_DONE_MESSAGE();
      82             :         } else {
      83          15 :             PROGRESS_FAILED_MESSAGE();
      84          15 :             throw ProcessError();
      85             :         }
      86         239 :     }
      87         223 :     if (detectors.getDetectors().empty()) {
      88           2 :         throw ProcessError(TL("No detectors found."));
      89             :     }
      90         243 : }
      91             : 
      92             : 
      93             : void
      94         222 : readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) {
      95         444 :     if (!oc.isSet("measure-files")) {
      96             :         // ok, not given, return an empty container
      97         108 :         return;
      98             :     }
      99             :     // check whether the file exists
     100         228 :     std::vector<std::string> files = oc.getStringVector("measure-files");
     101         220 :     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
     102         230 :         if (!FileHelpers::isReadable(*fileIt)) {
     103          22 :             throw ProcessError(TLF("The measure-file '%' can not be opened.", *fileIt));
     104             :         }
     105             :         // parse
     106         220 :         PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
     107         330 :         RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")),
     108         440 :                               string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor")));
     109         110 :         dfl.read(*fileIt);
     110         106 :         PROGRESS_DONE_MESSAGE();
     111         110 :     }
     112         114 : }
     113             : 
     114             : 
     115             : void
     116         213 : startComputation(RODFNet* optNet, RODFDetectorFlows& flows, RODFDetectorCon& detectors, OptionsCont& oc) {
     117         426 :     if (oc.getBool("print-absolute-flows")) {
     118           0 :         flows.printAbsolute();
     119             :     }
     120             : 
     121             :     // if a network was loaded... (mode1)
     122         213 :     if (optNet != nullptr) {
     123         426 :         if (oc.getBool("remove-empty-detectors")) {
     124          14 :             PROGRESS_BEGIN_MESSAGE(TL("Removing empty detectors"));
     125           7 :             optNet->removeEmptyDetectors(detectors, flows);
     126           7 :             PROGRESS_DONE_MESSAGE();
     127         412 :         } else  if (oc.getBool("report-empty-detectors")) {
     128          14 :             PROGRESS_BEGIN_MESSAGE(TL("Scanning for empty detectors"));
     129           7 :             optNet->reportEmptyDetectors(detectors, flows);
     130           7 :             PROGRESS_DONE_MESSAGE();
     131             :         }
     132             :         // compute the detector types (optionally)
     133         218 :         if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
     134         416 :             optNet->computeTypes(detectors, oc.getBool("strict-sources"));
     135             :         }
     136         213 :         std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
     137         222 :         for (; i != detectors.getDetectors().end(); ++i) {
     138         221 :             if ((*i)->getType() == SOURCE_DETECTOR) {
     139             :                 break;
     140             :             }
     141             :         }
     142         214 :         if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
     143           2 :             throw ProcessError(TL("No source detectors found."));
     144             :         }
     145             :         // compute routes between the detectors (optionally)
     146         212 :         if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
     147         424 :             PROGRESS_BEGIN_MESSAGE(TL("Computing routes"));
     148         424 :             optNet->buildRoutes(detectors,
     149         424 :                                 oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
     150         424 :                                 !oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
     151         212 :             PROGRESS_DONE_MESSAGE();
     152             :         }
     153             :     }
     154             : 
     155             :     // check
     156             :     // whether the detectors are valid
     157         212 :     if (!detectors.detectorsHaveCompleteTypes()) {
     158           0 :         throw ProcessError(TL("The detector types are not defined; use in combination with a network"));
     159             :     }
     160             :     // whether the detectors have routes
     161         212 :     if (!detectors.detectorsHaveRoutes()) {
     162           0 :         throw ProcessError(TL("The emitters have no routes; use in combination with a network"));
     163             :     }
     164             : 
     165             :     // save the detectors if wished
     166         424 :     if (oc.isSet("detector-output")) {
     167          36 :         detectors.save(oc.getString("detector-output"));
     168             :     }
     169             :     // save their positions as POIs if wished
     170         422 :     if (oc.isSet("detectors-poi-output")) {
     171          11 :         detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
     172             :     }
     173             : 
     174             :     // save the routes file if it was changed or it's wished
     175         521 :     if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
     176         218 :         detectors.saveRoutes(oc.getString("routes-output"));
     177             :     }
     178             : 
     179             :     // guess flows if wished
     180         418 :     if (oc.getBool("guess-empty-flows")) {
     181           0 :         optNet->buildDetectorDependencies(detectors);
     182           0 :         detectors.guessEmptyFlows(flows);
     183             :     }
     184             : 
     185         418 :     const SUMOTime begin = string2time(oc.getString("begin"));
     186         418 :     const SUMOTime end = string2time(oc.getString("end"));
     187         418 :     const SUMOTime step = string2time(oc.getString("time-step"));
     188             : 
     189             :     // save emitters if wished
     190         314 :     if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
     191         104 :         optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!!
     192         208 :         if (oc.getBool("revalidate-flows")) {
     193           0 :             PROGRESS_BEGIN_MESSAGE(TL("Rechecking loaded flows"));
     194           0 :             optNet->revalidateFlows(detectors, flows, begin, end, step);
     195           0 :             PROGRESS_DONE_MESSAGE();
     196             :         }
     197         208 :         if (oc.isSet("emitters-output")) {
     198         208 :             PROGRESS_BEGIN_MESSAGE(TL("Writing emitters"));
     199         418 :             detectors.writeEmitters(oc.getString("emitters-output"), flows,
     200             :                                     begin, end, step,
     201             :                                     *optNet,
     202         208 :                                     oc.getBool("calibrator-output"),
     203         208 :                                     oc.getBool("include-unused-routes"),
     204             :                                     oc.getFloat("scale"),
     205             : //                                    oc.getInt("max-search-depth"),
     206         104 :                                     oc.getBool("emissions-only"));
     207         102 :             PROGRESS_DONE_MESSAGE();
     208             :         }
     209         204 :         if (oc.isSet("emitters-poi-output")) {
     210           0 :             PROGRESS_BEGIN_MESSAGE(TL("Writing emitter pois"));
     211           0 :             detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
     212           0 :             PROGRESS_DONE_MESSAGE();
     213             :         }
     214             :     }
     215             :     // save end speed trigger if wished
     216         414 :     if (oc.isSet("variable-speed-sign-output")) {
     217           0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing speed triggers"));
     218           0 :         detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
     219             :                                     begin, end, step);
     220           0 :         PROGRESS_DONE_MESSAGE();
     221             :     }
     222             :     // save checking detectors if wished
     223         414 :     if (oc.isSet("validation-output")) {
     224           0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing validation detectors"));
     225           0 :         detectors.writeValidationDetectors(oc.getString("validation-output"),
     226           0 :                                            oc.getBool("validation-output.add-sources"), true, true); // !!!
     227           0 :         PROGRESS_DONE_MESSAGE();
     228             :     }
     229             :     // build global rerouter on end if wished
     230         414 :     if (oc.isSet("end-reroute-output")) {
     231           0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing highway end rerouter"));
     232           0 :         detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!!
     233           0 :         PROGRESS_DONE_MESSAGE();
     234             :     }
     235             :     /*
     236             :        // save the insertion definitions
     237             :        if(oc.isSet("flow-definitions")) {
     238             :            buildVehicleEmissions(oc.getString("flow-definitions"));
     239             :        }
     240             :     */
     241             :     //
     242         207 : }
     243             : 
     244             : 
     245             : /* -------------------------------------------------------------------------
     246             :  * main
     247             :  * ----------------------------------------------------------------------- */
     248             : int
     249         730 : main(int argc, char** argv) {
     250         730 :     OptionsCont& oc = OptionsCont::getOptions();
     251         730 :     oc.setApplicationDescription(TL("Builds vehicle routes for SUMO using detector values."));
     252        1460 :     oc.setApplicationName("dfrouter", "Eclipse SUMO dfrouter Version " VERSION_STRING);
     253             :     int ret = 0;
     254             :     RODFNet* net = nullptr;
     255             :     RODFDetectorCon* detectors = nullptr;
     256             :     RODFDetectorFlows* flows = nullptr;
     257             :     try {
     258             :         // initialise the application system (messaging, xml, options)
     259         730 :         XMLSubSys::init();
     260         730 :         RODFFrame::fillOptions();
     261         730 :         OptionsIO::setArgs(argc, argv);
     262         730 :         OptionsIO::getOptions();
     263         720 :         if (oc.processMetaOptions(argc < 2)) {
     264           6 :             SystemFrame::close();
     265           6 :             return 0;
     266             :         }
     267         714 :         SystemFrame::checkOptions(oc);
     268        2142 :         XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), "never");
     269         714 :         MsgHandler::initOutputOptions();
     270         714 :         if (!RODFFrame::checkOptions()) {
     271           0 :             throw ProcessError();
     272             :         }
     273         714 :         RandHelper::initRandGlobal();
     274             :         // load data
     275         714 :         ROLoader loader(oc, false, !oc.getBool("no-step-log"));
     276         714 :         net = new RODFNet(oc.getBool("highway-mode"));
     277         714 :         RODFEdgeBuilder builder;
     278         714 :         loader.loadNet(*net, builder);
     279         244 :         net->buildApproachList();
     280             :         // load detectors
     281         244 :         detectors = new RODFDetectorCon();
     282         244 :         readDetectors(*detectors, oc, net);
     283             :         // load detector values
     284         444 :         flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
     285         444 :                                       string2time(oc.getString("time-step")));
     286         222 :         readDetectorFlows(*flows, oc, *detectors);
     287             :         // build routes
     288         213 :         startComputation(net, *flows, *detectors, oc);
     289        1738 :     } catch (const ProcessError& e) {
     290         619 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     291          68 :             WRITE_ERROR(e.what());
     292             :         }
     293         517 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     294             :         ret = 1;
     295             : #ifndef _DEBUG
     296         517 :     } catch (const std::exception& e) {
     297           0 :         if (std::string(e.what()) != std::string("")) {
     298           0 :             WRITE_ERROR(e.what());
     299             :         }
     300           0 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     301             :         ret = 1;
     302           0 :     } catch (...) {
     303           0 :         MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
     304             :         ret = 1;
     305             : #endif
     306           0 :     }
     307         724 :     delete net;
     308         724 :     delete flows;
     309         724 :     delete detectors;
     310         724 :     SystemFrame::close();
     311         724 :     if (ret == 0) {
     312             :         std::cout << "Success." << std::endl;
     313             :     }
     314             :     return ret;
     315             : }
     316             : 
     317             : 
     318             : /****************************************************************************/

Generated by: LCOV version 1.14