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 357 : initNet(RONet& net, ROLoader& loader,
79 : const std::vector<double>& turnDefs) {
80 : // load the net
81 357 : ROJTREdgeBuilder builder;
82 357 : loader.loadNet(net, builder);
83 : // set the turn defaults
84 4191 : for (const auto& i : net.getEdgeMap()) {
85 4070 : static_cast<ROJTREdge*>(i.second)->setTurnDefaults(turnDefs);
86 : }
87 357 : }
88 :
89 : std::vector<double>
90 358 : getTurningDefaults(OptionsCont& oc) {
91 : std::vector<double> ret;
92 716 : std::vector<std::string> defs = oc.getStringVector("turn-defaults");
93 358 : 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 1465 : for (std::vector<std::string>::const_iterator i = defs.begin(); i != defs.end(); ++i) {
97 : try {
98 1108 : double val = StringUtils::toDouble(*i);
99 1108 : ret.push_back(val);
100 0 : } catch (NumberFormatException&) {
101 0 : throw ProcessError(TL("A turn default is not numeric."));
102 0 : }
103 : }
104 357 : return ret;
105 359 : }
106 :
107 :
108 : void
109 121 : loadJTRDefinitions(RONet& net, OptionsCont& oc) {
110 : // load the turning definitions (and possible sink definition)
111 242 : if (oc.isSet("turn-ratio-files")) {
112 38 : ROJTRTurnDefLoader loader(net);
113 76 : std::vector<std::string> ratio_files = oc.getStringVector("turn-ratio-files");
114 75 : for (std::vector<std::string>::const_iterator i = ratio_files.begin(); i != ratio_files.end(); ++i) {
115 40 : if (!XMLSubSys::runParser(loader, *i)) {
116 3 : throw ProcessError();
117 : }
118 : }
119 41 : }
120 223 : 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 18 : ROJTRTurnDefLoader loader(net);
123 36 : for (std::string fileOption : {
124 : "route-files", "additional-files"
125 54 : }) {
126 54 : for (std::string file : oc.getStringVector(fileOption)) {
127 18 : if (!XMLSubSys::runParser(loader, file)) {
128 0 : throw ProcessError();
129 : }
130 : }
131 : }
132 18 : }
133 :
134 118 : 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 236 : if (oc.isSet("sink-edges")) {
139 106 : std::vector<std::string> edges = oc.getStringVector("sink-edges");
140 109 : for (std::vector<std::string>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
141 : ROJTREdge* edge = static_cast<ROJTREdge*>(net.getEdge(*i));
142 56 : if (edge == nullptr) {
143 12 : throw ProcessError(TLF("The edge '%' declared as a sink is not known.", *i));
144 : }
145 : edge->setSink();
146 : }
147 53 : }
148 114 : }
149 :
150 :
151 : /**
152 : * Computes the routes saving them
153 : */
154 : void
155 114 : computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) {
156 : // initialise the loader
157 114 : loader.openRoutes(net);
158 : // prepare the output
159 112 : net.openOutput(oc);
160 : // build the router
161 333 : ROJTRRouter* router = new ROJTRRouter(oc.getBool("ignore-errors"), oc.getBool("accept-all-destinations"),
162 222 : (int)(((double) net.getEdgeNumber()) * OptionsCont::getOptions().getFloat("max-edges-factor")),
163 222 : oc.getBool("ignore-vclasses"),
164 222 : oc.getBool("allow-loops"),
165 777 : oc.getBool("discount-sources"));
166 : RORouteDef::setUsingJTRR();
167 111 : RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(),
168 111 : new ROIntermodalRouter(RONet::adaptIntermodalRouter, 0, 0, "dijkstra"), nullptr);
169 115 : const SUMOTime end = oc.isDefault("end") ? SUMOTime_MAX : string2time(oc.getString("end"));
170 222 : loader.processRoutes(string2time(oc.getString("begin")), end,
171 111 : string2time(oc.getString("route-steps")), net, provider);
172 111 : net.cleanup();
173 111 : }
174 :
175 : // -----------------------------------------------------------------------
176 : // main
177 : // -----------------------------------------------------------------------
178 :
179 : int
180 373 : main(int argc, char** argv) {
181 373 : OptionsCont& oc = OptionsCont::getOptions();
182 373 : oc.setApplicationDescription(TL("Router for the microscopic, multi-modal traffic simulation SUMO based on junction turning ratios."));
183 746 : 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 373 : XMLSubSys::init();
189 373 : ROJTRFrame::fillOptions();
190 373 : OptionsIO::setArgs(argc, argv);
191 373 : OptionsIO::getOptions();
192 372 : if (oc.processMetaOptions(argc < 2)) {
193 6 : SystemFrame::close();
194 6 : return 0;
195 : }
196 366 : SystemFrame::checkOptions(oc);
197 1355 : XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
198 366 : MsgHandler::initOutputOptions();
199 366 : if (!ROJTRFrame::checkOptions()) {
200 8 : throw ProcessError();
201 : }
202 358 : RandHelper::initRandGlobal();
203 358 : std::vector<double> defs = getTurningDefaults(oc);
204 : // load data
205 357 : ROLoader loader(oc, true, !oc.getBool("no-step-log"));
206 357 : net = new RONet();
207 357 : initNet(*net, loader, defs);
208 : try {
209 : // parse and set the turn defaults first
210 121 : loadJTRDefinitions(*net, oc);
211 : // build routes
212 114 : 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 111 : if (MsgHandler::getErrorInstance()->wasInformed()) {
221 1 : throw ProcessError();
222 : }
223 861 : } catch (const ProcessError& e) {
224 277 : if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
225 20 : WRITE_ERROR(e.what());
226 : }
227 257 : MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
228 : ret = 1;
229 : #ifndef _DEBUG
230 257 : } 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 367 : delete net;
242 367 : SystemFrame::close();
243 367 : if (ret == 0) {
244 : std::cout << "Success." << std::endl;
245 : }
246 : return ret;
247 : }
248 :
249 :
250 : /****************************************************************************/
|