53 delete myPTLine.second;
82 if (item.second->getWays().size() > 0) {
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());
115 const std::vector<std::string>& waysIds = line->
getWays();
116 if (waysIds.size() == 1 && line->
getStops().size() > 1) {
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());
125 WRITE_WARNINGF(
TL(
"Cannot revise pt stop localization for pt line '%', which has no route edges. Ignoring!"), line->
getLineID());
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);
133 stop =
findWay(line, stop, ec, sc);
134 if (stop ==
nullptr) {
138 auto waysIdsIt = std::find(waysIds.begin(), waysIds.end(), stop->getOrigEdgeId());
139 if (waysIdsIt == waysIds.end()) {
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());
152 const std::vector<long long int>* wayPrev =
nullptr;
153 if (waysIdsIt != waysIds.begin()) {
156 const std::vector<long long int>* wayNext =
nullptr;
157 if (waysIdsIt != (waysIds.end() - 1)) {
160 if (wayPrev ==
nullptr && wayNext ==
nullptr) {
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) {
172 }
else if (wayEnds == wayPrevBegins || wayEnds == wayPrevEnds || wayBegins == wayNextEnds || wayBegins == wayNextBegins) {
179 std::string edgeId = stop->getEdgeId();
181 int assignedDir = edgeId.at(0) ==
'-' ?
BWD :
FWD;
183 if (dir != assignedDir) {
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());
192 if (stop->getLines().size() > 0) {
193 std::shared_ptr<NBPTStop> reverseStop = sc.
getReverseStop(stop, ec);
200 stop->setEdgeId(reverse->
getID(), ec);
202 stop->addLine(line->
getRef());
203 stopsRevised.back() =
true;
210 const std::vector<std::string>& waysIds = line->
getWays();
211 for (std::shared_ptr<NBPTStop> stop : line->
getStops()) {
213 stop =
findWay(line, stop, ec, sc);
214 if (stop ==
nullptr) {
218 auto waysIdsIt = std::find(waysIds.begin(), waysIds.end(), stop->getOrigEdgeId());
219 if (waysIdsIt == waysIds.end()) {
223 stop->addLine(line->
getRef());
228std::shared_ptr<NBPTStop>
230 const std::vector<std::string>& waysIds = line->
getWays();
233 std::cout <<
" stop=" << stop->getID() <<
" line=" << line->
getLineID() <<
" edgeID=" << stop->getEdgeId() <<
" origID=" << stop->getOrigEdgeId() <<
"\n";
236 if (stop->isLoose()) {
238 double minDist = std::numeric_limits<double>::max();
242 if (dist < minDist) {
250 <<
" found=" << (std::find(waysIds.begin(), waysIds.end(),
getWayID(best->
getID())) != waysIds.end())
251 <<
" wayIDs=" <<
toString(waysIds) <<
"\n";
256 if (stop->getEdgeId() ==
"") {
257 stop->setEdgeId(best->
getID(), ec);
258 stop->setOrigEdgeId(wayID);
259 }
else if (stop->getEdgeId() != best->
getID()) {
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);
272 WRITE_WARNINGF(
TL(
"Could not assign stop '%' to pt line '%' (closest edge '%', distance %). Ignoring!"),
278 auto waysIdsIt = waysIds.begin();
279 for (; waysIdsIt != waysIds.end(); waysIdsIt++) {
280 if ((*waysIdsIt) == stop->getOrigEdgeId()) {
285 if (waysIdsIt == waysIds.end()) {
287 for (
auto& edgeCand : stop->getAdditionalEdgeCandidates()) {
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);
303 if (waysIdsIt == waysIds.end()) {
304 WRITE_WARNINGF(
TL(
"Cannot assign stop % on edge '%' to pt line '%'. Ignoring!"), stop->getID(), stop->getOrigEdgeId(), line->
getLineID());
313 std::vector<NBEdge*> edges;
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++) {
323 int foundForward = 0;
324 if (cont.
retrieve(*it3,
false) !=
nullptr) {
325 currentWayEdges.push_back(cont.
retrieve(*it3,
false));
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));
338 int foundReverse = 0;
339 if (cont.
retrieve(
"-" + *it3,
false) !=
nullptr) {
340 currentWayMinusEdges.push_back(cont.
retrieve(
"-" + *it3,
false));
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));
353 bool fakeMinus =
false;
357 currentWayMinusEdges.insert(currentWayMinusEdges.begin(), currentWayEdges.rbegin(), currentWayEdges.rbegin() + foundForward);
360#ifdef DEBUG_CONSTRUCT_ROUTE
362 std::cout <<
" way=" << (*it3)
366 <<
"\n +=" <<
toString(currentWayEdges)
367 <<
"\n -=" <<
toString(currentWayMinusEdges)
368 <<
"\n p+=" <<
toString(prevWayEdges)
369 <<
"\n p-=" <<
toString(prevWayMinusEdges)
373 if (currentWayEdges.empty()) {
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();
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();
390 if (currentWayMinusEdges.empty()) {
391 currentWayEdges.clear();
395 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
397 last = currentWayMinusEdges.back()->getFromNode();
399 last = currentWayMinusEdges.back()->getToNode();
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();
413 prevWayEdges.clear();
414 prevWayMinusEdges.clear();
417 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
418 last = currentWayMinusEdges.back()->getToNode();
419 prevWayEdges.clear();
420 prevWayMinusEdges.clear();
423 if (it3 != pTLine->
getWays().begin()) {
424#ifdef DEBUG_CONSTRUCT_ROUTE
426 std::cout <<
" way " << (*it3)
427 <<
" is not the start of ptline " << pTLine->
getLineID()
428 <<
" (" + pTLine->
getName() +
")\n";
431 }
else if (pTLine->
getWays().size() == 1) {
432 if (currentWayEdges.size() > 0) {
433 edges.insert(edges.end(), currentWayEdges.begin(), currentWayEdges.end());
435 edges.insert(edges.end(), currentWayMinusEdges.begin(), currentWayMinusEdges.end());
438 prevWayEdges = currentWayEdges;
439 prevWayMinusEdges = currentWayMinusEdges;
440 if (!prevWayEdges.empty()) {
441 first = prevWayEdges.front()->getFromNode();
442 last = prevWayEdges.back()->getToNode();
448 currentWayEdges.clear();
449 currentWayMinusEdges.clear();
461 for (
const NBEdge* e : item.second->getRoute()) {
467 line->replaceEdge(edgeID, replacement);
468 for (
const NBEdge* e : replacement) {
478 std::set<std::string> result;
481 for (std::shared_ptr<NBPTStop> stop : line->
getStops()) {
482 result.insert(stop->getID());
491 std::map<std::string, SUMOVehicleClass> types;
508 std::vector<std::shared_ptr<NBPTStop> > stops = line->
getStops();
509 if (stops.size() < 2) {
512 if (types.count(line->
getType()) == 0) {
513 WRITE_WARNINGF(
TL(
"Could not determine vehicle class for public transport line of type '%'."), 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()) {
531 std::shared_ptr<NBPTStop> from2 = to2;
533 const double c1 =
getCost(ec, *router, from, to, &veh);
534 const double c2 =
getCost(ec, *router, from2, to, &veh);
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);
566 const double c1 =
getCost(ec, *router, from, to, &veh);
567 const double c2 =
getCost(ec, *router, from, to2, &veh);
578 if (best < std::numeric_limits<double>::max()) {
585 newStops.push_back(used);
587 assert(stops.size() == newStops.size());
597 item.second->removeInvalidEdges(ec);
606 const std::vector<NBEdge*>& route = line->
getRoute();
608 for (
int i = 1; i < (int)route.size(); i++) {
609 NBEdge* e1 = route[i - 1];
612 if (cons.size() == 0) {
616 for (
const auto& c : cons) {
623 int lane = cons[0].fromLane;
634 const std::shared_ptr<NBPTStop> from,
const std::shared_ptr<NBPTStop> to,
const NBVehicle* veh) {
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();
643 return std::numeric_limits<double>::max();
646 return std::numeric_limits<double>::max();
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();
660 std::size_t found = edgeID.rfind(
"#");
661 std::string result = edgeID;
662 if (found != std::string::npos) {
663 result = edgeID.substr(0, found);
665 if (result[0] ==
'-') {
666 result = result.substr(1);
#define WRITE_WARNINGF(...)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
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)
Computes the shortest path through a network using the Dijkstra algorithm.
Storage for edges, including some functionality operating on multiple edges.
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.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
const std::string & getID() const
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
const NBEdge * getBidiEdge() const
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Represents a single node (junction) during network building.
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 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
void replaceStop(std::shared_ptr< NBPTStop > oldStop, std::shared_ptr< NBPTStop > newStop)
replace the given stop
void replaceStops(std::vector< std::shared_ptr< NBPTStop > > stops)
const std::vector< long long int > * getWayNodes(std::string wayId)
void deleteInvalidStops(const NBEdgeCont &ec, const NBPTStopCont &sc)
remove invalid stops from the line
const std::string & getName() const
const std::string & getLineID() const
std::vector< PTStopInfo > getStopEdges(const NBEdgeCont &ec) const
SUMOVehicleClass getVClass() const
const std::string & getRef() const
get line reference (not unique)
const std::vector< NBEdge * > & getRoute() const
const std::vector< std::string > & getWays() const
const std::vector< std::shared_ptr< NBPTStop > > & getStops()
void setRevised(std::vector< bool > stopsRevised)
void setEdges(const std::vector< NBEdge * > &edges)
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)
A vehicle as used by router.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
A storage for options typed value containers)
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