Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NBPTLineCont.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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/****************************************************************************/
19// Container for NBPTLine during netbuild
20/****************************************************************************/
21#include <config.h>
22
23#include <iostream>
28#include "NBPTLineCont.h"
29#include "NBPTStop.h"
30#include "NBEdge.h"
31#include "NBNode.h"
32#include "NBVehicle.h"
33#include "NBPTStopCont.h"
34
35//#define DEBUG_FIND_WAY
36//#define DEBUG_CONSTRUCT_ROUTE
37
38#define DEBUGLINEID ""
39#define DEBUGSTOPID ""
40
41// ===========================================================================
42// static value definitions
43// ===========================================================================
44const int NBPTLineCont::FWD(1);
45const int NBPTLineCont::BWD(-1);
46
47
48// ===========================================================================
49// method definitions
50// ===========================================================================
52 for (auto& myPTLine : myPTLines) {
53 delete myPTLine.second;
54 }
55 myPTLines.clear();
56}
57
58
59bool
61 if (myPTLines.count(ptLine->getLineID()) == 0) {
62 myPTLines[ptLine->getLineID()] = ptLine;
63 return true;
64 }
65 return false;
66}
67
68
70NBPTLineCont::retrieve(const std::string& lineID) {
71 if (myPTLines.count(lineID) == 0) {
72 return nullptr;
73 } else {
74 return myPTLines[lineID];
75 }
76}
77
78void
80 for (auto& item : myPTLines) {
81 NBPTLine* line = item.second;
82 if (item.second->getWays().size() > 0) {
83 // loaded from OSM rather than ptline input. We can use extra
84 // information to reconstruct route and stops
85 constructRoute(line, ec);
86 if (!routeOnly) {
87 // map stops to ways, using the constructed route for loose stops
88 reviseStops(line, ec, sc);
89 }
90 }
91 // fix circular line if necessary
92 if (line->getStops().size() > 1
93 && line->getStops().front() == line->getStops().back()
94 && line->getRoute().size() > 1
95 && line->getRoute().front() != line->getRoute().back()) {
96 // we need to duplicate either the first or the last edge depending on the stop locations
97 const std::string firstStopEdge = line->getStops().front()->getEdgeId();
98 const std::string lastStopEdge = line->getStops().back()->getEdgeId();
99 std::vector<NBEdge*> edges = line->getRoute();
100 if (firstStopEdge == edges.back()->getID()) {
101 edges.insert(edges.begin(), edges.back());
102 } else if (lastStopEdge == edges.front()->getID()) {
103 edges.push_back(edges.front());
104 }
105 line->setEdges(edges);
106 }
107 line->deleteInvalidStops(ec, sc);
108 //line->deleteDuplicateStops();
109 }
110}
111
112
113void
115 const std::vector<std::string>& waysIds = line->getWays();
116 if (waysIds.size() == 1 && line->getStops().size() > 1) {
117 reviseSingleWayStops(line, ec, sc);
118 return;
119 }
120 if (waysIds.size() <= 1) {
121 WRITE_WARNINGF(TL("Cannot revise pt stop localization for pt line '%', which consist of one way only. Ignoring!"), line->getLineID());
122 return;
123 }
124 if (line->getRoute().size() == 0) {
125 WRITE_WARNINGF(TL("Cannot revise pt stop localization for pt line '%', which has no route edges. Ignoring!"), line->getLineID());
126 return;
127 }
128 std::vector<std::shared_ptr<NBPTStop> > stops = line->getStops();
129 std::vector<bool> stopsRevised;
130 for (std::shared_ptr<NBPTStop> stop : stops) {
131 stopsRevised.push_back(false);
132 //get the corresponding and one of the two adjacent ways
133 stop = findWay(line, stop, ec, sc);
134 if (stop == nullptr) {
135 // warning already given
136 continue;
137 }
138 auto waysIdsIt = std::find(waysIds.begin(), waysIds.end(), stop->getOrigEdgeId());
139 if (waysIdsIt == waysIds.end()) {
140 // warning already given
141 continue;
142 }
143 // find directional edge (OSM ways are bidirectional)
144 const std::vector<long long int>* const way = line->getWayNodes(stop->getOrigEdgeId());
145 if (way == nullptr) {
146 WRITE_WARNINGF(TL("Cannot assign stop '%' on edge '%' to pt line '%' (wayNodes not found). Ignoring!"),
147 stop->getID(), stop->getOrigEdgeId(), line->getLineID());
148 continue;
149 }
150
151 int dir;
152 const std::vector<long long int>* wayPrev = nullptr;
153 if (waysIdsIt != waysIds.begin()) {
154 wayPrev = line->getWayNodes(*(waysIdsIt - 1));
155 }
156 const std::vector<long long int>* wayNext = nullptr;
157 if (waysIdsIt != (waysIds.end() - 1)) {
158 wayNext = line->getWayNodes(*(waysIdsIt + 1));
159 }
160 if (wayPrev == nullptr && wayNext == nullptr) {
161 WRITE_WARNINGF(TL("Cannot revise pt stop localization for incomplete pt line '%'. Ignoring!"), line->getLineID());
162 continue;
163 }
164 const long long int wayEnds = way->back();
165 const long long int wayBegins = way->front();
166 const long long int wayPrevEnds = wayPrev != nullptr ? wayPrev->back() : 0;
167 const long long int wayPrevBegins = wayPrev != nullptr ? wayPrev->front() : 0;
168 const long long int wayNextEnds = wayNext != nullptr ? wayNext->back() : 0;
169 const long long int wayNextBegins = wayNext != nullptr ? wayNext->front() : 0;
170 if (wayBegins == wayPrevEnds || wayBegins == wayPrevBegins || wayEnds == wayNextBegins || wayEnds == wayNextEnds) {
171 dir = FWD;
172 } else if (wayEnds == wayPrevBegins || wayEnds == wayPrevEnds || wayBegins == wayNextEnds || wayBegins == wayNextBegins) {
173 dir = BWD;
174 } else {
175 WRITE_WARNINGF(TL("Cannot revise pt stop localization for incomplete pt line '%'. Ignoring!"), line->getLineID());
176 continue;
177 }
178
179 std::string edgeId = stop->getEdgeId();
180 NBEdge* current = ec.getByID(edgeId);
181 int assignedDir = edgeId.at(0) == '-' ? BWD : FWD;
182
183 if (dir != assignedDir) {
184 NBEdge* reverse = NBPTStopCont::getReverseEdge(current);
185 if (reverse == nullptr) {
187 if (!oc.getBool("railway.topology.repair") && oc.getBool("ptstop-output.no-bidi")) {
188 WRITE_WARNINGF(TL("Could not re-assign PT stop '%'. May need option --railway.topology.repair"), stop->getID());
189 }
190 continue;
191 }
192 if (stop->getLines().size() > 0) {
193 std::shared_ptr<NBPTStop> reverseStop = sc.getReverseStop(stop, ec);
194 sc.insert(reverseStop);
195 line->replaceStop(stop, reverseStop);
196 stop = reverseStop;
197 } else {
198 WRITE_WARNINGF(TL("PT stop '%' has been moved to edge '%'."), stop->getID(), reverse->getID());
199 }
200 stop->setEdgeId(reverse->getID(), ec);
201 }
202 stop->addLine(line->getRef());
203 stopsRevised.back() = true;
204 }
205 line->setRevised(stopsRevised);
206}
207
208
210 const std::vector<std::string>& waysIds = line->getWays();
211 for (std::shared_ptr<NBPTStop> stop : line->getStops()) {
212 //get the corresponding and one of the two adjacent ways
213 stop = findWay(line, stop, ec, sc);
214 if (stop == nullptr) {
215 // warning already given
216 continue;
217 }
218 auto waysIdsIt = std::find(waysIds.begin(), waysIds.end(), stop->getOrigEdgeId());
219 if (waysIdsIt == waysIds.end()) {
220 // warning already given
221 continue;
222 }
223 stop->addLine(line->getRef());
224 }
225}
226
227
228std::shared_ptr<NBPTStop>
229NBPTLineCont::findWay(NBPTLine* line, std::shared_ptr<NBPTStop> stop, const NBEdgeCont& ec, NBPTStopCont& sc) const {
230 const std::vector<std::string>& waysIds = line->getWays();
231#ifdef DEBUG_FIND_WAY
232 if (stop->getID() == DEBUGSTOPID) {
233 std::cout << " stop=" << stop->getID() << " line=" << line->getLineID() << " edgeID=" << stop->getEdgeId() << " origID=" << stop->getOrigEdgeId() << "\n";
234 }
235#endif
236 if (stop->isLoose()) {
237 // find closest edge in route
238 double minDist = std::numeric_limits<double>::max();
239 NBEdge* best = nullptr;
240 for (NBEdge* edge : line->getRoute()) {
241 const double dist = edge->getLaneShape(0).distance2D(stop->getPosition());
242 if (dist < minDist) {
243 best = edge;
244 minDist = dist;
245 }
246 }
247#ifdef DEBUG_FIND_WAY
248 if (stop->getID() == DEBUGSTOPID) {
249 std::cout << " best=" << Named::getIDSecure(best) << " minDist=" << minDist << " wayID=" << getWayID(best->getID())
250 << " found=" << (std::find(waysIds.begin(), waysIds.end(), getWayID(best->getID())) != waysIds.end())
251 << " wayIDs=" << toString(waysIds) << "\n";
252 }
253#endif
254 if (minDist < OptionsCont::getOptions().getFloat("ptline.match-dist")) {
255 const std::string wayID = getWayID(best->getID());
256 if (stop->getEdgeId() == "") {
257 stop->setEdgeId(best->getID(), ec);
258 stop->setOrigEdgeId(wayID);
259 } else if (stop->getEdgeId() != best->getID()) {
260 // stop is used by multiple lines and mapped to different edges.
261 // check if an alternative stop already exists
262 std::shared_ptr<NBPTStop> newStop = sc.findStop(wayID, stop->getPosition());
263 if (newStop == nullptr) {
264 newStop = std::make_shared<NBPTStop>(stop->getElement(), stop->getID() + "@" + line->getLineID(), stop->getPosition(), best->getID(), wayID, stop->getLength(), stop->getName(), stop->getPermissions());
265 newStop->setEdgeId(best->getID(), ec); // trigger lane assignment
266 sc.insert(newStop);
267 }
268 line->replaceStop(stop, newStop);
269 stop = newStop;
270 }
271 } else {
272 WRITE_WARNINGF(TL("Could not assign stop '%' to pt line '%' (closest edge '%', distance %). Ignoring!"),
273 stop->getID(), line->getLineID(), Named::getIDSecure(best), minDist);
274 return nullptr;
275 }
276 } else {
277 // if the stop is part of an edge, find that edge among the line edges
278 auto waysIdsIt = waysIds.begin();
279 for (; waysIdsIt != waysIds.end(); waysIdsIt++) {
280 if ((*waysIdsIt) == stop->getOrigEdgeId()) {
281 break;
282 }
283 }
284
285 if (waysIdsIt == waysIds.end()) {
286 // stop edge not found, try additional edges
287 for (auto& edgeCand : stop->getAdditionalEdgeCandidates()) {
288 bool found = false;
289 waysIdsIt = waysIds.begin();
290 for (; waysIdsIt != waysIds.end(); waysIdsIt++) {
291 if ((*waysIdsIt) == edgeCand.first) {
292 if (stop->setEdgeId(edgeCand.second, ec)) {
293 stop->setOrigEdgeId(edgeCand.first);
294 found = true;
295 break;
296 }
297 }
298 }
299 if (found) {
300 break;
301 }
302 }
303 if (waysIdsIt == waysIds.end()) {
304 WRITE_WARNINGF(TL("Cannot assign stop % on edge '%' to pt line '%'. Ignoring!"), stop->getID(), stop->getOrigEdgeId(), line->getLineID());
305 }
306 }
307 }
308 return stop;
309}
310
311
313 std::vector<NBEdge*> edges;
314
315 NBNode* first = nullptr;
316 NBNode* last = nullptr;
317 std::vector<NBEdge*> prevWayEdges;
318 std::vector<NBEdge*> prevWayMinusEdges;
319 std::vector<NBEdge*> currentWayEdges;
320 std::vector<NBEdge*> currentWayMinusEdges;
321 for (auto it3 = pTLine->getWays().begin(); it3 != pTLine->getWays().end(); it3++) {
322
323 int foundForward = 0;
324 if (cont.retrieve(*it3, false) != nullptr) {
325 currentWayEdges.push_back(cont.retrieve(*it3, false));
326 foundForward++;
327 } else {
328 int i = 0;
329 while (cont.retrieve(*it3 + "#" + std::to_string(i), true) != nullptr) {
330 if (cont.retrieve(*it3 + "#" + std::to_string(i), false)) {
331 currentWayEdges.push_back(cont.retrieve(*it3 + "#" + std::to_string(i), false));
332 foundForward++;
333 }
334 i++;
335 }
336 }
337
338 int foundReverse = 0;
339 if (cont.retrieve("-" + *it3, false) != nullptr) {
340 currentWayMinusEdges.push_back(cont.retrieve("-" + *it3, false));
341 foundReverse++;
342 } else {
343 int i = 0;
344 while (cont.retrieve("-" + *it3 + "#" + std::to_string(i), true) != nullptr) {
345 if (cont.retrieve("-" + *it3 + "#" + std::to_string(i), false)) {
346 currentWayMinusEdges.insert(currentWayMinusEdges.end() - foundReverse,
347 cont.retrieve("-" + *it3 + "#" + std::to_string(i), false));
348 foundReverse++;
349 }
350 i++;
351 }
352 }
353 bool fakeMinus = false;
354 if (foundReverse == 0 && foundForward > 0 && isRailway(pTLine->getVClass())) {
355 // rail tracks may be used in both directions and are often not tagged as such.
356 // This can be repaired later with option --railway.topology.repair
357 currentWayMinusEdges.insert(currentWayMinusEdges.begin(), currentWayEdges.rbegin(), currentWayEdges.rbegin() + foundForward);
358 fakeMinus = true;
359 }
360#ifdef DEBUG_CONSTRUCT_ROUTE
361 if (pTLine->getLineID() == DEBUGLINEID) {
362 std::cout << " way=" << (*it3)
363 << " done=" << toString(edges)
364 << " first=" << Named::getIDSecure(first)
365 << " last=" << Named::getIDSecure(last)
366 << "\n +=" << toString(currentWayEdges)
367 << "\n -=" << toString(currentWayMinusEdges)
368 << "\n p+=" << toString(prevWayEdges)
369 << "\n p-=" << toString(prevWayMinusEdges)
370 << "\n";
371 }
372#endif
373 if (currentWayEdges.empty()) {
374 continue;
375 }
376 if (last == currentWayEdges.front()->getFromNode() && last != nullptr) {
377 if (!prevWayEdges.empty()) {
378 edges.insert(edges.end(), prevWayEdges.begin(), prevWayEdges.end());
379 prevWayEdges.clear();
380 prevWayMinusEdges.clear();
381 }
382 edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
383 last = currentWayEdges.back()->getToNode();
384 } else if (last == currentWayEdges.back()->getToNode() && last != nullptr) {
385 if (!prevWayEdges.empty()) {
386 edges.insert(edges.end(), prevWayEdges.begin(), prevWayEdges.end());
387 prevWayEdges.clear();
388 prevWayMinusEdges.clear();
389 }
390 if (currentWayMinusEdges.empty()) {
391 currentWayEdges.clear();
392 last = nullptr;
393 continue;
394 } else {
395 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
396 if (fakeMinus) {
397 last = currentWayMinusEdges.back()->getFromNode();
398 } else {
399 last = currentWayMinusEdges.back()->getToNode();
400 }
401 }
402 } else if (first == currentWayEdges.front()->getFromNode() && first != nullptr) {
403 edges.insert(edges.end(), prevWayMinusEdges.begin(), prevWayMinusEdges.end());
404 edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
405 last = currentWayEdges.back()->getToNode();
406 prevWayEdges.clear();
407 prevWayMinusEdges.clear();
408 } else if (first == currentWayEdges.back()->getToNode() && first != nullptr) {
409 edges.insert(edges.end(), prevWayMinusEdges.begin(), prevWayMinusEdges.end());
410 if (currentWayMinusEdges.empty()) {
411 currentWayEdges.clear();
412 last = nullptr;
413 prevWayEdges.clear();
414 prevWayMinusEdges.clear();
415 continue;
416 } else {
417 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
418 last = currentWayMinusEdges.back()->getToNode();
419 prevWayEdges.clear();
420 prevWayMinusEdges.clear();
421 }
422 } else {
423 if (it3 != pTLine->getWays().begin()) {
424#ifdef DEBUG_CONSTRUCT_ROUTE
425 if (pTLine->getLineID() == DEBUGLINEID) {
426 std::cout << " way " << (*it3)
427 << " is not the start of ptline " << pTLine->getLineID()
428 << " (" + pTLine->getName() + ")\n";
429 }
430#endif
431 } else if (pTLine->getWays().size() == 1) {
432 if (currentWayEdges.size() > 0) {
433 edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
434 } else {
435 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
436 }
437 }
438 prevWayEdges = currentWayEdges;
439 prevWayMinusEdges = currentWayMinusEdges;
440 if (!prevWayEdges.empty()) {
441 first = prevWayEdges.front()->getFromNode();
442 last = prevWayEdges.back()->getToNode();
443 } else {
444 first = nullptr;
445 last = nullptr;
446 }
447 }
448 currentWayEdges.clear();
449 currentWayMinusEdges.clear();
450 }
451 pTLine->setEdges(edges);
452}
453
454
455void
456NBPTLineCont::replaceEdge(const std::string& edgeID, const EdgeVector& replacement) {
457 //std::cout << " replaceEdge " << edgeID << " replacement=" << toString(replacement) << "\n";
458 if (myPTLines.size() > 0 && myPTLineLookup.size() == 0) {
459 // init lookup once
460 for (auto& item : myPTLines) {
461 for (const NBEdge* e : item.second->getRoute()) {
462 myPTLineLookup[e->getID()].insert(item.second);
463 }
464 }
465 }
466 for (NBPTLine* line : myPTLineLookup[edgeID]) {
467 line->replaceEdge(edgeID, replacement);
468 for (const NBEdge* e : replacement) {
469 myPTLineLookup[e->getID()].insert(line);
470 }
471 }
472 myPTLineLookup.erase(edgeID);
473}
474
475
476std::set<std::string>
478 std::set<std::string> result;
479 for (auto& item : myPTLines) {
480 NBPTLine* line = item.second;
481 for (std::shared_ptr<NBPTStop> stop : line->getStops()) {
482 result.insert(stop->getID());
483 }
484 }
485 return result;
486}
487
488
489void
491 std::map<std::string, SUMOVehicleClass> types;
492 types["bus"] = SVC_BUS;
493 types["minibus"] = SVC_BUS;
494 types["trolleybus"] = SVC_BUS;
495 types["tram"] = SVC_TRAM;
496 types["train"] = SVC_RAIL;
497 types["subway"] = SVC_RAIL_URBAN;
498 types["light_rail"] = SVC_RAIL_URBAN;
499 types["monorail"] = SVC_RAIL_URBAN;
500 types["aerialway"] = SVC_RAIL_URBAN;
501 types["ferry"] = SVC_SHIP;
502
504 ec.getAllRouterEdges(), true, &NBRouterEdge::getTravelTimeStatic, nullptr, true);
505
506 for (auto& item : myPTLines) {
507 NBPTLine* line = item.second;
508 std::vector<std::shared_ptr<NBPTStop> > stops = line->getStops();
509 if (stops.size() < 2) {
510 continue;
511 }
512 if (types.count(line->getType()) == 0) {
513 WRITE_WARNINGF(TL("Could not determine vehicle class for public transport line of type '%'."), line->getType());
514 continue;
515 }
516 NBVehicle veh(line->getRef(), types[line->getType()]);
517 std::vector<std::shared_ptr<NBPTStop> > newStops;
518 std::shared_ptr<NBPTStop> from = nullptr;
519 std::vector<NBPTLine::PTStopInfo> stopInfos = line->getStopEdges(ec);
520 assert(stopInfos.size() == stops.size());
521 for (auto it = stops.begin(); it != stops.end(); ++it) {
522 std::shared_ptr<NBPTStop> to = *it;
523 std::shared_ptr<NBPTStop> used = *it;
524 bool isRevised = stopInfos[it - stops.begin()].revised;
525 if (to->getBidiStop() != nullptr && !isRevised) {
526 double best = std::numeric_limits<double>::max();
527 std::shared_ptr<NBPTStop> to2 = to->getBidiStop();
528 if (from == nullptr) {
529 if ((it + 1) != stops.end()) {
530 from = to;
531 std::shared_ptr<NBPTStop> from2 = to2;
532 to = *(it + 1);
533 const double c1 = getCost(ec, *router, from, to, &veh);
534 const double c2 = getCost(ec, *router, from2, to, &veh);
535 //std::cout << " from=" << from->getID() << " to=" << to->getID() << " c1=" << MIN2(10000.0, c1) << "\n";
536 //std::cout << " from2=" << from2->getID() << " to=" << to->getID() << " c2=" << MIN2(10000.0, c2) << "\n";
537 best = c1;
538 if (to->getBidiStop() != nullptr) {
539 to2 = to->getBidiStop();
540 const double c3 = getCost(ec, *router, from, to2, &veh);
541 const double c4 = getCost(ec, *router, from2, to2, &veh);
542 //std::cout << " from=" << from->getID() << " to2=" << to2->getID() << " c3=" << MIN2(10000.0, c3) << "\n";
543 //std::cout << " from2=" << from2->getID() << " to2=" << to2->getID() << " c4=" << MIN2(10000.0, c4) << "\n";
544 if (c2 < best) {
545 used = from2;
546 best = c2;
547 }
548 if (c3 < best) {
549 used = from;
550 best = c3;
551 }
552 if (c4 < best) {
553 used = from2;
554 best = c4;
555 }
556 } else {
557 if (c2 < c1) {
558 used = from2;
559 best = c2;
560 } else {
561 best = c1;
562 }
563 }
564 }
565 } else {
566 const double c1 = getCost(ec, *router, from, to, &veh);
567 const double c2 = getCost(ec, *router, from, to2, &veh);
568 //std::cout << " from=" << from->getID() << " to=" << to->getID() << " c1=" << MIN2(10000.0, c1) << "\n";
569 //std::cout << " from=" << from->getID() << " t2o=" << to2->getID() << " c2=" << MIN2(10000.0, c2) << "\n";
570 if (c2 < c1) {
571 used = to2;
572 best = c2;
573 } else {
574 best = c1;
575 }
576
577 }
578 if (best < std::numeric_limits<double>::max()) {
579 from = used;
580 } else {
581 WRITE_WARNINGF(TL("Could not determine direction for line '%' at stop '%'."), line->getLineID(), used->getID());
582 }
583 }
584 from = used;
585 newStops.push_back(used);
586 }
587 assert(stops.size() == newStops.size());
588 line->replaceStops(newStops);
589 }
590 delete router;
591}
592
593
594void
596 for (auto& item : myPTLines) {
597 item.second->removeInvalidEdges(ec);
598 }
599}
600
601
602void
604 for (auto& item : myPTLines) {
605 NBPTLine* line = item.second;
606 const std::vector<NBEdge*>& route = line->getRoute();
607 const SUMOVehicleClass svc = line->getVClass();
608 for (int i = 1; i < (int)route.size(); i++) {
609 NBEdge* e1 = route[i - 1];
610 NBEdge* e2 = route[i];
611 std::vector<NBEdge::Connection> cons = e1->getConnectionsFromLane(-1, e2, -1);
612 if (cons.size() == 0) {
613 //WRITE_WARNINGF(TL("Disconnected ptline '%' between edge '%' and edge '%'"), line->getLineID(), e1->getID(), e2->getID());
614 } else {
615 bool ok = false;
616 for (const auto& c : cons) {
617 if ((e1->getPermissions(c.fromLane) & svc) == svc) {
618 ok = true;
619 break;
620 }
621 }
622 if (!ok) {
623 int lane = cons[0].fromLane;
624 e1->setPermissions(e1->getPermissions(lane) | svc, lane);
625 }
626 }
627 }
628 }
629}
630
631
632double
634 const std::shared_ptr<NBPTStop> from, const std::shared_ptr<NBPTStop> to, const NBVehicle* veh) {
635 NBEdge* fromEdge = ec.getByID(from->getEdgeId());
636 NBEdge* toEdge = ec.getByID(to->getEdgeId());
637 if (fromEdge == nullptr || toEdge == nullptr) {
638 return std::numeric_limits<double>::max();
639 } else if (fromEdge == toEdge) {
640 if (from->getEndPos() <= to->getEndPos()) {
641 return to->getEndPos() - from->getEndPos();
642 } else {
643 return std::numeric_limits<double>::max();
644 }
645 } else if (fromEdge->getBidiEdge() == toEdge) {
646 return std::numeric_limits<double>::max();
647 }
648 std::vector<const NBRouterEdge*> route;
649 router.compute(fromEdge, toEdge, veh, 0, route);
650 if (route.size() == 0) {
651 return std::numeric_limits<double>::max();
652 } else {
653 return router.recomputeCosts(route, veh, 0);
654 }
655}
656
657
658std::string
659NBPTLineCont::getWayID(const std::string& edgeID) {
660 std::size_t found = edgeID.rfind("#");
661 std::string result = edgeID;
662 if (found != std::string::npos) {
663 result = edgeID.substr(0, found);
664 }
665 if (result[0] == '-') {
666 result = result.substr(1);
667 }
668 return result;
669}
670
671
672/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:304
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
#define DEBUGLINEID
#define DEBUGSTOPID
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_SHIP
is an arbitrary ship
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_RAIL_URBAN
vehicle is a city rail
@ SVC_TRAM
vehicle is a light rail
@ SVC_BUS
vehicle is a bus
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
Computes the shortest path through a network using the Dijkstra algorithm.
Storage for edges, including some functionality operating on multiple edges.
Definition NBEdgeCont.h:59
NBEdge * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
RouterEdgeVector getAllRouterEdges() const
return all router edges
The representation of a single edge during network building.
Definition NBEdge.h:92
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition NBEdge.cpp:4540
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition NBEdge.cpp:4503
const std::string & getID() const
Definition NBEdge.h:1551
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition NBEdge.cpp:1310
const NBEdge * getBidiEdge() const
Definition NBEdge.h:1537
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition NBEdge.cpp:1009
Represents a single node (junction) during network building.
Definition NBNode.h:66
static double getCost(const NBEdgeCont &ec, SUMOAbstractRouter< NBRouterEdge, NBVehicle > &router, const std::shared_ptr< NBPTStop > from, const std::shared_ptr< NBPTStop > to, const NBVehicle *veh)
void reviseStops(NBPTLine *line, const NBEdgeCont &ec, NBPTStopCont &sc)
find directional edge for all stops of the line
void fixPermissions()
ensure that all turn lanes have sufficient permissions
void process(NBEdgeCont &ec, NBPTStopCont &sc, bool routeOnly=false)
~NBPTLineCont()
destructor
std::map< std::string, NBPTLine * > myPTLines
The map of names to pt lines.
std::shared_ptr< NBPTStop > findWay(NBPTLine *line, std::shared_ptr< NBPTStop > stop, const NBEdgeCont &ec, NBPTStopCont &sc) const
NBPTLine * retrieve(const std::string &lineID)
std::set< std::string > getServedPTStops()
void replaceEdge(const std::string &edgeID, const EdgeVector &replacement)
replace the edge with the given edge list in all lines
void constructRoute(NBPTLine *myPTLine, const NBEdgeCont &cont)
bool insert(NBPTLine *ptLine)
insert new line
void removeInvalidEdges(const NBEdgeCont &ec)
filter out edges that were removed due to –geometry.remove
void fixBidiStops(const NBEdgeCont &ec)
select the correct stop on superposed rail edges
static const int BWD
static const int FWD
static std::string getWayID(const std::string &edgeID)
void reviseSingleWayStops(NBPTLine *line, const NBEdgeCont &ec, NBPTStopCont &sc)
std::map< std::string, std::set< NBPTLine * > > myPTLineLookup
The map of edge ids to lines that use this edge in their route.
const std::string & getType() const
Definition NBPTLine.h:59
void replaceStop(std::shared_ptr< NBPTStop > oldStop, std::shared_ptr< NBPTStop > newStop)
replace the given stop
Definition NBPTLine.cpp:282
void replaceStops(std::vector< std::shared_ptr< NBPTStop > > stops)
Definition NBPTLine.h:74
const std::vector< long long int > * getWayNodes(std::string wayId)
Definition NBPTLine.cpp:132
void deleteInvalidStops(const NBEdgeCont &ec, const NBPTStopCont &sc)
remove invalid stops from the line
Definition NBPTLine.cpp:310
const std::string & getName() const
Definition NBPTLine.h:55
const std::string & getLineID() const
Definition NBPTLine.h:51
std::vector< PTStopInfo > getStopEdges(const NBEdgeCont &ec) const
Definition NBPTLine.cpp:180
SUMOVehicleClass getVClass() const
Definition NBPTLine.h:101
const std::string & getRef() const
get line reference (not unique)
Definition NBPTLine.h:70
const std::vector< NBEdge * > & getRoute() const
Definition NBPTLine.cpp:174
const std::vector< std::string > & getWays() const
Definition NBPTLine.h:130
const std::vector< std::shared_ptr< NBPTStop > > & getStops()
Definition NBPTLine.cpp:68
void setRevised(std::vector< bool > stopsRevised)
Definition NBPTLine.h:78
void setEdges(const std::vector< NBEdge * > &edges)
Definition NBPTLine.cpp:141
Container for public transport stops during the net building process.
static NBEdge * getReverseEdge(NBEdge *edge)
std::shared_ptr< NBPTStop > getReverseStop(std::shared_ptr< NBPTStop > pStop, const NBEdgeCont &ec)
std::shared_ptr< NBPTStop > findStop(const std::string &origEdgeID, Position pos, double threshold=1) const
bool insert(std::shared_ptr< NBPTStop > ptStop, bool floating=false)
Inserts a node into the map.
static double getTravelTimeStatic(const NBRouterEdge *const edge, const NBVehicle *const, double)
Definition NBEdge.h:82
A vehicle as used by router.
Definition NBVehicle.h:42
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition Named.h:67
A storage for options typed value containers)
Definition OptionsCont.h:89
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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.
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
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...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const