SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IntermodalNetwork.h
Go to the documentation of this file.
1 /****************************************************************************/
9 // The Edge definition for the Intermodal Router
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 #ifndef IntermodalNetwork_h
23 #define IntermodalNetwork_h
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <string>
36 #include <vector>
37 #include <algorithm>
38 #include <assert.h>
39 #include <utils/common/SUMOTime.h>
40 #include <utils/common/ToString.h>
41 #include <utils/common/Named.h>
42 #include "IntermodalEdge.h"
43 
44 //#define IntermodalRouter_DEBUG_NETWORK
45 
46 
47 // ===========================================================================
48 // class definitions
49 // ===========================================================================
51 template<class E, class L, class N, class V>
53 private:
56  typedef std::pair<_IntermodalEdge*, _IntermodalEdge*> EdgePair;
57 
58 public:
59  /* brief build the pedestrian network (once)
60  * @param noE The number of edges in the dictionary of E
61  */
62  IntermodalNetwork(const std::vector<E*>& edges, int numericalID = 0) {
63 #ifdef IntermodalRouter_DEBUG_NETWORK
64  std::cout << "initIntermodalNetwork\n";
65 #endif
66  // build the Intermodal edges and the lookup tables
67  bool haveSeenWalkingArea = false;
68  for (typename std::vector<E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
69  const E* const edge = *i;
70  if (edge->isInternal()) {
71  continue;
72  }
73  const L* lane = getSidewalk<E, L>(edge);
74  if (lane != 0) {
75  if (edge->isWalkingArea()) {
76  // only a single edge
77  addEdge(new _PedestrianEdge(numericalID++, edge, lane, true));
78  myBidiLookup[edge] = std::make_pair(myEdges.back(), myEdges.back());
79  myDepartLookup[edge].push_back(myEdges.back());
80  myArrivalLookup[edge].push_back(myEdges.back());
81  haveSeenWalkingArea = true;
82  } else { // regular edge or crossing
83  // forward and backward edges
84  addEdge(new _PedestrianEdge(numericalID++, edge, lane, true));
85  addEdge(new _PedestrianEdge(numericalID++, edge, lane, false));
86  myBidiLookup[edge] = std::make_pair(myEdges[numericalID - 2], myEdges.back());
87  }
88  }
89  if (!edge->isWalkingArea()) {
90  // depart and arrival edges (the router can decide the initial direction to take and the direction to arrive from)
91  addEdge(new _IntermodalEdge(edge->getID() + "_depart_connector", numericalID++, edge, "!connector"));
92  myDepartLookup[edge].push_back(myEdges.back());
93  addEdge(new _IntermodalEdge(edge->getID() + "_arrival_connector", numericalID++, edge, "!connector"));
94  myArrivalLookup[edge].push_back(myEdges.back());
95  }
96  }
97 
98  // build the connections
99  for (typename std::vector<E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
100  E* const edge = *i;
101  const L* sidewalk = getSidewalk<E, L>(edge);
102  if (edge->isInternal() || sidewalk == 0) {
103  continue;
104  }
105  // find all incoming and outgoing lanes for the sidewalk and
106  // connect the corresponding IntermodalEdges
107  const EdgePair& pair = getBothDirections(edge);
108 #ifdef IntermodalRouter_DEBUG_NETWORK
109  std::cout << " building connections from " << sidewalk->getID() << "\n";
110 #endif
111  if (haveSeenWalkingArea) {
112  std::vector<const L*> outgoing = sidewalk->getOutgoingLanes();
113  // if one of the outgoing lanes is a walking area it must be used.
114  // All other connections shall be ignored
115  bool hasWalkingArea = false;
116  for (typename std::vector<const L*>::iterator it = outgoing.begin(); it != outgoing.end(); ++it) {
117  const L* target = *it;
118  const E* targetEdge = &(target->getEdge());
119  if (targetEdge->isWalkingArea()) {
120  hasWalkingArea = true;
121  break;
122  }
123  }
124  for (typename std::vector<const L*>::iterator it = outgoing.begin(); it != outgoing.end(); ++it) {
125  const L* target = *it;
126  const E* targetEdge = &(target->getEdge());
127  const bool used = (target == getSidewalk<E, L>(targetEdge)
128  && (!hasWalkingArea || targetEdge->isWalkingArea()));
129 #ifdef IntermodalRouter_DEBUG_NETWORK
130  const L* potTarget = getSidewalk<E, L>(targetEdge);
131  std::cout << " lane=" << (potTarget == 0 ? "NULL" : potTarget->getID()) << (used ? "(used)" : "") << "\n";
132 #endif
133  if (used) {
134  const EdgePair& targetPair = getBothDirections(targetEdge);
135  pair.first->addSuccessor(targetPair.first);
136  targetPair.second->addSuccessor(pair.second);
137 #ifdef IntermodalRouter_DEBUG_NETWORK
138  std::cout << " " << pair.first->getID() << " -> " << targetPair.first->getID() << "\n";
139  std::cout << " " << targetPair.second->getID() << " -> " << pair.second->getID() << "\n";
140 #endif
141  }
142  }
143  } else {
144  // we have a network without pedestrian structures. Assume that
145  // all sidewalks at a crossing are interconnected
146  const N* toNode = edge->getToJunction();
147  std::vector<const E*> outgoing = toNode->getOutgoing();
148  for (typename std::vector<const E*>::iterator it = outgoing.begin(); it != outgoing.end(); ++it) {
149  // build forward and backward connections for all outgoing sidewalks
150  const E* targetEdge = *it;
151  const L* target = getSidewalk<E, L>(targetEdge);
152  if (targetEdge->isInternal() || target == 0) {
153  continue;
154  }
155  const EdgePair& targetPair = getBothDirections(targetEdge);
156  pair.first->addSuccessor(targetPair.first);
157  targetPair.second->addSuccessor(pair.second);
158 #ifdef IntermodalRouter_DEBUG_NETWORK
159  std::cout << " " << pair.first->getID() << " -> " << targetPair.first->getID() << "\n";
160  std::cout << " " << targetPair.second->getID() << " -> " << pair.second->getID() << "\n";
161 #endif
162  }
163  std::vector<const E*> incoming = toNode->getIncoming();
164  for (typename std::vector<const E*>::iterator it = incoming.begin(); it != incoming.end(); ++it) {
165  // build forward-to-backward connections for all incoming sidewalks
166  const E* targetEdge = *it;
167  const L* target = getSidewalk<E, L>(targetEdge);
168  if (targetEdge->isInternal() || target == 0 || targetEdge == edge) {
169  continue;
170  }
171  const EdgePair& targetPair = getBothDirections(targetEdge);
172  pair.first->addSuccessor(targetPair.second); // change direction
173 #ifdef IntermodalRouter_DEBUG_NETWORK
174  std::cout << " " << pair.first->getID() << " -> " << targetPair.second->getID() << "\n";
175 #endif
176  }
177  const N* fromNode = edge->getFromJunction();
178  outgoing = fromNode->getOutgoing();
179  for (typename std::vector<const E*>::iterator it = outgoing.begin(); it != outgoing.end(); ++it) {
180  // build backward-to-forward connections for all outgoing sidewalks at the fromNode
181  const E* targetEdge = *it;
182  const L* target = getSidewalk<E, L>(targetEdge);
183  if (targetEdge->isInternal() || target == 0 || targetEdge == edge) {
184  continue;
185  }
186  const EdgePair& targetPair = getBothDirections(targetEdge);
187  pair.second->addSuccessor(targetPair.first);
188 #ifdef IntermodalRouter_DEBUG_NETWORK
189  std::cout << " " << pair.second->getID() << " -> " << targetPair.first->getID() << "\n";
190 #endif
191  }
192  }
193  if (edge->isWalkingArea()) {
194  continue;
195  }
196  // build connections from depart connector
197  _IntermodalEdge* startConnector = getDepartEdge(edge);
198  startConnector->addSuccessor(pair.first);
199  startConnector->addSuccessor(pair.second);
200  // build connections to arrival connector
201  _IntermodalEdge* endConnector = getArrivalEdge(edge);
202  pair.first->addSuccessor(endConnector);
203  pair.second->addSuccessor(endConnector);
204 #ifdef IntermodalRouter_DEBUG_NETWORK
205  std::cout << " " << startConnector->getID() << " -> " << pair.first->getID() << "\n";
206  std::cout << " " << startConnector->getID() << " -> " << pair.second->getID() << "\n";
207  std::cout << " " << pair.first->getID() << " -> " << endConnector->getID() << "\n";
208  std::cout << " " << pair.second->getID() << " -> " << endConnector->getID() << "\n";
209 #endif
210  }
211  }
212 
214  for (typename std::vector<_IntermodalEdge*>::iterator it = myEdges.begin(); it != myEdges.end(); ++it) {
215  delete *it;
216  }
217  }
218 
219  void addEdge(_IntermodalEdge* edge) {
220  while ((int)myEdges.size() <= edge->getNumericalID()) {
221  myEdges.push_back(0);
222  }
223  myEdges[edge->getNumericalID()] = edge;
224  }
225 
226  void addConnectors(_IntermodalEdge* const depConn, _IntermodalEdge* const arrConn, const int splitIndex) {
227  addEdge(depConn);
228  addEdge(arrConn);
229  myDepartLookup[depConn->getEdge()].insert(myDepartLookup[depConn->getEdge()].begin() + splitIndex, depConn);
230  myArrivalLookup[arrConn->getEdge()].insert(myArrivalLookup[arrConn->getEdge()].begin() + splitIndex, arrConn);
231  }
232 
233  const std::vector<_IntermodalEdge*>& getAllEdges() {
234  return myEdges;
235  }
236 
238  const EdgePair& getBothDirections(const E* e) {
239  typename std::map<const E*, EdgePair>::const_iterator it = myBidiLookup.find(e);
240  if (it == myBidiLookup.end()) {
241  assert(false);
242  throw ProcessError("Edge '" + e->getID() + "' not found in pedestrian network '");
243  }
244  return (*it).second;
245  }
246 
248  _IntermodalEdge* getDepartEdge(const E* e, const SUMOReal pos = -1.) {
249  typename std::map<const E*, std::vector<_IntermodalEdge*> >::const_iterator it = myDepartLookup.find(e);
250  if (it == myDepartLookup.end()) {
251  throw ProcessError("Depart edge '" + e->getID() + "' not found in pedestrian network.");
252  }
253  const std::vector<_IntermodalEdge*>& splitList = it->second;
254  typename std::vector<_IntermodalEdge*>::const_iterator splitIt = splitList.begin();
255  SUMOReal totalLength = 0.;
256  while (splitIt != splitList.end() && totalLength + (*splitIt)->getLength() + POSITION_EPS < pos) {
257  totalLength += (*splitIt)->getLength();
258  ++splitIt;
259  }
260  return *splitIt;
261  }
262 
264  _IntermodalEdge* getArrivalEdge(const E* e, const SUMOReal pos = -1.) {
265  typename std::map<const E*, std::vector<_IntermodalEdge*> >::const_iterator it = myArrivalLookup.find(e);
266  if (it == myArrivalLookup.end()) {
267  throw ProcessError("Arrival edge '" + e->getID() + "' not found in pedestrian network.");
268  }
269  const std::vector<_IntermodalEdge*>& splitList = it->second;
270  typename std::vector<_IntermodalEdge*>::const_iterator splitIt = splitList.begin();
271  SUMOReal totalLength = 0.;
272  while (splitIt != splitList.end() && totalLength + (*splitIt)->getLength() + POSITION_EPS < pos) {
273  totalLength += (*splitIt)->getLength();
274  ++splitIt;
275  }
276  return *splitIt;
277  }
278 
279 
280 private:
282  std::vector<_IntermodalEdge*> myEdges;
283 
285  std::map<const E*, EdgePair> myBidiLookup;
286 
288  std::map<const E*, std::vector<_IntermodalEdge*> > myDepartLookup;
289 
291  std::map<const E*, std::vector<_IntermodalEdge*> > myArrivalLookup;
292 
293 };
294 
295 
296 #endif
297 
298 /****************************************************************************/
const std::vector< _IntermodalEdge * > & getAllEdges()
std::map< const E *, EdgePair > myBidiLookup
retrieve the forward and backward edge for the given input edge E
void addEdge(_IntermodalEdge *edge)
_IntermodalEdge * getDepartEdge(const E *e, const SUMOReal pos=-1.)
Returns the departing Intermodal edge.
void addSuccessor(IntermodalEdge *s)
IntermodalEdge< E, L, N, V > _IntermodalEdge
_IntermodalEdge * getArrivalEdge(const E *e, const SUMOReal pos=-1.)
Returns the arriving Intermodal edge.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
std::vector< _IntermodalEdge * > myEdges
the edge dictionary
PedestrianEdge< E, L, N, V > _PedestrianEdge
int getNumericalID() const
#define POSITION_EPS
Definition: config.h:188
std::pair< _IntermodalEdge *, _IntermodalEdge * > EdgePair
std::map< const E *, std::vector< _IntermodalEdge * > > myArrivalLookup
retrieve the arrival edges for the given input edge E
const E * getEdge() const
IntermodalNetwork(const std::vector< E * > &edges, int numericalID=0)
the pedestrian network storing edges, connections and the mappings to the "real" edges ...
the base edge type that is given to the internal router (SUMOAbstractRouter)
std::map< const E *, std::vector< _IntermodalEdge * > > myDepartLookup
retrieve the depart edges for the given input edge E
const EdgePair & getBothDirections(const E *e)
Returns the pair of forward and backward edge.
#define SUMOReal
Definition: config.h:214
the pedestrian edge type that is given to the internal router (SUMOAbstractRouter) ...
void addConnectors(_IntermodalEdge *const depConn, _IntermodalEdge *const arrConn, const int splitIndex)