SUMO - Simulation of Urban MObility
IntermodalRouter.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // The IntermodalRouter builds a special network and (delegates to a SUMOAbstractRouter)
17 /****************************************************************************/
18 #ifndef IntermodalRouter_h
19 #define IntermodalRouter_h
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <string>
28 #include <vector>
29 #include <algorithm>
30 #include <assert.h>
32 #include <utils/common/SUMOTime.h>
33 #include <utils/common/ToString.h>
35 #include "SUMOAbstractRouter.h"
36 #include "DijkstraRouter.h"
37 #include "IntermodalNetwork.h"
38 #include "EffortCalculator.h"
39 #include "CarEdge.h"
40 #include "StopEdge.h"
41 #include "PedestrianRouter.h"
42 
43 //#define IntermodalRouter_DEBUG_ROUTES
44 
45 
46 // ===========================================================================
47 // class definitions
48 // ===========================================================================
53 template<class E, class L, class N, class V>
54 class IntermodalRouter : public SUMOAbstractRouter<E, IntermodalTrip<E, N, V> > {
55 public:
57 
58 private:
63  typedef DijkstraRouter<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V>, SUMOAbstractRouterPermissions<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V> > > _InternalDijkstra;
64 
65 public:
66  struct TripItem {
67  TripItem(const std::string& _line = "") :
68  line(_line), intended(_line), depart(-1), traveltime(0.), cost(0.) {}
69  std::string line;
70  std::string destStop;
71  std::string intended; // intended public transport vehicle id
72  double depart; // intended public transport departure
73  std::vector<const E*> edges;
74  double traveltime;
75  double cost;
76  };
77 
79  IntermodalRouter(CreateNetCallback callback, const int carWalkTransfer, const int routingMode = 0, EffortCalculator* calc = nullptr) :
80  SUMOAbstractRouter<E, _IntermodalTrip>("IntermodalRouter"),
81  myAmClone(false), myInternalRouter(nullptr), myIntermodalNet(nullptr),
82  myCallback(callback), myCarWalkTransfer(carWalkTransfer), myRoutingMode(routingMode),
83  myExternalEffort(calc) {
84  }
85 
87  virtual ~IntermodalRouter() {
88  delete myInternalRouter;
89  if (!myAmClone) {
90  delete myIntermodalNet;
91  }
92  }
93 
95  createNet();
97  }
98 
101  bool compute(const E* from, const E* to, const double departPos, const double arrivalPos,
102  const std::string stopID, const double speed,
103  const V* const vehicle, const SVCPermissions modeSet, const SUMOTime msTime,
104  std::vector<TripItem>& into, const double externalFactor = 0.) {
105  createNet();
106  _IntermodalTrip trip(from, to, departPos, arrivalPos, speed, msTime, 0, vehicle, modeSet, myExternalEffort, externalFactor);
107  std::vector<const _IntermodalEdge*> intoEdges;
108  const bool success = myInternalRouter->compute(myIntermodalNet->getDepartEdge(from, trip.departPos),
109  stopID != "" ? myIntermodalNet->getStopEdge(stopID) : myIntermodalNet->getArrivalEdge(to, trip.arrivalPos),
110  &trip, msTime, intoEdges);
111  if (success) {
112  std::string lastLine = "";
113  double time = STEPS2TIME(msTime);
114  double effort = 0.;
115  const _IntermodalEdge* prev = nullptr;
116  for (const _IntermodalEdge* iEdge : intoEdges) {
117  if (iEdge->includeInRoute(false)) {
118  if (iEdge->getLine() == "!stop") {
119  into.back().destStop = iEdge->getID();
120  if (lastLine == "!ped") {
121  lastLine = ""; // a stop always starts a new trip item
122  }
123  } else {
124  if (iEdge->getLine() != lastLine) {
125  lastLine = iEdge->getLine();
126  if (lastLine == "!car") {
127  into.push_back(TripItem(vehicle->getID()));
128  } else if (lastLine == "!ped") {
129  into.push_back(TripItem());
130  } else {
131  into.push_back(TripItem(lastLine));
132  into.back().depart = iEdge->getIntended(time, into.back().intended);
133  }
134  }
135  if (into.back().edges.empty() || into.back().edges.back() != iEdge->getEdge()) {
136  into.back().edges.push_back(iEdge->getEdge());
137  }
138  }
139  }
140  if (prev != nullptr) {
141  myInternalRouter->updateViaCost(prev, iEdge, &trip, time, effort);
142  }
143  const double edgeEffort = myInternalRouter->getEffort(iEdge, &trip, time);
144  effort += edgeEffort;
145  const double edgeTime = myInternalRouter->getTravelTime(iEdge, &trip, time, edgeEffort);
146  time += edgeTime;
147  prev = iEdge;
148  if (!into.empty()) {
149  into.back().traveltime += edgeTime;
150  into.back().cost += edgeEffort;
151  }
152  }
153  }
154 #ifdef IntermodalRouter_DEBUG_ROUTES
155  double time = STEPS2TIME(msTime);
156  for (const _IntermodalEdge* iEdge : intoEdges) {
157  const double edgeEffort = myInternalRouter->getEffort(iEdge, &trip, time);
158  time += edgeEffort;
159  std::cout << iEdge->getID() << "(" << iEdge->getLine() << "): " << edgeEffort << std::endl;
160  }
161  std::cout << TIME2STEPS(msTime) << " trip from " << from->getID() << " to " << (to != nullptr ? to->getID() : stopID)
162  << " departPos=" << trip.departPos
163  << " arrivalPos=" << trip.arrivalPos
164  << " edges=" << toString(intoEdges)
165 // << " resultEdges=" << toString(into)
166  << " time=" << time
167  << "\n";
168 #endif
169  return success;
170  }
171 
174  bool compute(const E*, const E*, const _IntermodalTrip* const,
175  SUMOTime, std::vector<const E*>&) {
176  throw ProcessError("Do not use this method");
177  }
178 
179  void prohibit(const std::vector<E*>& toProhibit) {
180  createNet();
181  std::vector<_IntermodalEdge*> toProhibitPE;
182  for (typename std::vector<E*>::const_iterator it = toProhibit.begin(); it != toProhibit.end(); ++it) {
183  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).first);
184  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).second);
185  toProhibitPE.push_back(myIntermodalNet->getCarEdge(*it));
186  }
187  myInternalRouter->prohibit(toProhibitPE);
188  }
189 
191  createNet();
192  for (_IntermodalEdge* e : myIntermodalNet->getAllEdges()) {
193  dev.openTag(SUMO_TAG_EDGE);
194  dev.writeAttr(SUMO_ATTR_ID, e->getID());
195  dev.writeAttr(SUMO_ATTR_LINE, e->getLine());
196  dev.writeAttr(SUMO_ATTR_LENGTH, e->getLength());
197  dev.writeAttr("successors", toString(e->getSuccessors(SVC_IGNORING)));
198  dev.closeTag();
199  }
200  }
201 
203  createNet();
204  _IntermodalTrip trip(nullptr, nullptr, 0., 0., DEFAULT_PEDESTRIAN_SPEED, 0, 0, nullptr, SVC_PASSENGER | SVC_BICYCLE | SVC_BUS);
205  for (_IntermodalEdge* e : myIntermodalNet->getAllEdges()) {
206  dev.openTag(SUMO_TAG_EDGE);
207  dev.writeAttr(SUMO_ATTR_ID, e->getID());
208  dev.writeAttr("traveltime", e->getTravelTime(&trip, 0.));
209  dev.writeAttr("effort", e->getEffort(&trip, 0.));
210  dev.closeTag();
211  }
212  }
213 
214  Network* getNetwork() const {
215  return myIntermodalNet;
216  }
217 
218 private:
219  IntermodalRouter(Network* net):
220  SUMOAbstractRouter<E, _IntermodalTrip>("IntermodalRouterClone"), myAmClone(true),
221  myInternalRouter(new _InternalDijkstra(net->getAllEdges(), true, &_IntermodalEdge::getTravelTimeStatic)),
223 
224  static inline double getEffortAggregated(const _IntermodalEdge* const edge, const _IntermodalTrip* const trip, double time) {
225  return edge == nullptr || !edge->hasEffort() ? 0. : edge->getEffort(trip, time);
226  }
227 
228  static inline double getCombined(const _IntermodalEdge* const edge, const _IntermodalTrip* const trip, double time) {
229  return edge->getTravelTime(trip, time) + trip->externalFactor * trip->calc->getEffort(edge->getNumericalID());
230  }
231 
232  inline void createNet() {
233  if (myIntermodalNet == nullptr) {
234  myIntermodalNet = new Network(E::getAllEdges(), false, myCarWalkTransfer);
235  myIntermodalNet->addCarEdges(E::getAllEdges());
236  myCallback(*this);
237  switch (myRoutingMode) {
238  case 0:
240  break;
241  case 1:
243  break;
244  case 2:
246  break;
247  case 3:
248  if (myExternalEffort != nullptr) {
249  std::vector<std::string> edgeIDs;
250  for (const auto e : myIntermodalNet->getAllEdges()) {
251  edgeIDs.push_back(e->getID());
252  }
253  myExternalEffort->init(edgeIDs);
254  }
256  break;
257  }
258  }
259  }
260 
261 private:
262  const bool myAmClone;
263  _InternalRouter* myInternalRouter;
264  Network* myIntermodalNet;
266  const int myCarWalkTransfer;
267  const int myRoutingMode;
269 
270 
271 private:
274 
275 };
276 
277 
278 #endif
279 
280 /****************************************************************************/
bool compute(const E *from, const E *to, const double departPos, const double arrivalPos, const std::string stopID, const double speed, const V *const vehicle, const SVCPermissions modeSet, const SUMOTime msTime, std::vector< TripItem > &into, const double externalFactor=0.)
Builds the route between the given edges using the minimum effort at the given time The definition of...
void updateViaCost(const E *const prev, const E *const e, const V *const v, double &time, double &effort) const
DijkstraRouter< IntermodalEdge< E, L, N, V >, IntermodalTrip< E, N, V >, SUMOAbstractRouterPermissions< IntermodalEdge< E, L, N, V >, IntermodalTrip< E, N, V > > > _InternalDijkstra
void writeWeights(OutputDevice &dev)
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
double getEffort(const E *const e, const V *const v, double t) const
const EdgePair & getBothDirections(const E *e) const
Returns the pair of forward and backward edge.
static double getEffortAggregated(const _IntermodalEdge *const edge, const _IntermodalTrip *const trip, double time)
static double getEffortStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
IntermodalNetwork< E, L, N, V > Network
_IntermodalEdge * getArrivalEdge(const E *e, const double pos) const
Returns the arriving intermodal edge.
long long int SUMOTime
Definition: SUMOTime.h:36
virtual ~IntermodalRouter()
Destructor.
static double getCombined(const _IntermodalEdge *const edge, const _IntermodalTrip *const trip, double time)
void writeNetwork(OutputDevice &dev)
const std::vector< _IntermodalEdge * > & getAllEdges()
double getTravelTime(const E *const e, const V *const v, const double t, const double effort) const
static double getTravelTimeStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
virtual void init(const std::vector< std::string > &edges)=0
vehicle is a bicycle
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
_IntermodalEdge * getStopEdge(const std::string &stopId) const
Returns the associated stop edge.
int getNumericalID() const
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E *> &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
EffortCalculator *const myExternalEffort
SUMOAbstractRouterPermissions< IntermodalEdge< E, L, N, V >, IntermodalTrip< E, N, V > > _InternalRouter
void prohibit(const std::vector< E *> &toProhibit)
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
const EffortCalculator *const calc
TripItem(const std::string &_line="")
void prohibit(const std::vector< E *> &toProhibit)
the effort calculator interface
IntermodalEdge< E, L, N, V > _IntermodalEdge
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
Computes the shortest path through a network using the Dijkstra algorithm.
virtual double getEffort(const int edge) const =0
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
const double departPos
the intermodal network storing edges, connections and the mappings to the "real" edges ...
vehicle is a passenger car (a "normal" car)
const double arrivalPos
begin/end of the description of an edge
the base edge type that is given to the internal router (SUMOAbstractRouter)
_IntermodalEdge * getDepartEdge(const E *e, const double pos) const
Returns the departing intermodal edge.
vehicle is a bus
virtual double getEffort(const IntermodalTrip< E, N, V > *const, double) const
CreateNetCallback myCallback
const int myCarWalkTransfer
const double DEFAULT_PEDESTRIAN_SPEED
void(* CreateNetCallback)(IntermodalRouter< E, L, N, V > &)
std::vector< const E * > edges
bool compute(const E *, const E *, const _IntermodalTrip *const, SUMOTime, std::vector< const E *> &)
Builds the route between the given edges using the minimum effort at the given time The definition of...
Network * myIntermodalNet
void addCarEdges(const std::vector< E *> &edges)
const double externalFactor
SUMOAbstractRouter< E, _IntermodalTrip > * clone()
IntermodalRouter(Network *net)
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
_IntermodalEdge * getCarEdge(const E *e) const
Returns the associated car edge.
IntermodalTrip< E, N, V > _IntermodalTrip
IntermodalRouter & operator=(const IntermodalRouter &s)
Invalidated assignment operator.
_InternalRouter * myInternalRouter
IntermodalRouter(CreateNetCallback callback, const int carWalkTransfer, const int routingMode=0, EffortCalculator *calc=nullptr)
Constructor.
virtual bool hasEffort() const
the "vehicle" type that is given to the internal router (SUMOAbstractRouter)
vehicles ignoring classes
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Network * getNetwork() const
virtual double getTravelTime(const IntermodalTrip< E, N, V > *const, double) const