SUMO - Simulation of Urban MObility
NBPTLineCont.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-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 // Container for NBPTLine during netbuild
17 /****************************************************************************/
18 
19 #include <iostream>
21 #include <utils/common/ToString.h>
24 #include "NBPTLineCont.h"
25 #include "NBPTStop.h"
26 #include "NBEdge.h"
27 #include "NBNode.h"
28 #include "NBVehicle.h"
29 #include "NBPTStopCont.h"
30 
31 // ===========================================================================
32 // static value definitions
33 // ===========================================================================
34 const int NBPTLineCont::FWD(1);
35 const int NBPTLineCont::BWD(-1);
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 
41  :
42  myIdCnt(0) { }
43 
44 
46  for (auto& myPTLine : myPTLines) {
47  delete myPTLine;
48  }
49  myPTLines.clear();
50 }
51 
52 void
54  pLine->setId(myIdCnt++);
55  myPTLines.push_back(pLine);
56 }
58  for (auto& myPTLine : myPTLines) {
59  reviseStops(myPTLine, cont);
60 
61  constructRoute(myPTLine, cont);
62 
63 
64  //
65 
66 
67 
68  }
69 }
71  std::vector<NBPTStop*> stops = myPTLine->getStops();
72  for (auto& stop : stops) {
73  //get the corresponding and one of the two adjacent ways
74  std::string origId = stop->getOrigEdgeId();
75 
76  std::vector<std::string> waysIds = myPTLine->getMyWays();
77  auto waysIdsIt = waysIds.begin();
78  if (waysIds.size() <= 1) {
79  WRITE_WARNING("Cannot revise pt stop localization for pt line: " + myPTLine->getName()
80  + ", which consist of one way only. Ignoring!");
81  continue;
82  }
83  for (; waysIdsIt != waysIds.end(); waysIdsIt++) {
84  if ((*waysIdsIt) == origId) {
85  break;
86  }
87  }
88 
89  if (waysIdsIt == waysIds.end()) {
90  for (auto& edgeCand : stop->getMyAdditionalEdgeCandidates()) {
91  bool found = false;
92  waysIdsIt = waysIds.begin();
93  for (; waysIdsIt != waysIds.end(); waysIdsIt++) {
94  if ((*waysIdsIt) == edgeCand.first) {
95  if (stop->setEdgeId(edgeCand.second, cont)) {
96  stop->setMyOrigEdgeId(edgeCand.first);
97  origId = edgeCand.first;
98  found = true;
99  break;
100  }
101  }
102  }
103  if (found) {
104  break;
105  }
106  }
107  }
108 
109 
110  if (waysIdsIt == waysIds.end()) {
111  WRITE_WARNING("Cannot revise pt stop localization for incomplete pt line: " + myPTLine->getName()
112  + ". Ignoring!");
113  continue;
114  }
115 
116  std::vector<long long int>* way = myPTLine->getWaysNodes(origId);
117  if (way == nullptr) {
118  WRITE_WARNING("Cannot revise pt stop localization for incomplete pt line: " + myPTLine->getName()
119  + ". Ignoring!");
120  continue;
121  }
122 
123 
124  int dir;
125  std::string adjIdPrev;
126  std::string adjIdNext;
127  if (waysIdsIt != waysIds.begin()) {
128  adjIdPrev = *(waysIdsIt - 1);
129  }
130  if (waysIdsIt != (waysIds.end() - 1)) {
131  adjIdNext = *(waysIdsIt + 1);
132  }
133  std::vector<long long int>* wayPrev = myPTLine->getWaysNodes(adjIdPrev);
134  std::vector<long long int>* wayNext = myPTLine->getWaysNodes(adjIdNext);
135  if (wayPrev == nullptr && wayNext == nullptr) {
136  WRITE_WARNING("Cannot revise pt stop localization for incomplete pt line: " + myPTLine->getName()
137  + ". Ignoring!");
138  continue;
139  }
140  long long int wayEnds = *(way->end() - 1);
141  long long int wayBegins = *(way->begin());
142  long long int wayPrevEnds = wayPrev != nullptr ? *(wayPrev->end() - 1) : 0;
143  long long int wayPrevBegins = wayPrev != nullptr ? *(wayPrev->begin()) : 0;
144  long long int wayNextEnds = wayNext != nullptr ? *(wayNext->end() - 1) : 0;
145  long long int wayNextBegins = wayNext != nullptr ? *(wayNext->begin()) : 0;
146  if (wayBegins == wayPrevEnds || wayBegins == wayPrevBegins || wayEnds == wayNextBegins
147  || wayEnds == wayNextEnds) {
148  dir = FWD;
149  } else if (wayEnds == wayPrevBegins || wayEnds == wayPrevEnds || wayBegins == wayNextEnds
150  || wayBegins == wayNextBegins) {
151  dir = BWD;
152  } else {
153  WRITE_WARNING("Cannot revise pt stop localization for incomplete pt line: " + myPTLine->getName()
154  + ". Ignoring!");
155  continue;
156  }
157 
158  std::string edgeId = stop->getEdgeId();
159  NBEdge* current = cont.getByID(edgeId);
160  int assignedTo = edgeId.at(0) == '-' ? BWD : FWD;
161 
162  if (dir != assignedTo) {
163  NBEdge* reverse = NBPTStopCont::getReverseEdge(current);
164  if (reverse == nullptr) {
165  WRITE_WARNING("Could not re-assign PT stop: " + stop->getID() + " probably broken osm file");
166  continue;
167  }
168  stop->setEdgeId(reverse->getID(), cont);
169  WRITE_WARNING("PT stop: " + stop->getID() + " has been moved to edge: " + reverse->getID());
170  }
171  myServedPTStops.insert(stop->getID());
172  stop->addLine(myPTLine->getRef());
173  }
174 }
175 
176 
178  std::vector<NBEdge*> edges;
179 
180  NBNode* first = nullptr;
181  NBNode* last = nullptr;
182  std::vector<NBEdge*> prevWayEdges;
183  std::vector<NBEdge*> prevWayMinusEdges;
184  prevWayEdges.clear();
185  prevWayMinusEdges.clear();
186  std::vector<NBEdge*> currentWayEdges;
187  std::vector<NBEdge*> currentWayMinusEdges;
188  for (auto it3 = pTLine->getMyWays().begin();
189  it3 != pTLine->getMyWays().end(); it3++) {
190 
191  if (cont.retrieve(*it3, false) != nullptr) {
192  currentWayEdges.push_back(cont.retrieve(*it3, false));
193  } else {
194  int i = 0;
195  while (cont.retrieve(*it3 + "#" + std::to_string(i), false) != nullptr) {
196  currentWayEdges.push_back(cont.retrieve(*it3 + "#" + std::to_string(i), false));
197  i++;
198  }
199  }
200 
201  if (cont.retrieve("-" + *it3, false) != nullptr) {
202  currentWayMinusEdges.push_back(cont.retrieve("-" + *it3, false));
203  } else {
204  int i = 0;
205  while (cont.retrieve("-" + *it3 + "#" + std::to_string(i), false) != nullptr) {
206  currentWayMinusEdges.insert(currentWayMinusEdges.begin(),
207  cont.retrieve("-" + *it3 + "#" + std::to_string(i), false));
208  i++;
209  }
210  }
211  if (currentWayEdges.empty()) {
212  continue;
213  }
214  if (last == currentWayEdges.front()->getFromNode() && last != nullptr) {
215  if (!prevWayEdges.empty()) {
216  edges.insert(edges.end(), prevWayEdges.begin(), prevWayEdges.end());
217  prevWayEdges.clear();
218  prevWayMinusEdges.clear();
219  }
220  edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
221  last = currentWayEdges.back()->getToNode();
222  } else if (last == currentWayEdges.back()->getToNode() && last != nullptr) {
223  if (!prevWayEdges.empty()) {
224  edges.insert(edges.end(), prevWayEdges.begin(), prevWayEdges.end());
225  prevWayEdges.clear();
226  prevWayMinusEdges.clear();
227  }
228  if (currentWayMinusEdges.empty()) {
229  currentWayEdges.clear();
230  last = nullptr;
231  continue;
232  } else {
233  edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
234  last = currentWayMinusEdges.back()->getToNode();
235  }
236  } else if (first == currentWayEdges.front()->getFromNode() && first != nullptr) {
237  edges.insert(edges.end(), prevWayMinusEdges.begin(), prevWayMinusEdges.end());
238  edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
239  last = currentWayEdges.back()->getToNode();
240  prevWayEdges.clear();
241  prevWayMinusEdges.clear();
242  } else if (first == currentWayEdges.back()->getToNode() && first != nullptr) {
243  edges.insert(edges.end(), prevWayMinusEdges.begin(), prevWayMinusEdges.end());
244  if (currentWayMinusEdges.empty()) {
245  currentWayEdges.clear();
246  last = nullptr;
247  prevWayEdges.clear();
248  prevWayMinusEdges.clear();
249  continue;
250  } else {
251  edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
252  last = currentWayMinusEdges.back()->getToNode();
253  prevWayEdges.clear();
254  prevWayMinusEdges.clear();
255  }
256  } else {
257  if (it3 != pTLine->getMyWays().begin()) {
258  WRITE_WARNING("Incomplete route for ptline '" + toString(pTLine->getLineID()) + "' (" + pTLine->getName() + ")");
259  }
260  prevWayEdges = currentWayEdges;
261  prevWayMinusEdges = currentWayMinusEdges;
262  if (!prevWayEdges.empty()) {
263  first = prevWayEdges.front()->getFromNode();
264  last = prevWayEdges.back()->getToNode();
265  } else {
266  first = nullptr;
267  last = nullptr;
268  }
269  }
270  currentWayEdges.clear();
271  currentWayMinusEdges.clear();
272  }
273 
274  auto fr = edges.begin();
275  NBPTStop* frStop = pTLine->getStops()[0];
276  for (; fr != edges.end(); fr++) {
277  if ((*fr)->getID() == frStop->getEdgeId()) {
278  break;
279  }
280  }
281  auto to = fr;
282  NBPTStop* toStop = *(pTLine->getStops().end() - 1);
283  for (; to != edges.end(); to++) {
284  if ((*to)->getID() == toStop->getEdgeId()) {
285  to++;
286  break;
287  }
288  }
289 
290  pTLine->addEdgeVector(fr, to);
291 }
292 
293 
294 void
295 NBPTLineCont::addEdges2Keep(const OptionsCont& oc, std::set<std::string>& into) {
296  if (oc.isSet("ptline-output")) {
297  for (auto line : myPTLines) {
298  for (auto edge : line->getRoute()) {
299  into.insert(edge->getID());
300  }
301  }
302  }
303 }
304 
305 
306 std::set<std::string>&
308  return myServedPTStops;
309 }
310 
311 
312 void
314  std::map<std::string, SUMOVehicleClass> types;
315  types["bus"] = SVC_BUS;
316  types["tram"] = SVC_TRAM;
317  types["train"] = SVC_RAIL;
318  types["subway"] = SVC_RAIL_URBAN;
319  types["light_rail"] = SVC_RAIL_URBAN;
320  types["ferry"] = SVC_SHIP;
321 
324  ec.getAllEdges(), true, &NBEdge::getTravelTimeStatic, nullptr, true);
325 
326  for (NBPTLine* line : myPTLines) {
327  std::vector<NBPTStop*> stops = line->getStops();
328  if (stops.size() < 2) {
329  continue;
330  }
331  if (types.count(line->getType()) == 0) {
332  WRITE_WARNING("Could not determine vehicle class for public transport line of type '"
333  + line->getType() + "'.");
334  continue;
335  }
336  NBVehicle veh(line->getRef(), types[line->getType()]);
337  std::vector<NBPTStop*> newStops;
338  NBPTStop* from = nullptr;
339  for (auto it = stops.begin(); it != stops.end(); ++it) {
340  NBPTStop* to = *it;
341  NBPTStop* used = *it;
342  if (to->getBidiStop() != nullptr) {
343  double best = std::numeric_limits<double>::max();
344  NBPTStop* to2 = to->getBidiStop();
345  if (from == nullptr) {
346  if ((it + 1) != stops.end()) {
347  from = to;
348  NBPTStop* from2 = to2;
349  to = *(it + 1);
350  const double c1 = getCost(ec, *router, from, to, &veh);
351  const double c2 = getCost(ec, *router, from2, to, &veh);
352  //std::cout << " from=" << from->getID() << " to=" << to->getID() << " c1=" << MIN2(10000.0, c1) << "\n";
353  //std::cout << " from2=" << from2->getID() << " to=" << to->getID() << " c2=" << MIN2(10000.0, c2) << "\n";
354  best = c1;
355  if (to->getBidiStop() != nullptr) {
356  to2 = to->getBidiStop();
357  const double c3 = getCost(ec, *router, from, to2, &veh);
358  const double c4 = getCost(ec, *router, from2, to2, &veh);
359  //std::cout << " from=" << from->getID() << " to2=" << to2->getID() << " c3=" << MIN2(10000.0, c3) << "\n";
360  //std::cout << " from2=" << from2->getID() << " to2=" << to2->getID() << " c4=" << MIN2(10000.0, c4) << "\n";
361  if (c2 < best) {
362  used = from2;
363  best = c2;
364  }
365  if (c3 < best) {
366  used = from;
367  best = c3;
368  }
369  if (c4 < best) {
370  used = from2;
371  best = c4;
372  }
373  } else {
374  if (c2 < c1) {
375  used = from2;
376  best = c2;
377  } else {
378  best = c1;
379  }
380  }
381  }
382  } else {
383  const double c1 = getCost(ec, *router, from, to, &veh);
384  const double c2 = getCost(ec, *router, from, to2, &veh);
385  //std::cout << " from=" << from->getID() << " to=" << to->getID() << " c1=" << MIN2(10000.0, c1) << "\n";
386  //std::cout << " from=" << from->getID() << " t2o=" << to2->getID() << " c2=" << MIN2(10000.0, c2) << "\n";
387  if (c2 < c1) {
388  used = to2;
389  best = c2;
390  } else {
391  best = c1;
392  }
393 
394  }
395  if (best < std::numeric_limits<double>::max()) {
396  from = used;
397  } else {
398  WRITE_WARNING("Could not determine direction for line '" + toString(line->getLineID()) + "' at stop '" + used->getID() + "'");
399  };
400  }
401  from = used;
402  newStops.push_back(used);
403  }
404  assert(stops.size() == newStops.size());
405  line->replaceStops(newStops);
406  }
407  delete router;
408 }
409 
410 
411 double
413  const NBPTStop* from, const NBPTStop* to, const NBVehicle* veh) {
414  NBEdge* fromEdge = ec.getByID(from->getEdgeId());
415  NBEdge* toEdge = ec.getByID(to->getEdgeId());
416  if (fromEdge == nullptr || toEdge == nullptr) {
417  return std::numeric_limits<double>::max();
418  }
419  std::vector<const NBEdge*> route;
420  router.compute(fromEdge, toEdge, veh, 0, route);
421  if (route.size() == 0) {
422  return std::numeric_limits<double>::max();
423  } else {
424  return router.recomputeCosts(route, veh, 0);
425  }
426 }
std::vector< long long int > * getWaysNodes(std::string wayId)
Definition: NBPTLine.cpp:112
NBEdge * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
void reviseStops(NBPTLine *myPTLine, NBEdgeCont &cont)
vehicle is a not electrified rail
The representation of a single edge during network building.
Definition: NBEdge.h:65
vehicle is a light rail
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...
NBPTStop * getBidiStop() const
Definition: NBPTStop.h:88
static const int BWD
Definition: NBPTLineCont.h:69
std::string getID() const
Definition: NBPTStop.cpp:48
const std::string & getID() const
Returns the id.
Definition: Named.h:78
The representation of a single pt stop.
Definition: NBPTStop.h:45
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
const std::vector< std::string > & getMyWays() const
Definition: NBPTLine.cpp:109
void fixBidiStops(const NBEdgeCont &ec)
select the correct stop on superposed rail edges
vehicle is a city rail
void process(NBEdgeCont &cont)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
const std::string & getRef() const
get line reference (not unique)
Definition: NBPTLine.h:55
std::set< std::string > & getServedPTStops()
void insert(NBPTLine *pLine)
insert new line
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.
void addEdgeVector(std::vector< NBEdge *>::iterator fr, std::vector< NBEdge *>::iterator to)
Definition: NBPTLine.cpp:119
static double getCost(const NBEdgeCont &ec, SUMOAbstractRouter< NBEdge, NBVehicle > &router, const NBPTStop *from, const NBPTStop *to, const NBVehicle *veh)
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:61
static const int FWD
Definition: NBPTLineCont.h:68
A vehicle as used by router.
Definition: NBVehicle.h:44
void addEdges2Keep(const OptionsCont &oc, std::set< std::string > &into)
add edges that must be kept
long long int myIdCnt
Definition: NBPTLineCont.h:74
is an arbitrary ship
~NBPTLineCont()
destructor
vehicle is a bus
EdgeVector getAllEdges() const
return all edges
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:245
A storage for options typed value containers)
Definition: OptionsCont.h:92
static double getTravelTimeStatic(const NBEdge *const edge, const NBVehicle *const, double)
Definition: NBEdge.h:1270
Represents a single node (junction) during network building.
Definition: NBNode.h:68
const std::string & getName() const
Definition: NBPTLine.cpp:40
double recomputeCosts(const std::vector< const E *> &edges, const V *const v, SUMOTime msTime) const
std::vector< NBPTStop * > getStops()
Definition: NBPTLine.cpp:49
void constructRoute(NBPTLine *myPTLine, NBEdgeCont &cont)
NBPTLineCont()
constructor
long long int getLineID() const
Definition: NBPTLine.cpp:45
static NBEdge * getReverseEdge(NBEdge *edge)
const std::string getEdgeId() const
Definition: NBPTStop.cpp:59
void setId(long long int id)
Definition: NBPTLine.cpp:97
std::set< std::string > myServedPTStops
Definition: NBPTLineCont.h:78
std::vector< NBPTLine * > myPTLines
The map of names to pt lines.
Definition: NBPTLineCont.h:72