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