Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 NLBuilder.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Mon, 9 Jul 2001
19 : ///
20 : // The main interface for loading a microsim
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <iostream>
25 : #include <vector>
26 : #include <string>
27 : #include <map>
28 :
29 : #include <utils/common/MsgHandler.h>
30 : #include <utils/common/StringTokenizer.h>
31 : #include <utils/common/SystemFrame.h>
32 : #include <utils/options/Option.h>
33 : #include <utils/options/OptionsCont.h>
34 : #include <utils/options/OptionsIO.h>
35 : #include <utils/common/StringUtils.h>
36 : #include <utils/common/FileHelpers.h>
37 : #include <utils/common/SysUtils.h>
38 : #include <utils/common/ToString.h>
39 : #include <utils/vehicle/SUMORouteLoaderControl.h>
40 : #include <utils/vehicle/SUMORouteLoader.h>
41 : #include <utils/xml/XMLSubSys.h>
42 : #ifdef HAVE_FOX
43 : #include <utils/foxtools/MsgHandlerSynchronized.h>
44 : #endif
45 : #include <libsumo/Helper.h>
46 : #include <mesosim/MEVehicleControl.h>
47 : #include <mesosim/METypeHandler.h>
48 : #include <microsim/MSVehicleControl.h>
49 : #include <microsim/MSVehicleTransfer.h>
50 : #include <microsim/MSNet.h>
51 : #include <microsim/devices/MSDevice.h>
52 : #include <microsim/devices/MSDevice_ToC.h>
53 : #include <microsim/devices/MSDevice_BTreceiver.h>
54 : #include <microsim/devices/MSDevice_FCDReplay.h>
55 : #include <microsim/MSEdgeControl.h>
56 : #include <microsim/MSGlobals.h>
57 : #include <microsim/output/MSDetectorControl.h>
58 : #include <microsim/MSFrame.h>
59 : #include <microsim/MSEdgeWeightsStorage.h>
60 : #include <microsim/MSStateHandler.h>
61 : #include <microsim/MSDriverState.h>
62 : #include <microsim/trigger/MSTriggeredRerouter.h>
63 : #include <traci-server/TraCIServer.h>
64 :
65 : #include "NLHandler.h"
66 : #include "NLNetShapeHandler.h"
67 : #include "NLEdgeControlBuilder.h"
68 : #include "NLJunctionControlBuilder.h"
69 : #include "NLDetectorBuilder.h"
70 : #include "NLTriggerBuilder.h"
71 : #include "NLBuilder.h"
72 :
73 :
74 : // ===========================================================================
75 : // method definitions
76 : // ===========================================================================
77 : // ---------------------------------------------------------------------------
78 : // NLBuilder::EdgeFloatTimeLineRetriever_EdgeWeight - methods
79 : // ---------------------------------------------------------------------------
80 : void
81 0 : NLBuilder::EdgeFloatTimeLineRetriever_EdgeEffort::addEdgeWeight(const std::string& id,
82 : double value, double begTime, double endTime) const {
83 0 : MSEdge* edge = MSEdge::dictionary(id);
84 0 : if (edge != nullptr) {
85 0 : myNet.getWeightsStorage().addEffort(edge, begTime, endTime, value);
86 : } else {
87 0 : WRITE_ERRORF(TL("Trying to set the effort for the unknown edge '%'."), id);
88 : }
89 0 : }
90 :
91 :
92 : // ---------------------------------------------------------------------------
93 : // NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
94 : // ---------------------------------------------------------------------------
95 : void
96 18 : NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id,
97 : double value, double begTime, double endTime) const {
98 18 : MSEdge* edge = MSEdge::dictionary(id);
99 18 : if (edge != nullptr) {
100 18 : myNet.getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
101 : } else {
102 0 : WRITE_ERRORF(TL("Trying to set the travel time for the unknown edge '%'."), id);
103 : }
104 18 : }
105 :
106 :
107 : // ---------------------------------------------------------------------------
108 : // NLBuilder - methods
109 : // ---------------------------------------------------------------------------
110 41234 : NLBuilder::NLBuilder(OptionsCont& oc,
111 : MSNet& net,
112 : NLEdgeControlBuilder& eb,
113 : NLJunctionControlBuilder& jb,
114 : NLDetectorBuilder& db,
115 41234 : NLHandler& xmlHandler)
116 41234 : : myOptions(oc), myEdgeBuilder(eb), myJunctionBuilder(jb),
117 41234 : myDetectorBuilder(db),
118 41234 : myNet(net), myXMLHandler(xmlHandler) {}
119 :
120 :
121 41234 : NLBuilder::~NLBuilder() {}
122 :
123 :
124 : bool
125 41234 : NLBuilder::build() {
126 : // try to build the net
127 82468 : if (!load("net-file", true)) {
128 : return false;
129 : }
130 40945 : if (myXMLHandler.networkVersion() == MMVersion(0, 0)) {
131 0 : throw ProcessError(TL("Invalid network, no network version declared."));
132 : }
133 : // check whether the loaded net agrees with the simulation options
134 85040 : if ((myOptions.getBool("no-internal-links") || myOptions.getBool("mesosim")) && myXMLHandler.haveSeenInternalEdge() && myXMLHandler.haveSeenDefaultLength()) {
135 6362 : WRITE_WARNING(TL("Network contains internal links which are ignored. Vehicles will 'jump' across junctions and thus underestimate route lengths and travel times."));
136 : }
137 40945 : buildNet();
138 81516 : if (myOptions.isSet("alternative-net-file")) {
139 0 : for (std::string fname : myOptions.getStringVector("alternative-net-file")) {
140 0 : const long before = PROGRESS_BEGIN_TIME_MESSAGE("Loading alternative net from '" + fname + "'");
141 0 : NLNetShapeHandler nsh(fname, myNet);
142 0 : if (!XMLSubSys::runParser(nsh, fname, true)) {
143 0 : WRITE_MESSAGE("Loading of alternative net failed.");
144 : return false;
145 : }
146 0 : nsh.sortInternalShapes();
147 0 : PROGRESS_TIME_MESSAGE(before);
148 0 : }
149 : }
150 : // @note on loading order constraints:
151 : // - additional-files before route-files and state-files due to referencing
152 : // - additional-files before weight-files since the latter might contain intermodal edge data and the intermodal net depends on the stops and public transport from the additionals
153 :
154 : bool stateBeginMismatch = false;
155 81516 : if (myOptions.isSet("load-state")) {
156 : // first, load only the time
157 258 : const SUMOTime stateTime = MSStateHandler::MSStateTimeHandler::getTime(myOptions.getString("load-state"));
158 504 : if (myOptions.isDefault("begin")) {
159 378 : myOptions.set("begin", time2string(stateTime));
160 189 : if (TraCIServer::getInstance() != nullptr) {
161 18 : TraCIServer::getInstance()->stateLoaded(stateTime);
162 : }
163 : } else {
164 126 : if (stateTime != string2time(myOptions.getString("begin"))) {
165 45 : WRITE_WARNINGF(TL("State was written at a different time=% than the begin time %!"), time2string(stateTime), myOptions.getString("begin"));
166 : stateBeginMismatch = true;
167 : }
168 : }
169 504 : myNet.setCurrentTimeStep(string2time(myOptions.getString("begin")));
170 : }
171 :
172 81504 : if (myOptions.getBool("junction-taz")) {
173 : // create a TAZ for every junction
174 1039 : const MSJunctionControl& junctions = myNet.getJunctionControl();
175 17251 : for (auto it = junctions.begin(); it != junctions.end(); it++) {
176 16212 : const std::string sinkID = it->first + "-sink";
177 16212 : const std::string sourceID = it->first + "-source";
178 16212 : if (MSEdge::dictionary(sinkID) == nullptr && MSEdge::dictionary(sourceID) == nullptr) {
179 : // sink must be built and added before source
180 32424 : MSEdge* sink = myEdgeBuilder.buildEdge(sinkID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
181 32424 : MSEdge* source = myEdgeBuilder.buildEdge(sourceID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
182 : sink->setOtherTazConnector(source);
183 : source->setOtherTazConnector(sink);
184 16212 : MSEdge::dictionary(sinkID, sink);
185 16212 : MSEdge::dictionary(sourceID, source);
186 16212 : sink->initialize(new std::vector<MSLane*>());
187 16212 : source->initialize(new std::vector<MSLane*>());
188 16212 : const MSJunction* junction = it->second;
189 96341 : for (const MSEdge* edge : junction->getIncoming()) {
190 80129 : if (!edge->isInternal()) {
191 33244 : const_cast<MSEdge*>(edge)->addSuccessor(sink);
192 : }
193 : }
194 96341 : for (const MSEdge* edge : junction->getOutgoing()) {
195 80129 : if (!edge->isInternal()) {
196 33244 : source->addSuccessor(const_cast<MSEdge*>(edge));
197 : }
198 : }
199 : } else {
200 0 : WRITE_WARNINGF(TL("A TAZ with id '%' already exists. Not building junction TAZ."), it->first)
201 : }
202 : }
203 : }
204 : // load meso edge types
205 : bool haveSeenMesoEdgeType = false;
206 40752 : if (MSGlobals::gUseMesoSim) {
207 11880 : if (myOptions.isSet("additional-files")) {
208 6488 : haveSeenMesoEdgeType = loadMesoEdgeTypes("additional-files");
209 : }
210 : // meso segment building must be delayed until meso edge types have been read from additional files
211 5940 : myNet.getEdgeControl().buildMesoSegments();
212 : }
213 : // load additional net elements (sources, detectors, ...)
214 81504 : if (myOptions.isSet("additional-files")) {
215 52424 : if (!load("additional-files")) {
216 753 : return false;
217 : }
218 : // load shapes with separate handler
219 25459 : NLShapeHandler sh("", myNet.getShapeContainer());
220 50918 : if (!ShapeHandler::loadFiles(myOptions.getStringVector("additional-files"), sh)) {
221 : return false;
222 : }
223 25459 : if (myXMLHandler.haveSeenAdditionalSpeedRestrictions()) {
224 65 : myNet.getEdgeControl().setAdditionalRestrictions();
225 : }
226 25459 : MSTriggeredRerouter::checkParkingRerouteConsistency();
227 : }
228 39999 : if (MSGlobals::gUseMesoSim) {
229 5765 : if (haveSeenMesoEdgeType || myXMLHandler.haveSeenTLSParams()) {
230 79 : for (MSTrafficLightLogic* tll : myNet.getTLSControl().getAllLogics()) {
231 36 : tll->initMesoTLSPenalties();
232 43 : }
233 : }
234 : }
235 : // init tls after all detectors have been loaded
236 39999 : myJunctionBuilder.postLoadInitialization();
237 : // declare meandata set by options
238 79958 : buildDefaultMeanData("edgedata-output", "DEFAULT_EDGEDATA", false);
239 79958 : buildDefaultMeanData("lanedata-output", "DEFAULT_LANEDATA", true);
240 :
241 39979 : if (stateBeginMismatch && myNet.getVehicleControl().getLoadedVehicleNo() > 0) {
242 4 : throw ProcessError(TL("Loading vehicles ahead of a state file is not supported. Correct --begin option or load vehicles with option --route-files"));
243 : }
244 :
245 : // load weights if wished
246 79954 : if (myOptions.isSet("weight-files")) {
247 22 : if (!myOptions.isUsableFileList("weight-files")) {
248 0 : return false;
249 : }
250 : // build and prepare the weights handler
251 : std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
252 : // travel time, first (always used)
253 11 : EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(myNet);
254 11 : retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", true, ttRetriever));
255 : // the measure to use, then
256 11 : EdgeFloatTimeLineRetriever_EdgeEffort eRetriever(myNet);
257 11 : std::string measure = myOptions.getString("weight-attribute");
258 22 : if (!myOptions.isDefault("weight-attribute")) {
259 0 : if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
260 : measure += "_perVeh";
261 : }
262 0 : retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(measure, true, eRetriever));
263 : }
264 : // set up handler
265 11 : SAXWeightsHandler handler(retrieverDefs, "");
266 : // start parsing; for each file in the list
267 22 : std::vector<std::string> files = myOptions.getStringVector("weight-files");
268 22 : for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
269 : // report about loading when wished
270 33 : WRITE_MESSAGEF(TL("Loading weights from '%'..."), *i);
271 : // parse the file
272 11 : if (!XMLSubSys::runParser(handler, *i)) {
273 : return false;
274 : }
275 : }
276 22 : }
277 : // load the previous state if wished
278 79954 : if (myOptions.isSet("load-state")) {
279 250 : const std::string& f = myOptions.getString("load-state");
280 750 : long before = PROGRESS_BEGIN_TIME_MESSAGE(TLF("Loading state from '%'", f));
281 250 : MSStateHandler h(f, string2time(myOptions.getString("load-state.offset")));
282 250 : XMLSubSys::runParser(h, f);
283 250 : if (MsgHandler::getErrorInstance()->wasInformed()) {
284 : return false;
285 : }
286 245 : PROGRESS_TIME_MESSAGE(before);
287 250 : }
288 : // routes from FCD files
289 39972 : MSDevice_FCDReplay::init();
290 : // load routes
291 79944 : if (myOptions.isSet("route-files")) {
292 64916 : if (string2time(myOptions.getString("route-steps")) <= 0) {
293 : // incremental loading is disabled. Load route files fully
294 0 : if (!load("route-files")) {
295 : return false;
296 : }
297 : } else {
298 : // message must come after additional-files have been loaded (but buildRouteLoaderControl was called earlier)
299 98314 : for (std::string file : myOptions.getStringVector("route-files")) {
300 100194 : WRITE_MESSAGE(TLF("Loading route-files incrementally from '%'", file));
301 : }
302 : }
303 : }
304 : // optionally switch off traffic lights
305 79944 : if (myOptions.getBool("tls.all-off")) {
306 114 : myNet.getTLSControl().switchOffAll();
307 : }
308 39972 : WRITE_MESSAGE(TL("Loading done."));
309 39972 : return true;
310 : }
311 :
312 :
313 : MSNet*
314 33770 : NLBuilder::init(const bool isLibsumo) {
315 33770 : OptionsCont& oc = OptionsCont::getOptions();
316 33770 : oc.clear();
317 33770 : MSFrame::fillOptions();
318 33770 : OptionsIO::getOptions();
319 33478 : if (oc.processMetaOptions(OptionsIO::getArgC() < 2)) {
320 387 : SystemFrame::close();
321 387 : return nullptr;
322 : }
323 33091 : SystemFrame::checkOptions(oc);
324 33091 : std::string validation = oc.getString("xml-validation");
325 34765 : std::string routeValidation = oc.getString("xml-validation.routes");
326 33091 : if (isLibsumo) {
327 1198 : if (oc.isDefault("xml-validation")) {
328 : validation = "never";
329 : }
330 1198 : if (oc.isDefault("xml-validation.routes")) {
331 : routeValidation = "never";
332 : }
333 : }
334 33091 : XMLSubSys::setValidation(validation, oc.getString("xml-validation.net"), routeValidation);
335 33091 : if (!MSFrame::checkOptions()) {
336 275 : throw ProcessError();
337 : }
338 : #ifdef HAVE_FOX
339 65616 : if (oc.getInt("threads") > 1) {
340 : // make the output aware of threading
341 : MsgHandler::setFactory(&MsgHandlerSynchronized::create);
342 : }
343 : #endif
344 32808 : MsgHandler::initOutputOptions();
345 32808 : initRandomness();
346 32808 : MSFrame::setMSGlobals(oc);
347 : MSVehicleControl* vc = nullptr;
348 32808 : if (MSGlobals::gUseMesoSim) {
349 3270 : vc = new MEVehicleControl();
350 : } else {
351 29538 : vc = new MSVehicleControl();
352 : }
353 32808 : MSNet* net = new MSNet(vc, new MSEventControl(), new MSEventControl(), new MSEventControl());
354 : // need to init TraCI-Server before loading routes to catch VehicleState::BUILT
355 34482 : TraCIServer::openSocket(std::map<int, TraCIServer::CmdExecutor>());
356 32802 : if (isLibsumo) {
357 599 : libsumo::Helper::registerStateListener();
358 : }
359 :
360 32802 : NLEdgeControlBuilder eb;
361 32802 : NLDetectorBuilder db(*net);
362 32802 : NLJunctionControlBuilder jb(*net, db);
363 32802 : NLTriggerBuilder tb;
364 32802 : NLHandler handler("", *net, db, tb, eb, jb);
365 32802 : tb.setHandler(&handler);
366 32802 : NLBuilder builder(oc, *net, eb, jb, db, handler);
367 32802 : MsgHandler::getErrorInstance()->clear();
368 32802 : MsgHandler::getWarningInstance()->clear();
369 32802 : MsgHandler::getMessageInstance()->clear();
370 32802 : if (builder.build()) {
371 : // preload the routes especially for TraCI
372 31814 : net->loadRoutes();
373 : return net;
374 : }
375 804 : delete net;
376 804 : throw ProcessError();
377 39727 : }
378 :
379 :
380 : void
381 41242 : NLBuilder::initRandomness() {
382 41242 : RandHelper::initRandGlobal();
383 41242 : RandHelper::initRandGlobal(MSRouteHandler::getParsingRNG());
384 41242 : RandHelper::initRandGlobal(MSDevice::getEquipmentRNG());
385 41242 : RandHelper::initRandGlobal(OUProcess::getRNG());
386 41242 : RandHelper::initRandGlobal(MSDevice_ToC::getResponseTimeRNG());
387 41242 : RandHelper::initRandGlobal(MSDevice_BTreceiver::getRecognitionRNG());
388 41242 : MSLane::initRNGs(OptionsCont::getOptions());
389 41242 : }
390 :
391 :
392 : void
393 40945 : NLBuilder::buildNet() {
394 : MSEdgeControl* edges = nullptr;
395 : MSJunctionControl* junctions = nullptr;
396 : SUMORouteLoaderControl* routeLoaders = nullptr;
397 : MSTLLogicControl* tlc = nullptr;
398 : std::vector<SUMOTime> stateDumpTimes;
399 : std::vector<std::string> stateDumpFiles;
400 : try {
401 40945 : MSFrame::buildStreams(); // ensure streams are ready for output during building
402 40903 : edges = myEdgeBuilder.build(myXMLHandler.networkVersion());
403 40893 : junctions = myJunctionBuilder.build();
404 40893 : junctions->postloadInitContainer();
405 1747737 : for (MSEdge* e : edges->getEdges()) {
406 1706848 : e->postLoadInitLaneChanger();
407 : }
408 40889 : routeLoaders = buildRouteLoaderControl(myOptions);
409 40768 : tlc = myJunctionBuilder.buildTLLogics();
410 81875 : for (std::string timeStr : myOptions.getStringVector("save-state.times")) {
411 339 : stateDumpTimes.push_back(string2time(timeStr));
412 : }
413 81536 : if (myOptions.isSet("save-state.files")) {
414 554 : stateDumpFiles = myOptions.getStringVector("save-state.files");
415 277 : if (stateDumpFiles.size() != stateDumpTimes.size()) {
416 0 : throw ProcessError(TL("Wrong number of state file names!"));
417 : }
418 : } else {
419 40491 : const std::string prefix = myOptions.getString("save-state.prefix");
420 80982 : const std::string suffix = myOptions.getString("save-state.suffix");
421 40507 : for (std::vector<SUMOTime>::iterator i = stateDumpTimes.begin(); i != stateDumpTimes.end(); ++i) {
422 16 : std::string timeStamp = time2string(*i);
423 : std::replace(timeStamp.begin(), timeStamp.end(), ':', '-');
424 32 : stateDumpFiles.push_back(prefix + "_" + timeStamp + suffix);
425 : }
426 : }
427 177 : } catch (ProcessError&) {
428 177 : MSEdge::clear();
429 177 : MSLane::clear();
430 177 : delete edges;
431 177 : delete junctions;
432 177 : delete routeLoaders;
433 177 : delete tlc;
434 177 : throw;
435 177 : }
436 : // if anthing goes wrong after this point, the net is responsible for cleaning up
437 40778 : myNet.closeBuilding(myOptions, edges, junctions, routeLoaders, tlc, stateDumpTimes, stateDumpFiles,
438 : myXMLHandler.haveSeenInternalEdge(),
439 : myXMLHandler.hasJunctionHigherSpeeds(),
440 40768 : myXMLHandler.networkVersion());
441 41132 : }
442 :
443 :
444 : bool
445 67446 : NLBuilder::load(const std::string& mmlWhat, const bool isNet) {
446 67446 : if (!myOptions.isUsableFileList(mmlWhat)) {
447 : return false;
448 : }
449 67434 : std::vector<std::string> files = myOptions.getStringVector(mmlWhat);
450 151178 : for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
451 254322 : const long before = PROGRESS_BEGIN_TIME_MESSAGE(TLF("Loading % from '%'", mmlWhat, *fileIt));
452 84774 : if (!XMLSubSys::runParser(myXMLHandler, *fileIt, isNet)) {
453 3090 : WRITE_MESSAGEF(TL("Loading of % failed."), mmlWhat);
454 : return false;
455 : }
456 83744 : PROGRESS_TIME_MESSAGE(before);
457 : }
458 : return true;
459 67434 : }
460 :
461 :
462 : bool
463 3244 : NLBuilder::loadMesoEdgeTypes(const std::string& mmlWhat) {
464 3244 : if (!myOptions.isUsableFileList(mmlWhat)) {
465 : return false;
466 : }
467 3244 : METypeHandler meTypeHandler("", myNet);
468 8169 : for (const std::string& file : myOptions.getStringVector(mmlWhat)) {
469 4925 : if (!XMLSubSys::runParser(meTypeHandler, file)) {
470 : continue;
471 : }
472 : }
473 : return meTypeHandler.haveSeenMesoEdgeType();
474 3244 : }
475 :
476 :
477 : SUMORouteLoaderControl*
478 41075 : NLBuilder::buildRouteLoaderControl(const OptionsCont& oc) {
479 : // build the loaders
480 41075 : SUMORouteLoaderControl* loaders = new SUMORouteLoaderControl(string2time(oc.getString("route-steps")));
481 : // check whether a list is existing
482 107365 : if (oc.isSet("route-files") && string2time(oc.getString("route-steps")) > 0) {
483 66290 : std::vector<std::string> files = oc.getStringVector("route-files");
484 67109 : for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
485 68170 : if (!FileHelpers::isReadable(*fileIt)) {
486 363 : throw ProcessError(TLF("The route file '%' is not accessible.", *fileIt));
487 : }
488 : }
489 : // open files for reading
490 66988 : for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
491 33964 : loaders->add(new SUMORouteLoader(new MSRouteHandler(*fileIt, false)));
492 : }
493 33145 : }
494 40954 : return loaders;
495 : }
496 :
497 :
498 : void
499 79958 : NLBuilder::buildDefaultMeanData(const std::string& optionName, const std::string& id, bool useLanes) {
500 79958 : if (OptionsCont::getOptions().isSet(optionName)) {
501 81 : if (useLanes && MSGlobals::gUseMesoSim && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
502 4 : WRITE_WARNING(TL("LaneData requested for mesoscopic simulation but --meso-lane-queue is not active. Falling back to edgeData."));
503 : useLanes = false;
504 : }
505 : try {
506 69 : SUMOTime begin = string2time(OptionsCont::getOptions().getString("begin"));
507 138 : myDetectorBuilder.createEdgeLaneMeanData(id, -1, begin, -1, "traffic", useLanes, "true",
508 69 : false, false, 0, 100000, 0, SUMO_const_haltingSpeed, "", "", std::vector<MSEdge*>(), AggregateType::NO,
509 138 : OptionsCont::getOptions().getString(optionName));
510 0 : } catch (InvalidArgument& e) {
511 0 : WRITE_ERROR(e.what());
512 0 : } catch (IOError& e) {
513 0 : WRITE_ERROR(e.what());
514 0 : }
515 : }
516 79958 : }
517 :
518 : /****************************************************************************/
|