1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file jtrrouter_main.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Michael Behrisch
14 /// @date Tue, 20 Jan 2004
15 /// @version $Id$
16 ///
17 // Main for JTRROUTER
18 /****************************************************************************/
19
20
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25
26 #ifdef HAVE_VERSION_H
27 #include <version.h>
28 #endif
29
30 #include <iostream>
31 #include <string>
32 #include <limits.h>
33 #include <ctime>
34 #include <set>
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/RandHelper.h>
43 #include <utils/common/StringTokenizer.h>
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/xml/XMLSubSys.h>
49 #include <router/ROFrame.h>
50 #include <router/ROLoader.h>
51 #include <router/RONet.h>
52 #include <router/RORouteDef.h>
53 #include "ROJTREdgeBuilder.h"
54 #include "ROJTRRouter.h"
55 #include "ROJTREdge.h"
56 #include "ROJTRTurnDefLoader.h"
57 #include "ROJTRFrame.h"
58
59
60 // ===========================================================================
61 // functions
62 // ===========================================================================
63 /* -------------------------------------------------------------------------
64 * data processing methods
65 * ----------------------------------------------------------------------- */
66 /**
67 * loads the net
68 * The net is in this meaning made up by the net itself and the dynamic
69 * weights which may be supplied in a separate file
70 */
71 void
initNet(RONet & net,ROLoader & loader,const std::vector<double> & turnDefs)72 initNet(RONet& net, ROLoader& loader,
73 const std::vector<double>& turnDefs) {
74 // load the net
75 ROJTREdgeBuilder builder;
76 loader.loadNet(net, builder);
77 // set the turn defaults
78 for (const auto& i : net.getEdgeMap()) {
79 static_cast<ROJTREdge*>(i.second)->setTurnDefaults(turnDefs);
80 }
81 }
82
83 std::vector<double>
getTurningDefaults(OptionsCont & oc)84 getTurningDefaults(OptionsCont& oc) {
85 std::vector<double> ret;
86 std::vector<std::string> defs = oc.getStringVector("turn-defaults");
87 if (defs.size() < 2) {
88 throw ProcessError("The defaults for turnings must be a tuple of at least two numbers divided by ','.");
89 }
90 for (std::vector<std::string>::const_iterator i = defs.begin(); i != defs.end(); ++i) {
91 try {
92 double val = StringUtils::toDouble(*i);
93 ret.push_back(val);
94 } catch (NumberFormatException&) {
95 throw ProcessError("A turn default is not numeric.");
96 }
97 }
98 return ret;
99 }
100
101
102 void
loadJTRDefinitions(RONet & net,OptionsCont & oc)103 loadJTRDefinitions(RONet& net, OptionsCont& oc) {
104 // load the turning definitions (and possible sink definition)
105 if (oc.isSet("turn-ratio-files")) {
106 ROJTRTurnDefLoader loader(net);
107 std::vector<std::string> ratio_files = oc.getStringVector("turn-ratio-files");
108 for (std::vector<std::string>::const_iterator i = ratio_files.begin(); i != ratio_files.end(); ++i) {
109 if (!XMLSubSys::runParser(loader, *i)) {
110 throw ProcessError();
111 }
112 }
113 }
114 if (MsgHandler::getErrorInstance()->wasInformed() && oc.getBool("ignore-errors")) {
115 MsgHandler::getErrorInstance()->clear();
116 }
117 // parse sink edges specified at the input/within the configuration
118 if (oc.isSet("sink-edges")) {
119 std::vector<std::string> edges = oc.getStringVector("sink-edges");
120 for (std::vector<std::string>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
121 ROJTREdge* edge = static_cast<ROJTREdge*>(net.getEdge(*i));
122 if (edge == nullptr) {
123 throw ProcessError("The edge '" + *i + "' declared as a sink is not known.");
124 }
125 edge->setSink();
126 }
127 }
128 }
129
130
131 /**
132 * Computes the routes saving them
133 */
134 void
computeRoutes(RONet & net,ROLoader & loader,OptionsCont & oc)135 computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) {
136 // initialise the loader
137 loader.openRoutes(net);
138 // prepare the output
139 net.openOutput(oc);
140 // build the router
141 ROJTRRouter* router = new ROJTRRouter(oc.getBool("ignore-errors"), oc.getBool("accept-all-destinations"),
142 (int)(((double) net.getEdgeNumber()) * OptionsCont::getOptions().getFloat("max-edges-factor")),
143 oc.getBool("ignore-vclasses"), oc.getBool("allow-loops"));
144 RORouteDef::setUsingJTRR();
145 RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(),
146 new ROIntermodalRouter(RONet::adaptIntermodalRouter, 0, "dijkstra"));
147 loader.processRoutes(string2time(oc.getString("begin")), string2time(oc.getString("end")),
148 string2time(oc.getString("route-steps")), net, provider);
149 net.cleanup();
150 }
151
152
153 /* -------------------------------------------------------------------------
154 * main
155 * ----------------------------------------------------------------------- */
156 int
main(int argc,char ** argv)157 main(int argc, char** argv) {
158 OptionsCont& oc = OptionsCont::getOptions();
159 // give some application descriptions
160 oc.setApplicationDescription("Router for the microscopic, multi-modal traffic simulation SUMO based on junction turning ratios.");
161 oc.setApplicationName("jtrrouter", "Eclipse SUMO jtrrouter Version " VERSION_STRING);
162 int ret = 0;
163 RONet* net = nullptr;
164 try {
165 // initialise the application system (messaging, xml, options)
166 XMLSubSys::init();
167 ROJTRFrame::fillOptions();
168 OptionsIO::setArgs(argc, argv);
169 OptionsIO::getOptions();
170 if (oc.processMetaOptions(argc < 2)) {
171 SystemFrame::close();
172 return 0;
173 }
174 XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
175 MsgHandler::initOutputOptions();
176 if (!(ROJTRFrame::checkOptions() && SystemFrame::checkOptions())) {
177 throw ProcessError();
178 }
179 RandHelper::initRandGlobal();
180 std::vector<double> defs = getTurningDefaults(oc);
181 // load data
182 ROLoader loader(oc, true, !oc.getBool("no-step-log"));
183 net = new RONet();
184 initNet(*net, loader, defs);
185 try {
186 // parse and set the turn defaults first
187 loadJTRDefinitions(*net, oc);
188 // build routes
189 computeRoutes(*net, loader, oc);
190 } catch (XERCES_CPP_NAMESPACE::SAXParseException& e) {
191 WRITE_ERROR(toString(e.getLineNumber()));
192 ret = 1;
193 } catch (XERCES_CPP_NAMESPACE::SAXException& e) {
194 WRITE_ERROR(StringUtils::transcode(e.getMessage()));
195 ret = 1;
196 }
197 if (MsgHandler::getErrorInstance()->wasInformed()) {
198 throw ProcessError();
199 }
200 } catch (const ProcessError& e) {
201 if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
202 WRITE_ERROR(e.what());
203 }
204 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
205 ret = 1;
206 #ifndef _DEBUG
207 } catch (const std::exception& e) {
208 if (std::string(e.what()) != std::string("")) {
209 WRITE_ERROR(e.what());
210 }
211 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
212 ret = 1;
213 } catch (...) {
214 MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
215 ret = 1;
216 #endif
217 }
218 delete net;
219 SystemFrame::close();
220 if (ret == 0) {
221 std::cout << "Success." << std::endl;
222 }
223 return ret;
224 }
225
226
227 /****************************************************************************/
228