Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
RONet.cpp
Go to the documentation of this file.
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/****************************************************************************/
20// The router's network representation
21/****************************************************************************/
22#include <config.h>
23
24#include <algorithm>
35#include "ROEdge.h"
36#include "ROLane.h"
37#include "RONode.h"
38#include "ROPerson.h"
39#include "RORoute.h"
40#include "RORouteDef.h"
41#include "ROVehicle.h"
43#include "RONet.h"
44
45
46// ===========================================================================
47// static member definitions
48// ===========================================================================
49RONet* RONet::myInstance = nullptr;
50
51
52// ===========================================================================
53// method definitions
54// ===========================================================================
55RONet*
57 if (myInstance != nullptr) {
58 return myInstance;
59 }
60 throw ProcessError(TL("A network was not yet constructed."));
61}
62
63
65 myVehicleTypes(), myDefaultVTypeMayBeDeleted(true),
66 myDefaultPedTypeMayBeDeleted(true),
67 myDefaultBikeTypeMayBeDeleted(true),
68 myDefaultTaxiTypeMayBeDeleted(true),
69 myDefaultRailTypeMayBeDeleted(true),
70 myHaveActiveFlows(true),
71 myRoutesOutput(nullptr), myRouteAlternativesOutput(nullptr), myTypesOutput(nullptr),
72 myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
73 myHavePermissions(false),
74 myNumInternalEdges(0),
75 myErrorHandler(OptionsCont::getOptions().exists("ignore-errors")
76 && OptionsCont::getOptions().getBool("ignore-errors") ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
77 myKeepVTypeDist(OptionsCont::getOptions().exists("keep-vtype-distributions")
78 && OptionsCont::getOptions().getBool("keep-vtype-distributions")),
79 myDoPTRouting(!OptionsCont::getOptions().exists("ptline-routing")
80 || OptionsCont::getOptions().getBool("ptline-routing")),
81 myHasBidiEdges(false) {
82 if (myInstance != nullptr) {
83 throw ProcessError(TL("A network was already constructed."));
84 }
86 type->onlyReferenced = true;
87 myVehicleTypes.add(type->id, type);
88
90 defPedType->onlyReferenced = true;
92 myVehicleTypes.add(defPedType->id, defPedType);
93
95 defBikeType->onlyReferenced = true;
97 myVehicleTypes.add(defBikeType->id, defBikeType);
98
100 defTaxiType->onlyReferenced = true;
102 myVehicleTypes.add(defTaxiType->id, defTaxiType);
103
105 defRailType->onlyReferenced = true;
107 myVehicleTypes.add(defRailType->id, defRailType);
108
109 myInstance = this;
110}
111
112
114 for (const auto& routables : myRoutables) {
115 for (RORoutable* const r : routables.second) {
116 const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
117 // delete routes and the vehicle
118 if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
119 if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
120 delete veh->getRouteDefinition();
121 }
122 }
123 delete r;
124 }
125 }
126 for (const RORoutable* const r : myPTVehicles) {
127 const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
128 // delete routes and the vehicle
129 if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
130 if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
131 delete veh->getRouteDefinition();
132 }
133 }
134 delete r;
135 }
136 myRoutables.clear();
137 for (const auto& vTypeDist : myVTypeDistDict) {
138 delete vTypeDist.second;
139 }
140}
141
142
143void
144RONet::addRestriction(const std::string& id, const SUMOVehicleClass svc, const double speed) {
145 myRestrictions[id][svc] = speed;
146}
147
148
149const std::map<SUMOVehicleClass, double>*
150RONet::getRestrictions(const std::string& id) const {
151 std::map<std::string, std::map<SUMOVehicleClass, double> >::const_iterator i = myRestrictions.find(id);
152 if (i == myRestrictions.end()) {
153 return nullptr;
154 }
155 return &i->second;
156}
157
158
159bool
161 if (!myEdges.add(edge->getID(), edge)) {
162 WRITE_ERRORF(TL("The edge '%' occurs at least twice."), edge->getID());
163 delete edge;
164 return false;
165 }
166 if (edge->isInternal()) {
168 }
169 return true;
170}
171
172
173bool
174RONet::addDistrict(const std::string id, ROEdge* source, ROEdge* sink) {
175 if (myDistricts.count(id) > 0) {
176 WRITE_ERRORF(TL("The TAZ '%' occurs at least twice."), id);
177 delete source;
178 delete sink;
179 return false;
180 }
182 if (!addEdge(sink)) {
183 return false;
184 }
186 if (!addEdge(source)) {
187 return false;
188 }
189 sink->setOtherTazConnector(source);
190 source->setOtherTazConnector(sink);
191 myDistricts[id] = std::make_pair(std::vector<std::string>(), std::vector<std::string>());
192 return true;
193}
194
195
196bool
197RONet::addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource) {
198 if (myDistricts.count(tazID) == 0) {
199 WRITE_ERRORF(TL("The TAZ '%' is unknown."), tazID);
200 return false;
201 }
202 ROEdge* edge = getEdge(edgeID);
203 if (edge == nullptr) {
204 WRITE_ERRORF(TL("The edge '%' for TAZ '%' is unknown."), edgeID, tazID);
205 return false;
206 }
207 if (isSource) {
208 getEdge(tazID + "-source")->addSuccessor(edge);
209 myDistricts[tazID].first.push_back(edgeID);
210 } else {
211 edge->addSuccessor(getEdge(tazID + "-sink"));
212 myDistricts[tazID].second.push_back(edgeID);
213 }
214 return true;
215}
216
217
218void
220 for (auto item : myNodes) {
221 const std::string tazID = item.first;
222 if (myDistricts.count(tazID) != 0) {
223 WRITE_WARNINGF(TL("A TAZ with id '%' already exists. Not building junction TAZ."), tazID);
224 continue;
225 }
226 const std::string sourceID = tazID + "-source";
227 const std::string sinkID = tazID + "-sink";
228 // sink must be added before source
229 ROEdge* sink = eb.buildEdge(sinkID, nullptr, nullptr, 0);
230 ROEdge* source = eb.buildEdge(sourceID, nullptr, nullptr, 0);
231 sink->setOtherTazConnector(source);
232 source->setOtherTazConnector(sink);
233 if (!addDistrict(tazID, source, sink)) {
234 continue;
235 }
236 auto& district = myDistricts[tazID];
237 const RONode* junction = item.second;
238 for (const ROEdge* edge : junction->getIncoming()) {
239 if (!edge->isInternal()) {
240 const_cast<ROEdge*>(edge)->addSuccessor(sink);
241 district.second.push_back(edge->getID());
242 }
243 }
244 for (const ROEdge* edge : junction->getOutgoing()) {
245 if (!edge->isInternal()) {
246 source->addSuccessor(const_cast<ROEdge*>(edge));
247 district.first.push_back(edge->getID());
248 }
249 }
250 }
251}
252
253
254void
255RONet::setBidiEdges(const std::map<ROEdge*, std::string>& bidiMap) {
256 for (const auto& item : bidiMap) {
257 ROEdge* bidi = myEdges.get(item.second);
258 if (bidi == nullptr) {
259 WRITE_ERRORF(TL("The bidi edge '%' is not known."), item.second);
260 }
261 item.first->setBidiEdge(bidi);
262 myHasBidiEdges = true;
263 }
264}
265
266
267void
269 if (!myNodes.add(node->getID(), node)) {
270 WRITE_ERRORF(TL("The node '%' occurs at least twice."), node->getID());
271 delete node;
272 }
273}
274
275
276void
277RONet::addStoppingPlace(const std::string& id, const SumoXMLTag category, SUMOVehicleParameter::Stop* stop) {
278 if (!myStoppingPlaces[category == SUMO_TAG_TRAIN_STOP ? SUMO_TAG_BUS_STOP : category].add(id, stop)) {
279 WRITE_ERRORF(TL("The % '%' occurs at least twice."), toString(category), id);
280 delete stop;
281 }
282}
283
284
285bool
287 return myRoutes.add(def->getID(), def);
288}
289
290
291void
293 if (options.isSet("output-file") && options.getString("output-file") != "") {
294 myRoutesOutput = &OutputDevice::getDevice(options.getString("output-file"));
295 if (myRoutesOutput->isNull()) {
296 myRoutesOutput = nullptr;
297 } else {
299 myRoutesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
300 }
301 }
302 if (options.exists("alternatives-output") && options.isSet("alternatives-output")
303 && !(options.exists("write-trips") && options.getBool("write-trips"))) {
304 myRouteAlternativesOutput = &OutputDevice::getDevice(options.getString("alternatives-output"));
307 } else {
309 myRouteAlternativesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
310 }
311 }
312 if (options.isSet("vtype-output")) {
313 myTypesOutput = &OutputDevice::getDevice(options.getString("vtype-output"));
315 myTypesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
316 }
317}
318
319
320void
322 if (options.exists("intermodal-network-output") && options.isSet("intermodal-network-output")) {
323 OutputDevice::createDeviceByOption("intermodal-network-output", "intermodal");
324 router.writeNetwork(OutputDevice::getDevice(options.getString("intermodal-network-output")));
325 }
326 if (options.exists("intermodal-weight-output") && options.isSet("intermodal-weight-output")) {
327 OutputDevice::createDeviceByOption("intermodal-weight-output", "weights", "meandata_file.xsd");
328 OutputDevice& dev = OutputDevice::getDeviceByOption("intermodal-weight-output");
330 dev.writeAttr(SUMO_ATTR_ID, "intermodalweights");
333 router.writeWeights(dev);
334 dev.closeTag();
335 }
336}
337
338
339void
341 // end writing
342 if (myRoutesOutput != nullptr) {
344 }
345 // only if opened
346 if (myRouteAlternativesOutput != nullptr) {
348 }
349 // only if opened
350 if (myTypesOutput != nullptr) {
352 }
354#ifdef HAVE_FOX
355 if (myThreadPool.size() > 0) {
356 myThreadPool.clear();
357 }
358#endif
359}
360
361
362
364RONet::getVehicleTypeSecure(const std::string& id) {
365 // check whether the type was already known
367 if (id == DEFAULT_VTYPE_ID) {
369 } else if (id == DEFAULT_PEDTYPE_ID) {
371 } else if (id == DEFAULT_BIKETYPE_ID) {
373 } else if (id == DEFAULT_TAXITYPE_ID) {
375 } else if (id == DEFAULT_RAILTYPE_ID) {
377 }
378 if (type != nullptr) {
379 return type;
380 }
381 VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
382 if (it2 != myVTypeDistDict.end()) {
383 return it2->second->get();
384 }
385 if (id == "") {
386 // ok, no vehicle type or an unknown type was given within the user input
387 // return the default type
390 }
391 return type;
392}
393
394
395bool
396RONet::checkVType(const std::string& id) {
397 if (id == DEFAULT_VTYPE_ID) {
401 } else {
402 return false;
403 }
404 } else if (id == DEFAULT_PEDTYPE_ID) {
408 } else {
409 return false;
410 }
411 } else if (id == DEFAULT_BIKETYPE_ID) {
415 } else {
416 return false;
417 }
418 } else if (id == DEFAULT_TAXITYPE_ID) {
422 } else {
423 return false;
424 }
425 } else if (id == DEFAULT_RAILTYPE_ID) {
429 } else {
430 return false;
431 }
432 } else {
433 if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
434 return false;
435 }
436 }
437 return true;
438}
439
440
441bool
443 if (checkVType(type->id)) {
444 myVehicleTypes.add(type->id, type);
445 } else {
446 WRITE_ERRORF(TL("The vehicle type '%' occurs at least twice."), type->id);
447 delete type;
448 return false;
449 }
450 return true;
451}
452
453
454bool
455RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
456 if (checkVType(id)) {
457 myVTypeDistDict[id] = vehTypeDistribution;
458 return true;
459 }
460 delete vehTypeDistribution;
461 return false;
462}
463
464
465bool
466RONet::addVehicle(const std::string& id, ROVehicle* veh) {
467 if (myVehIDs.find(id) == myVehIDs.end()) {
469
470 if (veh->isPublicTransport()) {
471 if (!veh->isPartOfFlow()) {
472 myPTVehicles.push_back(veh);
473 }
474 if (!myDoPTRouting) {
475 return true;
476 }
477 }
478 myRoutables[veh->getDepart()].push_back(veh);
479 return true;
480 }
481 WRITE_ERRORF(TL("Another vehicle with the id '%' exists."), id);
482 delete veh;
483 return false;
484}
485
486
487bool
488RONet::knowsVehicle(const std::string& id) const {
489 return myVehIDs.find(id) != myVehIDs.end();
490}
491
493RONet::getDeparture(const std::string& vehID) const {
494 auto it = myVehIDs.find(vehID);
495 if (it != myVehIDs.end()) {
496 return it->second;
497 } else {
498 throw ProcessError(TLF("Requesting departure time for unknown vehicle '%'", vehID));
499 }
500}
501
502
503bool
504RONet::addFlow(SUMOVehicleParameter* flow, const bool randomize) {
505 if (randomize && flow->repetitionOffset >= 0) {
506 myDepartures[flow->id].reserve(flow->repetitionNumber);
507 for (int i = 0; i < flow->repetitionNumber; ++i) {
508 myDepartures[flow->id].push_back(flow->depart + RandHelper::rand(flow->repetitionNumber * flow->repetitionOffset));
509 }
510 std::sort(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
511 std::reverse(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
512 }
513 const bool added = myFlows.add(flow->id, flow);
514 if (added) {
515 myHaveActiveFlows = true;
516 }
517 return added;
518}
519
520
521bool
523 if (myPersonIDs.count(person->getID()) == 0) {
524 myPersonIDs.insert(person->getID());
525 myRoutables[person->getDepart()].push_back(person);
526 return true;
527 }
528 WRITE_ERRORF(TL("Another person with the id '%' exists."), person->getID());
529 return false;
530}
531
532
533void
534RONet::addContainer(const SUMOTime depart, const std::string desc) {
535 myContainers.insert(std::pair<const SUMOTime, const std::string>(depart, desc));
536}
537
538
539void
541 myHaveActiveFlows = false;
542 for (const auto& i : myFlows) {
543 SUMOVehicleParameter* const pars = i.second;
544 if (pars->line != "" && !myDoPTRouting) {
545 continue;
546 }
547 if (pars->repetitionProbability > 0) {
548 if (pars->repetitionEnd > pars->depart && pars->repetitionsDone < pars->repetitionNumber) {
549 myHaveActiveFlows = true;
550 }
551 const SUMOTime origDepart = pars->depart;
552 while (pars->depart < time && pars->repetitionsDone < pars->repetitionNumber) {
553 if (pars->repetitionEnd <= pars->depart) {
554 break;
555 }
556 // only call rand if all other conditions are met
557 if (RandHelper::rand() < (pars->repetitionProbability * TS)) {
558 SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
559 newPars->id = pars->id + "." + toString(pars->repetitionsDone);
560 newPars->depart = pars->depart;
561 for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
562 if (stop->until >= 0) {
563 stop->until += pars->depart - origDepart;
564 }
565 }
566 pars->repetitionsDone++;
567 // try to build the vehicle
569 if (type == nullptr) {
571 } else if (!myKeepVTypeDist) {
572 // fix the type id in case we used a distribution
573 newPars->vtypeid = type->id;
574 }
575 const SUMOTime stopOffset = pars->routeid[0] == '!' ? pars->depart - origDepart : pars->depart;
576 RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
577 ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
578 addVehicle(newPars->id, veh);
579 delete newPars;
580 }
581 pars->depart += DELTA_T;
582 }
583 } else {
584 SUMOTime depart = static_cast<SUMOTime>(pars->depart + pars->repetitionTotalOffset);
585 while (pars->repetitionsDone < pars->repetitionNumber && pars->repetitionEnd >= depart) {
586 myHaveActiveFlows = true;
587 depart = static_cast<SUMOTime>(pars->depart + pars->repetitionTotalOffset);
588 if (myDepartures.find(pars->id) != myDepartures.end()) {
589 depart = myDepartures[pars->id].back();
590 }
591 if (depart >= time + DELTA_T) {
592 break;
593 }
594 if (myDepartures.find(pars->id) != myDepartures.end()) {
595 myDepartures[pars->id].pop_back();
596 }
597 SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
598 newPars->id = pars->id + "." + toString(pars->repetitionsDone);
599 newPars->depart = depart;
600 for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
601 if (stop->until >= 0) {
602 stop->until += depart - pars->depart;
603 }
604 }
605 pars->incrementFlow(1);
606 // try to build the vehicle
608 if (type == nullptr) {
610 } else {
611 // fix the type id in case we used a distribution
612 newPars->vtypeid = type->id;
613 }
614 const SUMOTime stopOffset = pars->routeid[0] == '!' ? depart - pars->depart : depart;
615 RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
616 ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
617 addVehicle(newPars->id, veh);
618 delete newPars;
619 }
620 }
621 }
622}
623
624
625void
626RONet::createBulkRouteRequests(const RORouterProvider& provider, const SUMOTime time, const bool removeLoops) {
627 std::map<const int, std::vector<RORoutable*> > bulkVehs;
628 for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
629 if (i->first >= time) {
630 break;
631 }
632 for (RORoutable* const routable : i->second) {
633 const ROEdge* const depEdge = routable->getDepartEdge();
634 bulkVehs[depEdge->getNumericalID()].push_back(routable);
635 RORoutable* const first = bulkVehs[depEdge->getNumericalID()].front();
636 if (first->getMaxSpeed() != routable->getMaxSpeed()) {
637 WRITE_WARNINGF(TL("Bulking different maximum speeds ('%' and '%') may lead to suboptimal routes."), first->getID(), routable->getID());
638 }
639 if (first->getVClass() != routable->getVClass()) {
640 WRITE_WARNINGF(TL("Bulking different vehicle classes ('%' and '%') may lead to invalid routes."), first->getID(), routable->getID());
641 }
642 }
643 }
644#ifdef HAVE_FOX
645 int workerIndex = 0;
646#endif
647 for (std::map<const int, std::vector<RORoutable*> >::const_iterator i = bulkVehs.begin(); i != bulkVehs.end(); ++i) {
648#ifdef HAVE_FOX
649 if (myThreadPool.size() > 0) {
650 bool bulk = true;
651 for (RORoutable* const r : i->second) {
652 myThreadPool.add(new RoutingTask(r, removeLoops, myErrorHandler), workerIndex);
653 if (bulk) {
654 myThreadPool.add(new BulkmodeTask(true), workerIndex);
655 bulk = false;
656 }
657 }
658 myThreadPool.add(new BulkmodeTask(false), workerIndex);
659 workerIndex++;
660 if (workerIndex == (int)myThreadPool.size()) {
661 workerIndex = 0;
662 }
663 continue;
664 }
665#endif
666 for (RORoutable* const r : i->second) {
667 r->computeRoute(provider, removeLoops, myErrorHandler);
668 provider.setBulkMode(true);
669 }
670 provider.setBulkMode(false);
671 }
672}
673
674
677 SUMOTime time) {
678 MsgHandler* mh = (options.getBool("ignore-errors") ?
680 if (myHaveActiveFlows) {
681 checkFlows(time, mh);
682 }
683 SUMOTime lastTime = -1;
684 const bool removeLoops = options.getBool("remove-loops");
685#ifdef HAVE_FOX
686 const int maxNumThreads = options.getInt("routing-threads");
687#endif
688 if (myRoutables.size() != 0) {
689 if (options.getBool("bulk-routing")) {
690#ifdef HAVE_FOX
691 while ((int)myThreadPool.size() < maxNumThreads) {
692 new WorkerThread(myThreadPool, provider);
693 }
694#endif
695 createBulkRouteRequests(provider, time, removeLoops);
696 } else {
697 for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
698 if (i->first >= time) {
699 break;
700 }
701 for (RORoutable* const routable : i->second) {
702#ifdef HAVE_FOX
703 // add task
704 if (maxNumThreads > 0) {
705 const int numThreads = (int)myThreadPool.size();
706 if (numThreads == 0) {
707 // This is the very first routing. Since at least the CHRouter needs initialization
708 // before it gets cloned, we do not do this in parallel
709 routable->computeRoute(provider, removeLoops, myErrorHandler);
710 new WorkerThread(myThreadPool, provider);
711 } else {
712 // add thread if necessary
713 if (numThreads < maxNumThreads && myThreadPool.isFull()) {
714 new WorkerThread(myThreadPool, provider);
715 }
716 myThreadPool.add(new RoutingTask(routable, removeLoops, myErrorHandler));
717 }
718 continue;
719 }
720#endif
721 routable->computeRoute(provider, removeLoops, myErrorHandler);
722 }
723 }
724 }
725#ifdef HAVE_FOX
726 myThreadPool.waitAll();
727#endif
728 }
729 const double scale = options.exists("scale-suffix") ? options.getFloat("scale") : 1;
730 // write all vehicles (and additional structures)
731 while (myRoutables.size() != 0 || myContainers.size() != 0) {
732 // get the next vehicle, person or container
733 RoutablesMap::iterator routables = myRoutables.begin();
734 const SUMOTime routableTime = routables == myRoutables.end() ? SUMOTime_MAX : routables->first;
735 ContainerMap::iterator container = myContainers.begin();
736 const SUMOTime containerTime = container == myContainers.end() ? SUMOTime_MAX : container->first;
737 // check whether it shall not yet be computed
738 if (routableTime >= time && containerTime >= time) {
739 lastTime = MIN2(routableTime, containerTime);
740 break;
741 }
742 const SUMOTime minTime = MIN2(routableTime, containerTime);
743 if (routableTime == minTime) {
744 // check whether to print the output
745 if (lastTime != routableTime && lastTime != -1) {
746 // report writing progress
747 if (options.getInt("stats-period") >= 0 && ((int)routableTime % options.getInt("stats-period")) == 0) {
748 WRITE_MESSAGE("Read: " + toString(myVehIDs.size()) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
749 }
750 }
751 lastTime = routableTime;
752 for (const RORoutable* const r : routables->second) {
753 // ok, check whether it has been routed
754 if (r->getRoutingSuccess()) {
755 // write the route
756 int quota = getScalingQuota(scale, myWrittenRouteNo);
757 r->write(myRoutesOutput, myRouteAlternativesOutput, myTypesOutput, options, quota);
759 } else {
761 }
762 // we need to keep individual public transport vehicles but not the flows
763 if (!r->isPublicTransport() || r->isPartOfFlow()) {
764 // delete routes and the vehicle
765 const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
766 if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
767 if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
768 delete veh->getRouteDefinition();
769 }
770 }
771 delete r;
772 }
773 }
774 myRoutables.erase(routables);
775 }
776 if (containerTime == minTime) {
777 myRoutesOutput->writePreformattedTag(container->second);
778 if (myRouteAlternativesOutput != nullptr) {
780 }
781 myContainers.erase(container);
782 }
783 }
784 return lastTime;
785}
786
787
788bool
790 return myRoutables.size() > 0 || (myFlows.size() > 0 && myHaveActiveFlows) || myContainers.size() > 0;
791}
792
793
794int
796 return myEdges.size();
797}
798
799
800int
804
805
806ROEdge*
807RONet::getEdgeForLaneID(const std::string& laneID) const {
809}
810
811
812ROLane*
813RONet::getLane(const std::string& laneID) const {
814 int laneIndex = SUMOXMLDefinitions::getIndexFromLane(laneID);
815 return getEdgeForLaneID(laneID)->getLanes()[laneIndex];
816}
817
818
819void
821 double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
822 for (const auto& stopType : myInstance->myStoppingPlaces) {
823 // add access to all stopping places
824 const SumoXMLTag element = stopType.first;
825 for (const auto& stop : stopType.second) {
826 router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(stop.second->lane),
827 stop.second->startPos, stop.second->endPos, 0., element, false, taxiWait);
828 // add access to all public transport stops
829 if (element == SUMO_TAG_BUS_STOP) {
830 for (const auto& a : stop.second->accessPos) {
831 router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(std::get<0>(a)),
832 std::get<1>(a), std::get<1>(a), std::get<2>(a), SUMO_TAG_BUS_STOP, true, taxiWait);
833 }
834 }
835 }
836 }
837 // fill the public transport router with pre-parsed public transport lines
838 for (const auto& i : myInstance->myFlows) {
839 if (i.second->line != "") {
840 const RORouteDef* const route = myInstance->getRouteDef(i.second->routeid);
841 const std::vector<SUMOVehicleParameter::Stop>* addStops = nullptr;
842 if (route != nullptr && route->getFirstRoute() != nullptr) {
843 addStops = &route->getFirstRoute()->getStops();
844 }
845 router.getNetwork()->addSchedule(*i.second, addStops);
846 }
847 }
848 for (const RORoutable* const veh : myInstance->myPTVehicles) {
849 // add single vehicles with line attribute which are not part of a flow
850 // no need to add route stops here, they have been added to the vehicle before
851 router.getNetwork()->addSchedule(veh->getParameter());
852 }
853 // add access to transfer from walking to taxi-use
855 for (const ROEdge* edge : ROEdge::getAllEdges()) {
856 if ((edge->getPermissions() & SVC_PEDESTRIAN) != 0 && (edge->getPermissions() & SVC_TAXI) != 0) {
857 router.getNetwork()->addCarAccess(edge, SVC_TAXI, taxiWait);
858 }
859 }
860 }
861}
862
863
864bool
866 return myHavePermissions;
867}
868
869
870void
874
875bool
877 for (const auto& item : myEdges) {
878 if (item.second->hasStoredEffort()) {
879 return true;
880 }
881 }
882 return false;
883}
884
885const std::string
886RONet::getStoppingPlaceName(const std::string& id) const {
887 for (const auto& mapItem : myStoppingPlaces) {
888 SUMOVehicleParameter::Stop* stop = mapItem.second.get(id);
889 if (stop != nullptr) {
890 // see RONetHandler::parseStoppingPlace
891 return stop->busstop;
892 }
893 }
894 return "";
895}
896
897const std::string
898RONet::getStoppingPlaceElement(const std::string& id) const {
899 for (const auto& mapItem : myStoppingPlaces) {
900 SUMOVehicleParameter::Stop* stop = mapItem.second.get(id);
901 if (stop != nullptr) {
902 // see RONetHandler::parseStoppingPlace
903 return stop->actType;
904 }
905 }
907}
908
909
910#ifdef HAVE_FOX
911// ---------------------------------------------------------------------------
912// RONet::RoutingTask-methods
913// ---------------------------------------------------------------------------
914void
915RONet::RoutingTask::run(MFXWorkerThread* context) {
916 myRoutable->computeRoute(*static_cast<WorkerThread*>(context), myRemoveLoops, myErrorHandler);
917}
918#endif
919
920
921/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ TAXI_PICKUP_ANYWHERE
taxi customer may be picked up anywhere
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition MsgHandler.h:305
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TS
Definition SUMOTime.h:42
const long long int VTYPEPARS_VEHICLECLASS_SET
const std::string DEFAULT_TAXITYPE_ID
const std::string DEFAULT_RAILTYPE_ID
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_TAXI
vehicle is a taxi
@ SVC_PEDESTRIAN
pedestrian
const std::string DEFAULT_BIKETYPE_ID
@ TRIGGERED
The departure is person triggered.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_ROUTES
root element of a route file
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
int getScalingQuota(double frac, int loaded)
Returns the number of instances of the current object that shall be emitted given the number of loade...
Definition StdDefs.cpp:61
T MIN2(T a, T b)
Definition StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
void addCarAccess(const E *edge, SUMOVehicleClass svc, double traveltime)
Adds access edges for transfering from walking to vehicle use.
void addAccess(const std::string &stopId, const E *stopEdge, const double startPos, const double endPos, const double length, const SumoXMLTag category, bool isAccess, double taxiWait)
Adds access edges for stopping places to the intermodal network.
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=nullptr)
Network * getNetwork() const
void writeWeights(OutputDevice &dev)
int getCarWalkTransfer() const
void writeNetwork(OutputDevice &dev)
A thread repeatingly calculating incoming tasks.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
const std::string & getID() const
Returns the id.
Definition Named.h:74
T get(const std::string &id) const
Retrieves an item.
int size() const
Returns the number of stored items within the container.
bool remove(const std::string &id, const bool del=true)
Removes an item.
bool add(const std::string &id, T item)
Adds an item.
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & writePreformattedTag(const std::string &val)
writes a preformatted tag to the device but ensures that any pending tags are closed
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
virtual bool isNull()
returns the information whether the device will discard all output
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeHeader(const SumoXMLTag &rootElement)
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
Interface for building instances of router-edges.
virtual ROEdge * buildEdge(const std::string &name, RONode *from, RONode *to, const int priority)=0
Builds an edge with the given name.
A basic edge for routing applications.
Definition ROEdge.h:72
int getNumericalID() const
Returns the index (numeric id) of the edge.
Definition ROEdge.h:231
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition ROEdge.h:117
bool isInternal() const
return whether this edge is an internal edge
Definition ROEdge.h:159
void setOtherTazConnector(const ROEdge *edge)
Definition ROEdge.h:177
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition ROEdge.h:529
virtual void addSuccessor(ROEdge *s, ROEdge *via=nullptr, std::string dir="")
Adds information about a connected edge.
Definition ROEdge.cpp:131
static const ROEdgeVector & getAllEdges()
Returns all ROEdges.
Definition ROEdge.cpp:372
A single lane the router may use.
Definition ROLane.h:48
The router's network representation.
Definition RONet.h:63
void createBulkRouteRequests(const RORouterProvider &provider, const SUMOTime time, const bool removeLoops)
Definition RONet.cpp:626
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition RONet.cpp:364
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
Definition RONet.cpp:56
int myNumInternalEdges
The number of internal edges in the dictionary.
Definition RONet.h:575
bool myDefaultPedTypeMayBeDeleted
Whether the default pedestrian type was already used or can still be replaced.
Definition RONet.h:514
void setPermissionsFound()
Definition RONet.cpp:871
bool myDefaultRailTypeMayBeDeleted
Whether the default rail type was already used or can still be replaced.
Definition RONet.h:523
bool myDefaultVTypeMayBeDeleted
Whether the default vehicle type was already used or can still be replaced.
Definition RONet.h:511
void checkFlows(SUMOTime time, MsgHandler *errorHandler)
Definition RONet.cpp:540
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition RONet.cpp:150
ContainerMap myContainers
Definition RONet.h:539
std::set< std::string > myPersonIDs
Known person ids.
Definition RONet.h:491
std::map< std::string, std::pair< std::vector< std::string >, std::vector< std::string > > > myDistricts
traffic assignment zones with sources and sinks
Definition RONet.h:548
bool addRouteDef(RORouteDef *def)
Definition RONet.cpp:286
void addStoppingPlace(const std::string &id, const SumoXMLTag category, SUMOVehicleParameter::Stop *stop)
Definition RONet.cpp:277
bool knowsVehicle(const std::string &id) const
returns whether a vehicle with the given id was already loaded
Definition RONet.cpp:488
void cleanup()
closes the file output for computed routes and deletes associated threads if necessary
Definition RONet.cpp:340
bool myHaveActiveFlows
whether any flows are still active
Definition RONet.h:535
std::map< std::string, SUMOTime > myVehIDs
Known vehicle ids and their departure.
Definition RONet.h:488
void openOutput(const OptionsCont &options)
Opens the output for computed routes.
Definition RONet.cpp:292
NamedObjectCont< SUMOVehicleParameter * > myFlows
Known flows.
Definition RONet.h:532
OutputDevice * myRouteAlternativesOutput
The file to write the computed route alternatives into.
Definition RONet.h:554
bool myDefaultBikeTypeMayBeDeleted
Whether the default bicycle type was already used or can still be replaced.
Definition RONet.h:517
RoutablesMap myRoutables
Known routables.
Definition RONet.h:529
int getInternalEdgeNumber() const
Returns the number of internal edges the network contains.
Definition RONet.cpp:801
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition RONet.cpp:466
SUMOTime getDeparture(const std::string &vehID) const
returns departure time for the given vehicle id
Definition RONet.cpp:493
bool myHasBidiEdges
whether the network contains bidirectional railway edges
Definition RONet.h:587
bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource)
Definition RONet.cpp:197
MsgHandler * myErrorHandler
handler for ignorable error messages
Definition RONet.h:578
void writeIntermodal(const OptionsCont &options, ROIntermodalRouter &router) const
Writes the intermodal network and weights if requested.
Definition RONet.cpp:321
RONet()
Constructor.
Definition RONet.cpp:64
NamedObjectCont< RONode * > myNodes
Known nodes.
Definition RONet.h:494
const std::string getStoppingPlaceElement(const std::string &id) const
return the element name for the given stopping place id
Definition RONet.cpp:898
void addContainer(const SUMOTime depart, const std::string desc)
Definition RONet.cpp:534
static void adaptIntermodalRouter(ROIntermodalRouter &router)
Definition RONet.cpp:820
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition RONet.h:158
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition RONet.cpp:144
NamedObjectCont< RORouteDef * > myRoutes
Known routes.
Definition RONet.h:526
bool furtherStored()
Returns the information whether further vehicles, persons or containers are stored.
Definition RONet.cpp:789
bool checkVType(const std::string &id)
Checks whether the vehicle type (distribution) may be added.
Definition RONet.cpp:396
OutputDevice * myRoutesOutput
The file to write the computed routes into.
Definition RONet.h:551
bool addPerson(ROPerson *person)
Definition RONet.cpp:522
int myWrittenRouteNo
The number of written routes.
Definition RONet.h:566
static RONet * myInstance
Unique instance of RONet.
Definition RONet.h:485
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition RONet.h:319
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition RONet.cpp:676
virtual bool addEdge(ROEdge *edge)
Definition RONet.cpp:160
bool myDefaultTaxiTypeMayBeDeleted
Whether the default taxi type was already used or can still be replaced.
Definition RONet.h:520
std::map< std::string, std::map< SUMOVehicleClass, double > > myRestrictions
The vehicle class specific speed restrictions.
Definition RONet.h:572
std::map< SumoXMLTag, NamedObjectCont< SUMOVehicleParameter::Stop * > > myStoppingPlaces
Known bus / train / container stops and parking areas.
Definition RONet.h:500
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition RONet.cpp:442
bool myHavePermissions
Whether the network contains edges which not all vehicles may pass.
Definition RONet.h:569
bool hasPermissions() const
Definition RONet.cpp:865
void setBidiEdges(const std::map< ROEdge *, std::string > &bidiMap)
add a taz for every junction unless a taz with the same id already exists
Definition RONet.cpp:255
ROLane * getLane(const std::string &laneID) const
Retrieves a lane rom the network given its id.
Definition RONet.cpp:813
int myDiscardedRouteNo
The number of discarded routes.
Definition RONet.h:563
VTypeDistDictType myVTypeDistDict
A distribution of vehicle types (probability->vehicle type)
Definition RONet.h:508
std::vector< const RORoutable * > myPTVehicles
vehicles to keep for public transport routing
Definition RONet.h:542
NamedObjectCont< ROEdge * > myEdges
Known edges.
Definition RONet.h:497
void addNode(RONode *node)
Definition RONet.cpp:268
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter * > *vehTypeDistribution)
Adds a vehicle type distribution.
Definition RONet.cpp:455
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition RONet.cpp:219
OutputDevice * myTypesOutput
The file to write the vehicle types into.
Definition RONet.h:557
const bool myDoPTRouting
whether to calculate routes for public transport
Definition RONet.h:584
const bool myKeepVTypeDist
whether to keep the vtype distribution in output
Definition RONet.h:581
virtual ~RONet()
Destructor.
Definition RONet.cpp:113
const std::string getStoppingPlaceName(const std::string &id) const
return the name for the given stopping place id
Definition RONet.cpp:886
std::map< std::string, std::vector< SUMOTime > > myDepartures
Departure times for randomized flows.
Definition RONet.h:545
int getEdgeNumber() const
Returns the total number of edges the network contains including internal edges.
Definition RONet.cpp:795
ROEdge * getEdgeForLaneID(const std::string &laneID) const
Retrieves an edge from the network when the lane id is given.
Definition RONet.cpp:807
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition RONet.cpp:504
bool hasLoadedEffort() const
whether efforts were loaded from file
Definition RONet.cpp:876
NamedObjectCont< SUMOVTypeParameter * > myVehicleTypes
Known vehicle types.
Definition RONet.h:503
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition RONet.cpp:174
Base class for nodes used by the router.
Definition RONode.h:46
const ConstROEdgeVector & getOutgoing() const
Definition RONode.h:76
const ConstROEdgeVector & getIncoming() const
Definition RONode.h:72
A person as used by router.
Definition ROPerson.h:50
A routable thing such as a vehicle or person.
Definition RORoutable.h:52
SUMOVehicleClass getVClass() const
Definition RORoutable.h:109
bool isPublicTransport() const
Definition RORoutable.h:129
bool isPartOfFlow() const
Definition RORoutable.h:133
SUMOTime getDepart() const
Returns the time the vehicle starts at, -1 for triggered vehicles.
Definition RORoutable.h:100
const std::string & getID() const
Returns the id of the routable.
Definition RORoutable.h:91
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Definition RORoutable.h:71
double getMaxSpeed() const
Returns the vehicle's maximum speed.
Definition RORoutable.h:121
Base class for a vehicle's route definition.
Definition RORouteDef.h:53
const RORoute * getFirstRoute() const
Definition RORouteDef.h:98
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the list of stops this route contains.
Definition RORoute.h:187
A vehicle as used by router.
Definition ROVehicle.h:50
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
Definition ROVehicle.h:92
RORouteDef * getRouteDefinition() const
Returns the definition of the route the vehicle takes.
Definition ROVehicle.h:73
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Represents a generic random distribution.
void setBulkMode(const bool mode) const
Structure representing possible vehicle parameter.
long long int parametersSet
Information for the router which parameter were set.
bool onlyReferenced
Information whether this is a type-stub, being only referenced but not defined (needed by routers)
std::string id
The vehicle type's id.
Definition of vehicle stop (position and duration)
std::string actType
act Type (only used by Persons) (used by netedit)
std::string busstop
(Optional) bus stop if one is assigned to the stop
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
void incrementFlow(double scale, SumoRNG *rng=nullptr)
increment flow
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOTime repetitionTotalOffset
The offset between depart and the time for the next vehicle insertions.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
std::string line
The vehicle's line (mainly for public transport)
static std::string getEdgeIDFromLane(const std::string laneID)
return edge id when given the lane ID
static int getIndexFromLane(const std::string laneID)
return lane index when given the lane ID