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 jtrrouter_main.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Tue, 20 Jan 2004
19 : ///
20 : // Main for JTRROUTER
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 <set>
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/ToString.h>
40 : #include <utils/common/RandHelper.h>
41 : #include <utils/common/StringTokenizer.h>
42 : #include <utils/iodevices/OutputDevice.h>
43 : #include <utils/options/Option.h>
44 : #include <utils/options/OptionsCont.h>
45 : #include <utils/options/OptionsIO.h>
46 : #include <utils/xml/XMLSubSys.h>
47 : #include <router/ROFrame.h>
48 : #include <router/ROLoader.h>
49 : #include <router/RONet.h>
50 : #include <router/RORouteDef.h>
51 : #include "ROJTREdgeBuilder.h"
52 : #include "ROJTRRouter.h"
53 : #include "ROJTREdge.h"
54 : #include "ROJTRTurnDefLoader.h"
55 : #include "ROJTRFrame.h"
56 :
57 : // ===========================================================================
58 : // method declaration
59 : // ===========================================================================
60 :
61 : void initNet(RONet& net, ROLoader& loader, const std::vector<double>& turnDefs);
62 : std::vector<double> getTurningDefaults(OptionsCont& oc);
63 : void loadJTRDefinitions(RONet& net, OptionsCont& oc);
64 : void computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc);
65 :
66 : // ===========================================================================
67 : // method implementation
68 : // ===========================================================================
69 : /* -------------------------------------------------------------------------
70 : * data processing methods
71 : * ----------------------------------------------------------------------- */
72 : /**
73 : * loads the net
74 : * The net is in this meaning made up by the net itself and the dynamic
75 : * weights which may be supplied in a separate file
76 : */
77 : void
78 642 : initNet(RONet& net, ROLoader& loader,
79 : const std::vector<double>& turnDefs) {
80 : // load the net
81 642 : ROJTREdgeBuilder builder;
82 642 : loader.loadNet(net, builder);
83 : // set the turn defaults
84 7098 : for (const auto& i : net.getEdgeMap()) {
85 6926 : static_cast<ROJTREdge*>(i.second)->setTurnDefaults(turnDefs);
86 : }
87 642 : }
88 :
89 : std::vector<double>
90 643 : getTurningDefaults(OptionsCont& oc) {
91 : std::vector<double> ret;
92 1287 : std::vector<std::string> defs = oc.getStringVector("turn-defaults");
93 643 : if (defs.size() < 2) {
94 2 : throw ProcessError(TL("The defaults for turnings must be a tuple of at least two numbers divided by ','."));
95 : }
96 2605 : for (std::vector<std::string>::const_iterator i = defs.begin(); i != defs.end(); ++i) {
97 : try {
98 1963 : double val = StringUtils::toDouble(*i);
99 1963 : ret.push_back(val);
100 0 : } catch (NumberFormatException&) {
101 0 : throw ProcessError(TL("A turn default is not numeric."));
102 0 : }
103 : }
104 642 : return ret;
105 643 : }
106 :
107 :
108 : void
109 172 : loadJTRDefinitions(RONet& net, OptionsCont& oc) {
110 : // load the turning definitions (and possible sink definition)
111 344 : if (oc.isSet("turn-ratio-files")) {
112 44 : ROJTRTurnDefLoader loader(net);
113 88 : std::vector<std::string> ratio_files = oc.getStringVector("turn-ratio-files");
114 87 : for (std::vector<std::string>::const_iterator i = ratio_files.begin(); i != ratio_files.end(); ++i) {
115 46 : if (!XMLSubSys::runParser(loader, *i)) {
116 3 : throw ProcessError();
117 : }
118 : }
119 47 : }
120 496 : if (oc.getBool("sources-are-sinks") || oc.getBool("discount-sources")) {
121 : // load all route-files and additional files to discover sink edges and flow discount values
122 21 : ROJTRTurnDefLoader loader(net);
123 42 : for (std::string fileOption : {
124 : "route-files", "additional-files"
125 63 : }) {
126 63 : for (std::string file : oc.getStringVector(fileOption)) {
127 21 : if (!XMLSubSys::runParser(loader, file)) {
128 0 : throw ProcessError();
129 : }
130 : }
131 : }
132 21 : }
133 :
134 169 : if (MsgHandler::getErrorInstance()->wasInformed() && oc.getBool("ignore-errors")) {
135 0 : MsgHandler::getErrorInstance()->clear();
136 : }
137 : // parse sink edges specified at the input/within the configuration
138 338 : if (oc.isSet("sink-edges")) {
139 110 : std::vector<std::string> edges = oc.getStringVector("sink-edges");
140 113 : for (std::vector<std::string>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
141 : ROJTREdge* edge = static_cast<ROJTREdge*>(net.getEdge(*i));
142 58 : if (edge == nullptr) {
143 17 : throw ProcessError(TLF("The edge '%' declared as a sink is not known.", *i));
144 : }
145 : edge->setSink();
146 : }
147 55 : }
148 165 : }
149 :
150 :
151 : /**
152 : * Computes the routes saving them
153 : */
154 : void
155 165 : computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) {
156 : // initialise the loader
157 165 : loader.openRoutes(net);
158 : // prepare the output
159 163 : net.openOutput(oc);
160 : // build the router
161 324 : ROJTRRouter* router = new ROJTRRouter(oc.getBool("ignore-errors"), oc.getBool("accept-all-destinations"),
162 324 : (int)(((double) net.getEdgeNumber()) * OptionsCont::getOptions().getFloat("max-edges-factor")),
163 324 : oc.getBool("ignore-vclasses"),
164 324 : oc.getBool("allow-loops"),
165 324 : oc.getBool("discount-sources"));
166 : RORouteDef::setUsingJTRR();
167 162 : RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(),
168 162 : new ROIntermodalRouter(RONet::adaptIntermodalRouter, 0, 0, "dijkstra"), nullptr);
169 166 : const SUMOTime end = oc.isDefault("end") ? SUMOTime_MAX : string2time(oc.getString("end"));
170 324 : loader.processRoutes(string2time(oc.getString("begin")), end,
171 324 : string2time(oc.getString("route-steps")), net, provider);
172 162 : net.cleanup();
173 162 : }
174 :
175 : // -----------------------------------------------------------------------
176 : // main
177 : // -----------------------------------------------------------------------
178 :
179 : int
180 658 : main(int argc, char** argv) {
181 658 : OptionsCont& oc = OptionsCont::getOptions();
182 658 : oc.setApplicationDescription(TL("Router for the microscopic, multi-modal traffic simulation SUMO based on junction turning ratios."));
183 1316 : oc.setApplicationName("jtrrouter", "Eclipse SUMO jtrrouter Version " VERSION_STRING);
184 : int ret = 0;
185 : RONet* net = nullptr;
186 : try {
187 : // initialise the application system (messaging, xml, options)
188 658 : XMLSubSys::init();
189 658 : ROJTRFrame::fillOptions();
190 658 : OptionsIO::setArgs(argc, argv);
191 658 : OptionsIO::getOptions();
192 657 : if (oc.processMetaOptions(argc < 2)) {
193 6 : SystemFrame::close();
194 6 : return 0;
195 : }
196 651 : SystemFrame::checkOptions(oc);
197 1953 : XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
198 651 : MsgHandler::initOutputOptions();
199 651 : if (!ROJTRFrame::checkOptions()) {
200 8 : throw ProcessError();
201 : }
202 643 : RandHelper::initRandGlobal();
203 643 : std::vector<double> defs = getTurningDefaults(oc);
204 : // load data
205 1123 : ROLoader loader(oc, true, !oc.getBool("no-step-log"));
206 642 : net = new RONet();
207 642 : initNet(*net, loader, defs);
208 : try {
209 : // parse and set the turn defaults first
210 172 : loadJTRDefinitions(*net, oc);
211 : // build routes
212 165 : computeRoutes(*net, loader, oc);
213 10 : } catch (XERCES_CPP_NAMESPACE::SAXParseException& e) {
214 0 : WRITE_ERROR(toString(e.getLineNumber()));
215 : ret = 1;
216 0 : } catch (XERCES_CPP_NAMESPACE::SAXException& e) {
217 0 : WRITE_ERROR(StringUtils::transcode(e.getMessage()));
218 : ret = 1;
219 0 : }
220 162 : if (MsgHandler::getErrorInstance()->wasInformed()) {
221 1 : throw ProcessError();
222 : }
223 1133 : } catch (const ProcessError& e) {
224 521 : if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
225 20 : WRITE_ERROR(e.what());
226 : }
227 491 : MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
228 : ret = 1;
229 : #ifndef _DEBUG
230 491 : } catch (const std::exception& e) {
231 0 : if (std::string(e.what()) != std::string("")) {
232 0 : WRITE_ERROR(e.what());
233 : }
234 0 : MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
235 : ret = 1;
236 0 : } catch (...) {
237 0 : MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
238 : ret = 1;
239 : #endif
240 0 : }
241 652 : delete net;
242 652 : SystemFrame::close();
243 652 : if (ret == 0) {
244 : std::cout << "Success." << std::endl;
245 : }
246 : return ret;
247 : }
248 :
249 :
250 : /****************************************************************************/
|