LCOV - code coverage report
Current view: top level - src/dfrouter - dfrouter_main.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 80.8 % 146 118
Test Date: 2024-12-21 15:45:41 Functions: 100.0 % 4 4

            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          200 : readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
      69          400 :     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          398 :     std::vector<std::string> files = oc.getStringVector("detector-files");
      74          379 :     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
      75          400 :         if (!FileHelpers::isReadable(*fileIt)) {
      76           15 :             throw ProcessError(TLF("Could not open detector file '%'", *fileIt));
      77              :         }
      78          585 :         PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
      79          195 :         RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
      80          195 :         if (XMLSubSys::runParser(handler, *fileIt)) {
      81          180 :             PROGRESS_DONE_MESSAGE();
      82              :         } else {
      83           15 :             PROGRESS_FAILED_MESSAGE();
      84           15 :             throw ProcessError();
      85              :         }
      86          195 :     }
      87          179 :     if (detectors.getDetectors().empty()) {
      88            2 :         throw ProcessError(TL("No detectors found."));
      89              :     }
      90          199 : }
      91              : 
      92              : 
      93              : void
      94          178 : readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) {
      95          356 :     if (!oc.isSet("measure-files")) {
      96              :         // ok, not given, return an empty container
      97           64 :         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           15 :             throw ProcessError(TLF("The measure-file '%' can not be opened.", *fileIt));
     104              :         }
     105              :         // parse
     106          330 :         PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
     107          440 :         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          169 : startComputation(RODFNet* optNet, RODFDetectorFlows& flows, RODFDetectorCon& detectors, OptionsCont& oc) {
     117          338 :     if (oc.getBool("print-absolute-flows")) {
     118            0 :         flows.printAbsolute();
     119              :     }
     120              : 
     121          338 :     if (oc.getBool("remove-empty-detectors")) {
     122           14 :         PROGRESS_BEGIN_MESSAGE(TL("Removing empty detectors"));
     123            7 :         optNet->removeEmptyDetectors(detectors, flows);
     124            7 :         PROGRESS_DONE_MESSAGE();
     125          324 :     } else  if (oc.getBool("report-empty-detectors")) {
     126           14 :         PROGRESS_BEGIN_MESSAGE(TL("Scanning for empty detectors"));
     127            7 :         optNet->reportEmptyDetectors(detectors, flows);
     128            7 :         PROGRESS_DONE_MESSAGE();
     129              :     }
     130              :     // compute the detector types (optionally)
     131          174 :     if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
     132          328 :         optNet->computeTypes(detectors, oc.getBool("strict-sources"));
     133              :     }
     134          169 :     std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
     135          178 :     for (; i != detectors.getDetectors().end(); ++i) {
     136          177 :         if ((*i)->getType() == SOURCE_DETECTOR) {
     137              :             break;
     138              :         }
     139              :     }
     140          170 :     if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
     141            2 :         throw ProcessError(TL("No source detectors found."));
     142              :     }
     143              :     // compute routes between the detectors (optionally)
     144          168 :     if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
     145          336 :         PROGRESS_BEGIN_MESSAGE(TL("Computing routes"));
     146          336 :         optNet->buildRoutes(detectors,
     147          336 :                             oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
     148          336 :                             !oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
     149          168 :         PROGRESS_DONE_MESSAGE();
     150              :     }
     151              : 
     152              :     // check
     153              :     // whether the detectors are valid
     154          168 :     if (!detectors.detectorsHaveCompleteTypes()) {
     155            0 :         throw ProcessError(TL("The detector types are not defined; use in combination with a network"));
     156              :     }
     157              :     // whether the detectors have routes
     158          168 :     if (!detectors.detectorsHaveRoutes()) {
     159            0 :         throw ProcessError(TL("The emitters have no routes; use in combination with a network"));
     160              :     }
     161              : 
     162              :     // save the detectors if wished
     163          336 :     if (oc.isSet("detector-output")) {
     164           35 :         detectors.save(oc.getString("detector-output"));
     165              :     }
     166              :     // save their positions as POIs if wished
     167          334 :     if (oc.isSet("detectors-poi-output")) {
     168            7 :         detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
     169              :     }
     170              : 
     171              :     // save the routes file if it was changed or it's wished
     172          332 :     if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
     173          217 :         detectors.saveRoutes(oc.getString("routes-output"));
     174              :     }
     175              : 
     176              :     // guess flows if wished
     177          330 :     if (oc.getBool("guess-empty-flows")) {
     178            0 :         optNet->buildDetectorDependencies(detectors);
     179            0 :         detectors.guessEmptyFlows(flows);
     180              :     }
     181              : 
     182          165 :     const SUMOTime begin = string2time(oc.getString("begin"));
     183          165 :     const SUMOTime end = string2time(oc.getString("end"));
     184          165 :     const SUMOTime step = string2time(oc.getString("time-step"));
     185              : 
     186              :     // save emitters if wished
     187          226 :     if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
     188          104 :         optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!!
     189          208 :         if (oc.getBool("revalidate-flows")) {
     190            0 :             PROGRESS_BEGIN_MESSAGE(TL("Rechecking loaded flows"));
     191            0 :             optNet->revalidateFlows(detectors, flows, begin, end, step);
     192            0 :             PROGRESS_DONE_MESSAGE();
     193              :         }
     194          208 :         if (oc.isSet("emitters-output")) {
     195          208 :             PROGRESS_BEGIN_MESSAGE(TL("Writing emitters"));
     196          416 :             detectors.writeEmitters(oc.getString("emitters-output"), flows,
     197              :                                     begin, end, step,
     198              :                                     *optNet,
     199          208 :                                     oc.getBool("calibrator-output"),
     200          208 :                                     oc.getBool("include-unused-routes"),
     201              :                                     oc.getFloat("scale"),
     202              : //                                    oc.getInt("max-search-depth"),
     203          104 :                                     oc.getBool("emissions-only"));
     204          102 :             PROGRESS_DONE_MESSAGE();
     205              :         }
     206          204 :         if (oc.isSet("emitters-poi-output")) {
     207            0 :             PROGRESS_BEGIN_MESSAGE(TL("Writing emitter pois"));
     208            0 :             detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
     209            0 :             PROGRESS_DONE_MESSAGE();
     210              :         }
     211              :     }
     212              :     // save end speed trigger if wished
     213          326 :     if (oc.isSet("variable-speed-sign-output")) {
     214            0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing speed triggers"));
     215            0 :         detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
     216              :                                     begin, end, step);
     217            0 :         PROGRESS_DONE_MESSAGE();
     218              :     }
     219              :     // save checking detectors if wished
     220          326 :     if (oc.isSet("validation-output")) {
     221            0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing validation detectors"));
     222            0 :         detectors.writeValidationDetectors(oc.getString("validation-output"),
     223            0 :                                            oc.getBool("validation-output.add-sources"), true, true); // !!!
     224            0 :         PROGRESS_DONE_MESSAGE();
     225              :     }
     226              :     // build global rerouter on end if wished
     227          326 :     if (oc.isSet("end-reroute-output")) {
     228            0 :         PROGRESS_BEGIN_MESSAGE(TL("Writing highway end rerouter"));
     229            0 :         detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!!
     230            0 :         PROGRESS_DONE_MESSAGE();
     231              :     }
     232              :     /*
     233              :        // save the insertion definitions
     234              :        if(oc.isSet("flow-definitions")) {
     235              :            buildVehicleEmissions(oc.getString("flow-definitions"));
     236              :        }
     237              :     */
     238              :     //
     239          163 : }
     240              : 
     241              : 
     242              : /* -------------------------------------------------------------------------
     243              :  * main
     244              :  * ----------------------------------------------------------------------- */
     245              : int
     246          452 : main(int argc, char** argv) {
     247          452 :     OptionsCont& oc = OptionsCont::getOptions();
     248          452 :     oc.setApplicationDescription(TL("Builds vehicle routes for SUMO using detector values."));
     249          904 :     oc.setApplicationName("dfrouter", "Eclipse SUMO dfrouter Version " VERSION_STRING);
     250              :     int ret = 0;
     251              :     RODFNet* net = nullptr;
     252              :     RODFDetectorCon* detectors = nullptr;
     253              :     RODFDetectorFlows* flows = nullptr;
     254              :     try {
     255              :         // initialise the application system (messaging, xml, options)
     256          452 :         XMLSubSys::init();
     257          452 :         RODFFrame::fillOptions();
     258          452 :         OptionsIO::setArgs(argc, argv);
     259          452 :         OptionsIO::getOptions();
     260          442 :         if (oc.processMetaOptions(argc < 2)) {
     261            6 :             SystemFrame::close();
     262            6 :             return 0;
     263              :         }
     264          436 :         SystemFrame::checkOptions(oc);
     265         1308 :         XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), "never");
     266          436 :         MsgHandler::initOutputOptions();
     267          436 :         if (!RODFFrame::checkOptions()) {
     268            0 :             throw ProcessError();
     269              :         }
     270          436 :         RandHelper::initRandGlobal();
     271              :         // load data
     272          719 :         ROLoader loader(oc, false, !oc.getBool("no-step-log"));
     273          436 :         net = new RODFNet(oc.getBool("highway-mode"));
     274          436 :         RODFEdgeBuilder builder;
     275          436 :         loader.loadNet(*net, builder);
     276          200 :         net->buildApproachList();
     277              :         // load detectors
     278          200 :         detectors = new RODFDetectorCon();
     279          200 :         readDetectors(*detectors, oc, net);
     280              :         // load detector values
     281          712 :         flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
     282          534 :                                       string2time(oc.getString("time-step")));
     283          178 :         readDetectorFlows(*flows, oc, *detectors);
     284              :         // build routes
     285          169 :         startComputation(net, *flows, *detectors, oc);
     286          992 :     } catch (const ProcessError& e) {
     287          351 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     288           68 :             WRITE_ERROR(e.what());
     289              :         }
     290          283 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     291              :         ret = 1;
     292              : #ifndef _DEBUG
     293          283 :     } catch (const std::exception& e) {
     294            0 :         if (std::string(e.what()) != std::string("")) {
     295            0 :             WRITE_ERROR(e.what());
     296              :         }
     297            0 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     298              :         ret = 1;
     299            0 :     } catch (...) {
     300            0 :         MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
     301              :         ret = 1;
     302              : #endif
     303            0 :     }
     304          446 :     delete net;
     305          446 :     delete flows;
     306          446 :     delete detectors;
     307          446 :     SystemFrame::close();
     308          446 :     if (ret == 0) {
     309              :         std::cout << "Success." << std::endl;
     310              :     }
     311              :     return ret;
     312              : }
     313              : 
     314              : 
     315              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1