Eclipse SUMO - Simulation of Urban MObility
RONet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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>
30 #include <utils/common/ToString.h>
34 #include "ROEdge.h"
35 #include "ROLane.h"
36 #include "RONode.h"
37 #include "ROPerson.h"
38 #include "RORoute.h"
39 #include "RORouteDef.h"
40 #include "ROVehicle.h"
41 #include "ROAbstractEdgeBuilder.h"
42 #include "RONet.h"
43 
44 
45 // ===========================================================================
46 // static member definitions
47 // ===========================================================================
48 RONet* RONet::myInstance = nullptr;
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 RONet*
56  if (myInstance != nullptr) {
57  return myInstance;
58  }
59  throw ProcessError("A network was not yet constructed.");
60 }
61 
62 
64  myVehicleTypes(), myDefaultVTypeMayBeDeleted(true),
65  myDefaultPedTypeMayBeDeleted(true), myDefaultBikeTypeMayBeDeleted(true),
66  myHaveActiveFlows(true),
67  myRoutesOutput(nullptr), myRouteAlternativesOutput(nullptr), myTypesOutput(nullptr),
68  myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
69  myHavePermissions(false),
70  myNumInternalEdges(0),
71  myErrorHandler(OptionsCont::getOptions().exists("ignore-errors")
72  && OptionsCont::getOptions().getBool("ignore-errors") ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
73  myKeepVTypeDist(OptionsCont::getOptions().exists("keep-vtype-distributions")
74  && OptionsCont::getOptions().getBool("keep-vtype-distributions")),
75  myHasBidiEdges(false) {
76  if (myInstance != nullptr) {
77  throw ProcessError("A network was already constructed.");
78  }
80  type->onlyReferenced = true;
81  myVehicleTypes.add(type->id, type);
82 
84  defPedType->onlyReferenced = true;
86  myVehicleTypes.add(defPedType->id, defPedType);
87 
89  defBikeType->onlyReferenced = true;
91  myVehicleTypes.add(defBikeType->id, defBikeType);
92 
94  defTaxiType->onlyReferenced = true;
96  myVehicleTypes.add(defTaxiType->id, defTaxiType);
97 
98  myInstance = this;
99 }
100 
101 
103  for (RoutablesMap::iterator routables = myRoutables.begin(); routables != myRoutables.end(); ++routables) {
104  for (RORoutable* const r : routables->second) {
105  const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
106  // delete routes and the vehicle
107  if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
108  if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
109  delete veh->getRouteDefinition();
110  }
111  }
112  delete r;
113  }
114  }
115  for (const RORoutable* const r : myPTVehicles) {
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  myRoutables.clear();
126 }
127 
128 
129 void
130 RONet::addRestriction(const std::string& id, const SUMOVehicleClass svc, const double speed) {
131  myRestrictions[id][svc] = speed;
132 }
133 
134 
135 const std::map<SUMOVehicleClass, double>*
136 RONet::getRestrictions(const std::string& id) const {
137  std::map<std::string, std::map<SUMOVehicleClass, double> >::const_iterator i = myRestrictions.find(id);
138  if (i == myRestrictions.end()) {
139  return nullptr;
140  }
141  return &i->second;
142 }
143 
144 
145 bool
147  if (!myEdges.add(edge->getID(), edge)) {
148  WRITE_ERROR("The edge '" + edge->getID() + "' occurs at least twice.");
149  delete edge;
150  return false;
151  }
152  if (edge->isInternal()) {
153  myNumInternalEdges += 1;
154  }
155  return true;
156 }
157 
158 
159 bool
160 RONet::addDistrict(const std::string id, ROEdge* source, ROEdge* sink) {
161  if (myDistricts.count(id) > 0) {
162  WRITE_ERROR("The TAZ '" + id + "' occurs at least twice.");
163  delete source;
164  delete sink;
165  return false;
166  }
168  addEdge(sink);
170  addEdge(source);
171  sink->setOtherTazConnector(source);
172  source->setOtherTazConnector(sink);
173  myDistricts[id] = std::make_pair(std::vector<std::string>(), std::vector<std::string>());
174  return true;
175 }
176 
177 
178 bool
179 RONet::addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource) {
180  if (myDistricts.count(tazID) == 0) {
181  WRITE_ERROR("The TAZ '" + tazID + "' is unknown.");
182  return false;
183  }
184  ROEdge* edge = getEdge(edgeID);
185  if (edge == nullptr) {
186  WRITE_ERROR("The edge '" + edgeID + "' for TAZ '" + tazID + "' is unknown.");
187  return false;
188  }
189  if (isSource) {
190  getEdge(tazID + "-source")->addSuccessor(edge);
191  myDistricts[tazID].first.push_back(edgeID);
192  } else {
193  edge->addSuccessor(getEdge(tazID + "-sink"));
194  myDistricts[tazID].second.push_back(edgeID);
195  }
196  return true;
197 }
198 
199 
200 void
202  for (auto item : myNodes) {
203  const std::string tazID = item.first;
204  if (myDistricts.count(tazID) != 0) {
205  WRITE_WARNINGF("A TAZ with id '%' already exists. Not building junction TAZ.", tazID);
206  continue;
207  }
208  const std::string sourceID = tazID + "-source";
209  const std::string sinkID = tazID + "-sink";
210  // sink must be addd before source
211  ROEdge* sink = eb.buildEdge(sinkID, nullptr, nullptr, 0);
212  ROEdge* source = eb.buildEdge(sourceID, nullptr, nullptr, 0);
213  sink->setOtherTazConnector(source);
214  source->setOtherTazConnector(sink);
215  addDistrict(tazID, source, sink);
216  auto& district = myDistricts[tazID];
217  const RONode* junction = item.second;
218  for (const ROEdge* edge : junction->getIncoming()) {
219  if (!edge->isInternal()) {
220  const_cast<ROEdge*>(edge)->addSuccessor(sink);
221  district.second.push_back(edge->getID());
222  }
223  }
224  for (const ROEdge* edge : junction->getOutgoing()) {
225  if (!edge->isInternal()) {
226  source->addSuccessor(const_cast<ROEdge*>(edge));
227  district.first.push_back(edge->getID());
228  }
229  }
230  }
231 }
232 
233 void
234 RONet::setBidiEdges(const std::map<ROEdge*, std::string>& bidiMap) {
235  for (const auto& item : bidiMap) {
236  ROEdge* bidi = myEdges.get(item.second);
237  if (bidi == nullptr) {
238  WRITE_ERROR("The bidi edge '" + item.second + "' is not known.");
239  }
240  item.first->setBidiEdge(bidi);
241  myHasBidiEdges = true;
242  }
243 }
244 
245 void
247  if (!myNodes.add(node->getID(), node)) {
248  WRITE_ERROR("The node '" + node->getID() + "' occurs at least twice.");
249  delete node;
250  }
251 }
252 
253 
254 void
255 RONet::addStoppingPlace(const std::string& id, const SumoXMLTag category, SUMOVehicleParameter::Stop* stop) {
256  if (!myStoppingPlaces[category == SUMO_TAG_TRAIN_STOP ? SUMO_TAG_BUS_STOP : category].add(id, stop)) {
257  WRITE_ERROR("The " + toString(category) + " '" + id + "' occurs at least twice.");
258  delete stop;
259  }
260 }
261 
262 
263 bool
265  return myRoutes.add(def->getID(), def);
266 }
267 
268 
269 void
271  if (options.isSet("output-file") && options.getString("output-file") != "") {
272  myRoutesOutput = &OutputDevice::getDevice(options.getString("output-file"));
274  myRoutesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
275  }
276  if (options.exists("alternatives-output") && options.isSet("alternatives-output")
277  && !(options.exists("write-trips") && options.getBool("write-trips"))) {
278  myRouteAlternativesOutput = &OutputDevice::getDevice(options.getString("alternatives-output"));
280  myRouteAlternativesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
281  }
282  if (options.isSet("vtype-output")) {
283  myTypesOutput = &OutputDevice::getDevice(options.getString("vtype-output"));
285  myTypesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
286  }
287 }
288 
289 
290 void
291 RONet::writeIntermodal(const OptionsCont& options, ROIntermodalRouter& router) const {
292  if (options.exists("intermodal-network-output") && options.isSet("intermodal-network-output")) {
293  OutputDevice::createDeviceByOption("intermodal-network-output", "intermodal");
294  router.writeNetwork(OutputDevice::getDevice(options.getString("intermodal-network-output")));
295  }
296  if (options.exists("intermodal-weight-output") && options.isSet("intermodal-weight-output")) {
297  OutputDevice::createDeviceByOption("intermodal-weight-output", "weights", "meandata_file.xsd");
298  OutputDevice& dev = OutputDevice::getDeviceByOption("intermodal-weight-output");
300  dev.writeAttr(SUMO_ATTR_ID, "intermodalweights");
301  dev.writeAttr(SUMO_ATTR_BEGIN, 0);
303  router.writeWeights(dev);
304  dev.closeTag();
305  }
306 }
307 
308 
309 void
311  // end writing
312  if (myRoutesOutput != nullptr) {
314  }
315  // only if opened
316  if (myRouteAlternativesOutput != nullptr) {
318  }
319  // only if opened
320  if (myTypesOutput != nullptr) {
321  myTypesOutput->close();
322  }
324 #ifdef HAVE_FOX
325  if (myThreadPool.size() > 0) {
326  myThreadPool.clear();
327  }
328 #endif
329 }
330 
331 
332 
334 RONet::getVehicleTypeSecure(const std::string& id) {
335  // check whether the type was already known
337  if (id == DEFAULT_VTYPE_ID) {
339  }
340  if (id == DEFAULT_PEDTYPE_ID) {
342  }
343  if (id == DEFAULT_BIKETYPE_ID) {
345  }
346  if (type != nullptr) {
347  return type;
348  }
349  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
350  if (it2 != myVTypeDistDict.end()) {
351  return it2->second->get();
352  }
353  if (id == "") {
354  // ok, no vehicle type or an unknown type was given within the user input
355  // return the default type
358  }
359  return type;
360 }
361 
362 
363 bool
364 RONet::checkVType(const std::string& id) {
365  if (id == DEFAULT_VTYPE_ID) {
369  } else {
370  return false;
371  }
372  } else if (id == DEFAULT_PEDTYPE_ID) {
376  } else {
377  return false;
378  }
379  } else {
380  if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
381  return false;
382  }
383  }
384  return true;
385 }
386 
387 
388 bool
390  if (checkVType(type->id)) {
391  myVehicleTypes.add(type->id, type);
392  } else {
393  WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
394  delete type;
395  return false;
396  }
397  return true;
398 }
399 
400 
401 bool
402 RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
403  if (checkVType(id)) {
404  myVTypeDistDict[id] = vehTypeDistribution;
405  return true;
406  }
407  return false;
408 }
409 
410 
411 bool
412 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
413  if (myVehIDs.find(id) == myVehIDs.end()) {
414  myVehIDs.insert(id);
415  if (veh->isPublicTransport()) {
416  if (!veh->isPartOfFlow()) {
417  myPTVehicles.push_back(veh);
418  }
419  if (OptionsCont::getOptions().exists("ptline-routing") && !OptionsCont::getOptions().getBool("ptline-routing")) {
420  return true;
421  }
422  }
423  myRoutables[veh->getDepart()].push_back(veh);
424  return true;
425  }
426  WRITE_ERROR("Another vehicle with the id '" + id + "' exists.");
427  return false;
428 }
429 
430 
431 bool
432 RONet::knowsVehicle(const std::string& id) {
433  return myVehIDs.find(id) != myVehIDs.end();
434 }
435 
436 
437 bool
438 RONet::addFlow(SUMOVehicleParameter* flow, const bool randomize) {
439  if (randomize) {
440  myDepartures[flow->id].reserve(flow->repetitionNumber);
441  for (int i = 0; i < flow->repetitionNumber; ++i) {
442  myDepartures[flow->id].push_back(flow->depart + RandHelper::rand(flow->repetitionNumber * flow->repetitionOffset));
443  }
444  std::sort(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
445  std::reverse(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
446  }
447  return myFlows.add(flow->id, flow);
448 }
449 
450 
451 bool
453  if (myPersonIDs.count(person->getID()) == 0) {
454  myPersonIDs.insert(person->getID());
455  myRoutables[person->getDepart()].push_back(person);
456  return true;
457  }
458  WRITE_ERROR("Another person with the id '" + person->getID() + "' exists.");
459  return false;
460 }
461 
462 
463 void
464 RONet::addContainer(const SUMOTime depart, const std::string desc) {
465  myContainers.insert(std::pair<const SUMOTime, const std::string>(depart, desc));
466 }
467 
468 
469 void
470 RONet::checkFlows(SUMOTime time, MsgHandler* errorHandler) {
471  myHaveActiveFlows = false;
472  for (const auto& i : myFlows) {
473  SUMOVehicleParameter* pars = i.second;
474  if (pars->repetitionProbability > 0) {
475  if (pars->repetitionEnd > pars->depart) {
476  myHaveActiveFlows = true;
477  }
478  const SUMOTime origDepart = pars->depart;
479  while (pars->depart < time) {
480  if (pars->repetitionEnd <= pars->depart) {
481  break;
482  }
483  // only call rand if all other conditions are met
484  if (RandHelper::rand() < (pars->repetitionProbability * TS)) {
485  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
486  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
487  newPars->depart = pars->depart;
488  for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
489  if (stop->until >= 0) {
490  stop->until += pars->depart - origDepart;
491  }
492  }
493  pars->repetitionsDone++;
494  // try to build the vehicle
496  if (!myKeepVTypeDist) {
497  // fix the type id in case we used a distribution
498  newPars->vtypeid = type->id;
499  }
500  const SUMOTime stopOffset = pars->routeid[0] == '!' ? pars->depart - origDepart : pars->depart;
501  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
502  ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
503  addVehicle(newPars->id, veh);
504  delete newPars;
505  }
506  pars->depart += DELTA_T;
507  }
508  } else {
509  while (pars->repetitionsDone < pars->repetitionNumber) {
510  myHaveActiveFlows = true;
511  SUMOTime depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
512  if (myDepartures.find(pars->id) != myDepartures.end()) {
513  depart = myDepartures[pars->id].back();
514  }
515  if (depart >= time + DELTA_T) {
516  break;
517  }
518  if (myDepartures.find(pars->id) != myDepartures.end()) {
519  myDepartures[pars->id].pop_back();
520  }
521  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
522  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
523  newPars->depart = depart;
524  for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
525  if (stop->until >= 0) {
526  stop->until += depart - pars->depart;
527  }
528  }
529  pars->repetitionsDone++;
530  // try to build the vehicle
532  if (type == nullptr) {
534  } else {
535  // fix the type id in case we used a distribution
536  newPars->vtypeid = type->id;
537  }
538  const SUMOTime stopOffset = pars->routeid[0] == '!' ? depart - pars->depart : depart;
539  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
540  ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
541  addVehicle(newPars->id, veh);
542  delete newPars;
543  }
544  }
545  }
546 }
547 
548 
549 void
550 RONet::createBulkRouteRequests(const RORouterProvider& provider, const SUMOTime time, const bool removeLoops) {
551  std::map<const int, std::vector<RORoutable*> > bulkVehs;
552  for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
553  if (i->first >= time) {
554  break;
555  }
556  for (RORoutable* const routable : i->second) {
557  const ROEdge* const depEdge = routable->getDepartEdge();
558  bulkVehs[depEdge->getNumericalID()].push_back(routable);
559  RORoutable* const first = bulkVehs[depEdge->getNumericalID()].front();
560  if (first->getMaxSpeed() != routable->getMaxSpeed()) {
561  WRITE_WARNING("Bulking different maximum speeds ('" + first->getID() + "' and '" + routable->getID() + "') may lead to suboptimal routes.");
562  }
563  if (first->getVClass() != routable->getVClass()) {
564  WRITE_WARNING("Bulking different vehicle classes ('" + first->getID() + "' and '" + routable->getID() + "') may lead to invalid routes.");
565  }
566  }
567  }
568  int workerIndex = 0;
569  for (std::map<const int, std::vector<RORoutable*> >::const_iterator i = bulkVehs.begin(); i != bulkVehs.end(); ++i) {
570 #ifdef HAVE_FOX
571  if (myThreadPool.size() > 0) {
572  RORoutable* const first = i->second.front();
573  myThreadPool.add(new RoutingTask(first, removeLoops, myErrorHandler), workerIndex);
574  myThreadPool.add(new BulkmodeTask(true), workerIndex);
575  for (std::vector<RORoutable*>::const_iterator j = i->second.begin() + 1; j != i->second.end(); ++j) {
576  myThreadPool.add(new RoutingTask(*j, removeLoops, myErrorHandler), workerIndex);
577  }
578  myThreadPool.add(new BulkmodeTask(false), workerIndex);
579  workerIndex++;
580  if (workerIndex == (int)myThreadPool.size()) {
581  workerIndex = 0;
582  }
583  continue;
584  }
585 #endif
586  for (std::vector<RORoutable*>::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
587  (*j)->computeRoute(provider, removeLoops, myErrorHandler);
588  provider.getVehicleRouter((*j)->getVClass()).setBulkMode(true);
589  }
590  provider.getVehicleRouter(SVC_IGNORING).setBulkMode(false);
591  }
592 }
593 
594 
595 SUMOTime
597  SUMOTime time) {
598  MsgHandler* mh = (options.getBool("ignore-errors") ?
600  if (myHaveActiveFlows) {
601  checkFlows(time, mh);
602  }
603  SUMOTime lastTime = -1;
604  const bool removeLoops = options.getBool("remove-loops");
605  const int maxNumThreads = options.getInt("routing-threads");
606  if (myRoutables.size() != 0) {
607  if (options.getBool("bulk-routing")) {
608 #ifdef HAVE_FOX
609  while ((int)myThreadPool.size() < maxNumThreads) {
610  new WorkerThread(myThreadPool, provider);
611  }
612 #endif
613  createBulkRouteRequests(provider, time, removeLoops);
614  } else {
615  for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
616  if (i->first >= time) {
617  break;
618  }
619  for (RORoutable* const routable : i->second) {
620 #ifdef HAVE_FOX
621  // add task
622  if (maxNumThreads > 0) {
623  const int numThreads = (int)myThreadPool.size();
624  if (numThreads == 0) {
625  // This is the very first routing. Since at least the CHRouter needs initialization
626  // before it gets cloned, we do not do this in parallel
627  routable->computeRoute(provider, removeLoops, myErrorHandler);
628  new WorkerThread(myThreadPool, provider);
629  } else {
630  // add thread if necessary
631  if (numThreads < maxNumThreads && myThreadPool.isFull()) {
632  new WorkerThread(myThreadPool, provider);
633  }
634  myThreadPool.add(new RoutingTask(routable, removeLoops, myErrorHandler));
635  }
636  continue;
637  }
638 #endif
639  routable->computeRoute(provider, removeLoops, myErrorHandler);
640  }
641  }
642  }
643 #ifdef HAVE_FOX
644  myThreadPool.waitAll();
645 #endif
646  }
647  // write all vehicles (and additional structures)
648  while (myRoutables.size() != 0 || myContainers.size() != 0) {
649  // get the next vehicle, person or container
650  RoutablesMap::iterator routables = myRoutables.begin();
651  const SUMOTime routableTime = routables == myRoutables.end() ? SUMOTime_MAX : routables->first;
652  ContainerMap::iterator container = myContainers.begin();
653  const SUMOTime containerTime = container == myContainers.end() ? SUMOTime_MAX : container->first;
654  // check whether it shall not yet be computed
655  if (routableTime >= time && containerTime >= time) {
656  lastTime = MIN2(routableTime, containerTime);
657  break;
658  }
659  const SUMOTime minTime = MIN2(routableTime, containerTime);
660  if (routableTime == minTime) {
661  // check whether to print the output
662  if (lastTime != routableTime && lastTime != -1) {
663  // report writing progress
664  if (options.getInt("stats-period") >= 0 && ((int)routableTime % options.getInt("stats-period")) == 0) {
665  WRITE_MESSAGE("Read: " + toString(myVehIDs.size()) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
666  }
667  }
668  lastTime = routableTime;
669  for (const RORoutable* const r : routables->second) {
670  // ok, check whether it has been routed
671  if (r->getRoutingSuccess()) {
672  // write the route
675  } else {
677  }
678  // delete routes and the vehicle
679  if (!r->isPublicTransport() || r->isPartOfFlow()) {
680  const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
681  if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
682  if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
683  delete veh->getRouteDefinition();
684  }
685  }
686  delete r;
687  }
688  }
689  myRoutables.erase(routables);
690  }
691  if (containerTime == minTime) {
692  myRoutesOutput->writePreformattedTag(container->second);
693  if (myRouteAlternativesOutput != nullptr) {
695  }
696  myContainers.erase(container);
697  }
698  }
699  return lastTime;
700 }
701 
702 
703 bool
705  return myRoutables.size() > 0 || (myFlows.size() > 0 && myHaveActiveFlows) || myContainers.size() > 0;
706 }
707 
708 
709 int
711  return myEdges.size();
712 }
713 
714 
715 int
717  return myNumInternalEdges;
718 }
719 
720 
721 void
723  double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
724  // add access to all parking areas
725  for (const auto& i : myInstance->myStoppingPlaces[SUMO_TAG_PARKING_AREA]) {
726  router.getNetwork()->addAccess(i.first, myInstance->getEdgeForLaneID(i.second->lane), (i.second->startPos + i.second->endPos) / 2., 0., SUMO_TAG_PARKING_AREA, false, taxiWait);
727  }
728  // add access to all public transport stops
729  for (const auto& stop : myInstance->myStoppingPlaces[SUMO_TAG_BUS_STOP]) {
730  router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(stop.second->lane), (stop.second->startPos + stop.second->endPos) / 2., 0., SUMO_TAG_BUS_STOP, false, taxiWait);
731  for (const auto& a : stop.second->accessPos) {
732  router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(std::get<0>(a)), std::get<1>(a), std::get<2>(a), SUMO_TAG_BUS_STOP, true, taxiWait);
733  }
734  }
735  // fill the public transport router with pre-parsed public transport lines
736  for (const auto& i : myInstance->myFlows) {
737  if (i.second->line != "") {
738  const RORouteDef* const route = myInstance->getRouteDef(i.second->routeid);
739  const std::vector<SUMOVehicleParameter::Stop>* addStops = nullptr;
740  if (route != nullptr && route->getFirstRoute() != nullptr) {
741  addStops = &route->getFirstRoute()->getStops();
742  }
743  router.getNetwork()->addSchedule(*i.second, addStops);
744  }
745  }
746  for (const RORoutable* const veh : myInstance->myPTVehicles) {
747  // add single vehicles with line attribute which are not part of a flow
748  // no need to add route stops here, they have been added to the vehicle before
749  router.getNetwork()->addSchedule(veh->getParameter());
750  }
751  // add access to transfer from walking to taxi-use
753  for (const ROEdge* edge : ROEdge::getAllEdges()) {
754  if ((edge->getPermissions() & SVC_PEDESTRIAN) != 0 && (edge->getPermissions() & SVC_TAXI) != 0) {
755  router.getNetwork()->addCarAccess(edge, SVC_TAXI, taxiWait);
756  }
757  }
758  }
759 }
760 
761 
762 bool
764  return myHavePermissions;
765 }
766 
767 
768 void
770  myHavePermissions = true;
771 }
772 
773 bool
775  for (const auto& item : myEdges) {
776  if (item.second->hasStoredEffort()) {
777  return true;
778  }
779  }
780  return false;
781 }
782 
783 const std::string
784 RONet::getStoppingPlaceName(const std::string& id) const {
785  for (const auto& mapItem : myStoppingPlaces) {
786  SUMOVehicleParameter::Stop* stop = mapItem.second.get(id);
787  if (stop != nullptr) {
788  // see RONetHandler::parseStoppingPlace
789  return stop->busstop;
790  }
791  }
792  return "";
793 }
794 
795 #ifdef HAVE_FOX
796 // ---------------------------------------------------------------------------
797 // RONet::RoutingTask-methods
798 // ---------------------------------------------------------------------------
799 void
800 RONet::RoutingTask::run(FXWorkerThread* context) {
801  myRoutable->computeRoute(*static_cast<WorkerThread*>(context), myRemoveLoops, myErrorHandler);
802 }
803 #endif
804 
805 
806 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:277
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:278
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SUMOTime_MAX
Definition: SUMOTime.h:32
#define TS
Definition: SUMOTime.h:40
long long int SUMOTime
Definition: SUMOTime.h:31
const int VTYPEPARS_VEHICLECLASS_SET
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ 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_TAXITYPE_ID
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
const std::string DEFAULT_BIKETYPE_ID
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_PARKING_AREA
A parking area.
@ 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
T MIN2(T a, T b)
Definition: StdDefs.h:73
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A thread repeatingly calculating incoming tasks.
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 pos, const double length, const SumoXMLTag category, bool isAccess, double taxiWait)
Adds access edges for stopping places to the intermodal network.
@ TAXI_PICKUP_ANYWHERE
taxi customer may be picked up anywhere
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)
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:67
const std::string & getID() const
Returns the id.
Definition: Named.h:73
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.
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.
Definition: OptionsCont.cpp:58
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & writePreformattedTag(const std::string &val)
writes a preformatted tag to the device but ensures that any pending tags are closed
Definition: OutputDevice.h:277
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.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
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)
Definition: OutputDevice.h:184
static OutputDevice & getDevice(const std::string &name)
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:70
int getNumericalID() const
Returns the index (numeric id) of the edge.
Definition: ROEdge.h:217
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition: ROEdge.h:112
bool isInternal() const
return whether this edge is an internal edge
Definition: ROEdge.h:145
void setOtherTazConnector(const ROEdge *edge)
Definition: ROEdge.h:163
virtual void addSuccessor(ROEdge *s, ROEdge *via=nullptr, std::string dir="")
Adds information about a connected edge.
Definition: ROEdge.cpp:107
static const ROEdgeVector & getAllEdges()
Returns all ROEdges.
Definition: ROEdge.cpp:347
The router's network representation.
Definition: RONet.h:62
void createBulkRouteRequests(const RORouterProvider &provider, const SUMOTime time, const bool removeLoops)
Definition: RONet.cpp:550
std::set< std::string > myVehIDs
Known vehicle ids.
Definition: RONet.h:464
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition: RONet.cpp:334
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
Definition: RONet.cpp:55
int myNumInternalEdges
The number of internal edges in the dictionary.
Definition: RONet.h:545
bool myDefaultPedTypeMayBeDeleted
Whether the default pedestrian type was already used or can still be replaced.
Definition: RONet.h:490
void setPermissionsFound()
Definition: RONet.cpp:769
bool myDefaultVTypeMayBeDeleted
Whether the default vehicle type was already used or can still be replaced.
Definition: RONet.h:487
void checkFlows(SUMOTime time, MsgHandler *errorHandler)
Definition: RONet.cpp:470
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
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:136
ROEdge * getEdgeForLaneID(const std::string &laneID) const
Retrieves an edge from the network when the lane id is given.
Definition: RONet.h:167
ContainerMap myContainers
Definition: RONet.h:509
std::set< std::string > myPersonIDs
Known person ids.
Definition: RONet.h:467
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:518
bool addRouteDef(RORouteDef *def)
Definition: RONet.cpp:264
void addStoppingPlace(const std::string &id, const SumoXMLTag category, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:255
void cleanup()
closes the file output for computed routes and deletes associated threads if necessary
Definition: RONet.cpp:310
bool myHaveActiveFlows
whether any flows are still active
Definition: RONet.h:505
void openOutput(const OptionsCont &options)
Opens the output for computed routes.
Definition: RONet.cpp:270
NamedObjectCont< SUMOVehicleParameter * > myFlows
Known flows.
Definition: RONet.h:502
OutputDevice * myRouteAlternativesOutput
The file to write the computed route alternatives into.
Definition: RONet.h:524
bool myDefaultBikeTypeMayBeDeleted
Whether the default bicycle type was already used or can still be replaced.
Definition: RONet.h:493
RoutablesMap myRoutables
Known routables.
Definition: RONet.h:499
int getInternalEdgeNumber() const
Returns the number of internal edges the network contains.
Definition: RONet.cpp:716
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition: RONet.cpp:412
bool myHasBidiEdges
whether the network contains bidirectional railway edges
Definition: RONet.h:554
bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource)
Definition: RONet.cpp:179
MsgHandler * myErrorHandler
handler for ignorable error messages
Definition: RONet.h:548
void writeIntermodal(const OptionsCont &options, ROIntermodalRouter &router) const
Writes the intermodal network and weights if requested.
Definition: RONet.cpp:291
RONet()
Constructor.
Definition: RONet.cpp:63
NamedObjectCont< RONode * > myNodes
Known nodes.
Definition: RONet.h:470
void addContainer(const SUMOTime depart, const std::string desc)
Definition: RONet.cpp:464
static void adaptIntermodalRouter(ROIntermodalRouter &router)
Definition: RONet.cpp:722
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: RONet.cpp:130
NamedObjectCont< RORouteDef * > myRoutes
Known routes.
Definition: RONet.h:496
bool furtherStored()
Returns the information whether further vehicles, persons or containers are stored.
Definition: RONet.cpp:704
bool checkVType(const std::string &id)
Checks whether the vehicle type (distribution) may be added.
Definition: RONet.cpp:364
OutputDevice * myRoutesOutput
The file to write the computed routes into.
Definition: RONet.h:521
bool addPerson(ROPerson *person)
Definition: RONet.cpp:452
int myWrittenRouteNo
The number of written routes.
Definition: RONet.h:536
static RONet * myInstance
Unique instance of RONet.
Definition: RONet.h:461
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition: RONet.cpp:596
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:146
std::map< std::string, std::map< SUMOVehicleClass, double > > myRestrictions
The vehicle class specific speed restrictions.
Definition: RONet.h:542
std::map< SumoXMLTag, NamedObjectCont< SUMOVehicleParameter::Stop * > > myStoppingPlaces
Known bus / train / container stops and parking areas.
Definition: RONet.h:476
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition: RONet.cpp:389
bool myHavePermissions
Whether the network contains edges which not all vehicles may pass.
Definition: RONet.h:539
bool hasPermissions() const
Definition: RONet.cpp:763
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:234
bool knowsVehicle(const std::string &id)
returns whether a vehicle with the given id was already loaded
Definition: RONet.cpp:432
int myDiscardedRouteNo
The number of discarded routes.
Definition: RONet.h:533
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition: RONet.h:298
VTypeDistDictType myVTypeDistDict
A distribution of vehicle types (probability->vehicle type)
Definition: RONet.h:484
std::vector< const RORoutable * > myPTVehicles
vehicles to keep for public transport routing
Definition: RONet.h:512
NamedObjectCont< ROEdge * > myEdges
Known edges.
Definition: RONet.h:473
void addNode(RONode *node)
Definition: RONet.cpp:246
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter * > *vehTypeDistribution)
Adds a vehicle type distribution.
Definition: RONet.cpp:402
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:201
OutputDevice * myTypesOutput
The file to write the vehicle types into.
Definition: RONet.h:527
const bool myKeepVTypeDist
whether to keep the the vtype distribution in output
Definition: RONet.h:551
virtual ~RONet()
Destructor.
Definition: RONet.cpp:102
const std::string getStoppingPlaceName(const std::string &id) const
return the name for the given stopping place id
Definition: RONet.cpp:784
std::map< std::string, std::vector< SUMOTime > > myDepartures
Departure times for randomized flows.
Definition: RONet.h:515
int getEdgeNumber() const
Returns the total number of edges the network contains including internal edges.
Definition: RONet.cpp:710
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition: RONet.cpp:438
bool hasLoadedEffort() const
whether efforts were loaded from file
Definition: RONet.cpp:774
NamedObjectCont< SUMOVTypeParameter * > myVehicleTypes
Known vehicle types.
Definition: RONet.h:479
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition: RONet.cpp:160
Base class for nodes used by the router.
Definition: RONode.h:43
const ConstROEdgeVector & getIncoming() const
Definition: RONode.h:69
const ConstROEdgeVector & getOutgoing() const
Definition: RONode.h:73
A person as used by router.
Definition: ROPerson.h:49
A routable thing such as a vehicle or person.
Definition: RORoutable.h:52
bool getRoutingSuccess() const
Definition: RORoutable.h:151
void write(OutputDevice &os, OutputDevice *const altos, OutputDevice *const typeos, OptionsCont &options) const
Saves the routable including the vehicle type (if it was not saved before).
Definition: RORoutable.h:138
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Definition: RORoutable.h:71
const std::string & getID() const
Returns the id of the routable.
Definition: RORoutable.h:91
SUMOVehicleClass getVClass() const
Definition: RORoutable.h:105
bool isPublicTransport() const
Definition: RORoutable.h:119
bool isPartOfFlow() const
Definition: RORoutable.h:123
virtual void computeRoute(const RORouterProvider &provider, const bool removeLoops, MsgHandler *errorHandler)=0
SUMOTime getDepart() const
Returns the time the vehicle starts at, -1 for triggered vehicles.
Definition: RORoutable.h:100
virtual const ROEdge * getDepartEdge() const =0
double getMaxSpeed() const
Returns the vehicle's maximum speed.
Definition: RORoutable.h:111
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.
Definition: RORouteDef.cpp:392
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the list of stops this route contains.
Definition: RORoute.h:181
A vehicle as used by router.
Definition: ROVehicle.h:50
RORouteDef * getRouteDefinition() const
Returns the definition of the route the vehicle takes.
Definition: ROVehicle.h:73
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:51
SUMOAbstractRouter< E, V > & getVehicleRouter(SUMOVehicleClass svc) const
Structure representing possible vehicle parameter.
bool onlyReferenced
Information whether this is a type-stub, being only referenced but not defined (needed by routers)
int parametersSet
Information for the router which parameter were set.
std::string id
The vehicle type's id.
Definition of vehicle stop (position and duration)
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.
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 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.