43#define DEBUGNODEID "gneJ34"
44#define DEBUGNODEID2 "28842974"
45#define DEBUGEDGEID "22820560#0"
46#define DEBUGCOND(obj) ((obj != 0 && (obj)->getID() == DEBUGNODEID))
48#define SHARP_THRESHOLD_SAMEDIR 100
49#define SHARP_THRESHOLD 80
66const std::vector<NBRailwayTopologyAnalyzer::Track*>&
68 if ((minPermissions & svc) != 0) {
71 if (svcSuccessors.count(svc) == 0) {
72 std::vector<Track*> succ;
73 for (
Track* t : successors) {
74 if ((t->edge->getPermissions() & svc) != 0) {
78 svcSuccessors[svc] = succ;
80 return svcSuccessors[svc];
85const std::vector<std::pair<const NBRailwayTopologyAnalyzer::Track*, const NBRailwayTopologyAnalyzer::Track*> >&
87 if ((minPermissions & svc) != 0) {
90 if (svcViaSuccessors.count(svc) == 0) {
91 std::vector<std::pair<const Track*, const Track*> >& succ = svcViaSuccessors[svc];
92 for (
const Track*
const t : successors) {
93 if ((t->edge->getPermissions() & svc) != 0) {
94 succ.push_back(std::make_pair(t,
nullptr));
98 return svcViaSuccessors[svc];
133 int numRailEdges = 0;
134 int numBidiEdges = 0;
135 int numNotCenterEdges = 0;
136 int numAddedBidiEdges = 0;
138 std::vector<NBEdge*> edges;
139 if (inputfile ==
"") {
141 edges.push_back(edge);
144 std::set<std::string> edgeIDs;
146 for (
const std::string& edgeID : edgeIDs) {
148 if (edge !=
nullptr) {
149 edges.push_back(edge);
153 for (
NBEdge* edge : edges) {
158 if (!edge->isBidiRail()) {
172 WRITE_MESSAGE(
"Added " +
toString(numAddedBidiEdges) +
" bidi-edges to ensure that all tracks are usable in both directions.");
173 if (numNotCenterEdges) {
174 WRITE_WARNING(
"Ignore " +
toString(numNotCenterEdges) +
" edges because they have the wrong spreadType");
176 return numAddedBidiEdges;
184 const std::string id2 = (edge->
getID()[0] ==
'-'
185 ? edge->
getID().substr(1)
186 :
"-" + edge->
getID());
204 incoming->invalidateConnections(
true);
221 inEdges.push_back(e);
226 outEdges.push_back(e);
234 std::set<NBNode*> brokenNodes;
240 std::set<NBNode*> railNodes =
getRailNodes(ec, verbose);
241 std::map<std::pair<int, int>, std::set<NBNode*, ComparatorIdLess> > types;
242 std::set<NBEdge*, ComparatorIdLess> bidiEdges;
243 std::set<NBEdge*, ComparatorIdLess> bufferStops;
244 for (
NBNode* node : railNodes) {
247 types[std::make_pair((
int)inEdges.size(), (
int)outEdges.size())].insert(node);
248 for (
NBEdge* e : outEdges) {
249 if (e->isBidiRail() && bidiEdges.count(e->getTurnDestination(
true)) == 0) {
252 if (e->getID()[0] ==
'-') {
254 }
else if (primary->
getID()[0] !=
'-' && secondary->
getID()[0] !=
'-' && secondary->
getID() < primary->
getID()) {
257 if (bidiEdges.count(secondary) == 0) {
259 bidiEdges.insert(primary);
269 int numBufferStops = 0;
270 if (verbose && types.size() > 0) {
271 WRITE_MESSAGE(
TL(
"Railway nodes by number of incoming,outgoing edges:"))
276 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are outgoing");
280 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are incoming");
284 device.
writeAttr(
"meaning",
"an incoming edge has a sharp angle to all outgoing edges");
288 device.
writeAttr(
"meaning",
"an outgoing edge has a sharp angle from all incoming edges");
292 for (
auto it : types) {
293 int numBrokenType = 0;
294 device.
openTag(
"railNodeType");
295 int in = it.first.first;
296 int out = it.first.second;
299 for (
NBNode* n : it.second) {
307 std::string broken =
"";
317 for (
NBEdge* e : inRail) {
328 for (
NBEdge* e : outRail) {
339 if (((in == 1 && out == 1) || (in == 2 && out == 2))
344 if (broken.size() > 0) {
346 brokenNodes.insert(n);
358 +
" count: " +
toString(it.second.size()) +
" broken: " +
toString(numBrokenType));
372 for (
NBEdge* e : bidiEdges) {
375 device.
writeAttr(
"bidi", e->getTurnDestination(
true)->getID());
389 std::set<NBNode*> railNodes;
390 int numRailEdges = 0;
391 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
392 if (
hasRailway(it->second->getPermissions())) {
394 railNodes.insert(it->second->getFromNode());
395 railNodes.insert(it->second->getToNode());
398 int numRailSignals = 0;
399 for (
const NBNode*
const node : railNodes) {
437#ifdef DEBUG_SEQSTOREVERSE
442 for (
NBEdge* e1 : edges) {
443 for (
NBEdge* e2 : edges2) {
463 if (e != candOut &&
isStraight(node, e, candOut)) {
465 std::cout <<
" isStraight e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
471 if (e != candOut && !
isStraight(node, e, candOut)) {
473 std::cout <<
" isSharp e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
490 if (!e1->isBidiRail(
true)) {
496 return !
allBidi || countBidiAsSharp;
503 if (!e->isBidiRail()) {
514 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
532 if (bidiOut ==
nullptr) {
537 tmpBidiOut.push_back(bidiOut);
539 tmpBidiIn.push_back(bidiIn);
543 for (
NBEdge* cand : outRail) {
545 if (!cand->isBidiRail() &&
isStraight(node, bidiIn, cand)
547 &&
allSharp(node, inRail, tmpBidiOut,
true)) {
554 for (
NBEdge* cand : inRail) {
556 if (!cand->isBidiRail() &&
isStraight(node, cand, bidiOut)
558 &&
allSharp(node, outRail, tmpBidiIn,
true)) {
573 std::vector<EdgeVector> seqsToReverse;
574 for (
NBNode* n : brokenNodes) {
577 for (
NBEdge* start : outRail) {
579 tmp.push_back(start);
581 if (!
allBroken(n, start, inRail, outRail)
582 || (inRail.size() == 1 && outRail.size() == 1)) {
583#ifdef DEBUG_SEQSTOREVERSE
585 std::cout <<
" abort at start n=" << n->getID() <<
" (not all broken)\n";
594 seq.push_back(start);
596 NBNode* n2 = start->getToNode();
599 if (brokenNodes.count(n2) != 0) {
601 tmp2.push_back(start);
602 if (
allBroken(n2, start, outRail2, inRail2)) {
603 seqsToReverse.push_back(seq);
605#ifdef DEBUG_SEQSTOREVERSE
607 std::cout <<
" abort at n2=" << n2->
getID() <<
" (not all broken)\n";
613 if (outRail2.size() == 0) {
616#ifdef DEBUG_SEQSTOREVERSE
618 std::cout <<
" abort at n2=" << n2->
getID() <<
" (border)\n";
621 }
else if (outRail2.size() > 1 || inRail2.size() > 1) {
624#ifdef DEBUG_SEQSTOREVERSE
626 std::cout <<
" abort at n2=" << n2->
getID() <<
" (switch)\n";
630 start = outRail2.front();
637 if (seqsToReverse.size() > 0) {
638 WRITE_MESSAGE(
"Found " +
toString(seqsToReverse.size()) +
" reversible edge sequences between broken rail nodes");
640 std::sort(seqsToReverse.begin(), seqsToReverse.end(),
642 return a.size() < b.size();
645 std::set<NBNode*> affectedEndpoints;
646 std::set<std::string> reversedIDs;
647 std::map<int, int> seqLengths;
649 NBNode* seqStart = seq.front()->getFromNode();
650 NBNode* seqEnd = seq.back()->getToNode();
652 if (affectedEndpoints.count(seqStart) == 0
653 && affectedEndpoints.count(seqEnd) == 0) {
654 affectedEndpoints.insert(seqStart);
655 affectedEndpoints.insert(seqEnd);
658 e->reinitNodes(e->getToNode(), e->getFromNode());
659 e->setGeometry(e->getGeometry().reverse());
660 reversedIDs.insert(e->getID());
662 seqLengths[(int)seq.size()]++;
666 if (numReversed > 0) {
669 if (reversedIDs.count(item.second->getEdgeId())) {
670 item.second->findLaneAndComputeBusStopExtent(ec);
683 int numBufferStops = 0;
684 int numAddedBidiTotal = 0;
685 for (
NBNode* node : railNodes) {
687 if (node->getEdges().size() != 1) {
688 WRITE_WARNINGF(
TL(
"Ignoring buffer stop junction '%' with % edges."), node->getID(), node->getEdges().size());
691 int numAddedBidi = 0;
698 while (prev ==
nullptr || (inRail.size() + outRail.size()) == 3) {
700 if (prev ==
nullptr) {
701 assert(node->getEdges().size() == 1);
702 e = node->getEdges().front();
707 assert(inRail.size() == 2);
708 e = inRail.front() == prev2 ? inRail.back() : inRail.front();
711 assert(outRail.size() == 2);
712 e = outRail.front() == prev2 ? outRail.back() : outRail.front();
744 if (numAddedBidiTotal > 0) {
745 WRITE_MESSAGE(
"Added " +
toString(numAddedBidiTotal) +
" edges to connect " +
toString(numBufferStops) +
" buffer stops in both directions.");
747 return numAddedBidiTotal;
754 if (inRail.size() == 2 && outRail.size() == 1 &&
isStraight(n, inRail.front(), inRail.back())) {
755 if (
isStraight(n, inRail.front(), outRail.front())) {
756 return inRail.front();
757 }
else if (
isStraight(n, inRail.back(), outRail.front())) {
758 return inRail.back();
761 if (inRail.size() == 1 && outRail.size() == 2 &&
isStraight(n, outRail.front(), outRail.back())) {
762 if (
isStraight(n, outRail.front(), inRail.front())) {
763 return outRail.front();
764 }
else if (
isStraight(n, outRail.back(), inRail.front())) {
765 return outRail.back();
775 std::map<int, int> seqLengths;
778 for (
NBNode* n : brokenNodes) {
781 std::vector<NBNode*> nodeSeq;
784 nodeSeq.push_back(prev);
785 edgeSeq.push_back(edge);
793 if (allRail.size() == 2 &&
isStraight(next, allRail.front(), allRail.back())) {
795 edge = allRail.front() == edge ? allRail.back() : allRail.front();
796 nodeSeq.push_back(prev);
797 edgeSeq.push_back(edge);
806 for (
NBEdge* e : edgeSeq) {
809 seqLengths[(int)edgeSeq.size()]++;
811 numAdded += (int)edgeSeq.size();
825 if (seqLengths.size() > 0) {
834 std::set<NBPTLine*> result;
835 std::set<std::pair<NBPTStop*, NBPTStop*> > visited;
836 for (
const auto& item : lc.
getLines()) {
837 const std::vector<NBPTStop*>& stops = item.second->getStops();
838 if (stops.size() > 1) {
839 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
842 visited.insert({fromStop, toStop});
846 for (
const auto& item : lc.
getLines()) {
847 const std::vector<NBPTStop*>& stops = item.second->getStops();
848 if (stops.size() > 1) {
849 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
852 std::pair<NBPTStop*, NBPTStop*> reverseTrip({toStop, fromStop});
853 if (visited.count(reverseTrip)) {
854 result.insert(item.second);
867 std::vector<Track*> tracks;
869 tracks.push_back(
new Track(edge));
871 const int numEdges = (int)tracks.size();
873 tracks.push_back(
new Track(edge, (
int)tracks.size(), edge->getID() +
"_reverse"));
876 std::map<NBEdge*, std::pair<Track*, Track*> > stopTracks;
879 Track* start =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_start");
880 tracks.push_back(start);
881 Track* end =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_end");
882 tracks.push_back(end);
883 stopTracks[edge] = {start, end};
890 for (
NBEdge* e1 : railEdges) {
891 for (
NBEdge* e2 : railEdges) {
893 int i = e1->getNumericalID();
894 int i2 = e2->getNumericalID();
895 if (e1->getToNode() == node) {
896 if (e2->getFromNode() == node) {
898 tracks[i]->addSuccessor(tracks[i2]);
900 tracks[i2 + numEdges]->addSuccessor(tracks[i + numEdges]);
903 tracks[i]->addSuccessor(tracks[i2 + numEdges]);
904 tracks[i2]->addSuccessor(tracks[i + numEdges]);
907 if (e2->getFromNode() == node) {
909 tracks[i + numEdges]->addSuccessor(tracks[i2]);
910 tracks[i2 + numEdges]->addSuccessor(tracks[i]);
921 for (
auto& item : stopTracks) {
922 const int index = item.first->getNumericalID();
924 item.second.first->addSuccessor(tracks[index]);
925 item.second.first->addSuccessor(tracks[index + numEdges]);
927 tracks[index]->addSuccessor(item.second.second);
928 tracks[index + numEdges]->addSuccessor(item.second.second);
944 int numDisconnected = 0;
945 std::set<NBEdge*, ComparatorIdLess> addBidiStops;
946 std::set<NBEdge*, ComparatorIdLess> addBidiEdges;
947 std::set<std::pair<std::string, std::string> > visited;
954 for (
const auto& item : lc.
getLines()) {
956 std::vector<std::pair<NBEdge*, std::string> > stops = line->
getStopEdges(ec);
959 if (routeStart !=
nullptr) {
960 stops.insert(stops.begin(), {routeStart, routeStart->getID()});
962 if (routeEnd !=
nullptr) {
963 stops.push_back({routeEnd, routeEnd->
getID()});
965 if (stops.size() < 2) {
968 std::vector<NBEdge*> stopEdges;
969 for (
auto it : stops) {
970 stopEdges.push_back(it.first);
972 if (!line->
isConsistent(stopEdges) && requireBidi.count(line) == 0) {
973 WRITE_WARNINGF(
TL(
"Edge sequence is not consistent with stop sequence in line '%', not adding bidi edges."), item.first);
976 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
977 NBEdge* fromEdge = it->first;
978 NBEdge* toEdge = (it + 1)->first;
979 const std::string fromStop = it->second;
980 const std::string toStop = (it + 1)->second;
981 std::pair<std::string, std::string> trip(fromStop, toStop);
982 std::pair<std::string, std::string> reverseTrip(toStop, fromStop);
984 if (visited.count(trip) != 0) {
987 visited.insert(trip);
989 if (stopTracks.count(fromEdge) == 0
990 || stopTracks.count(toEdge) == 0) {
993 const bool needBidi = visited.count(reverseTrip) != 0;
995 std::vector<const Track*> route;
996 router->
compute(stopTracks[fromEdge].first, stopTracks[toEdge].second, &veh, 0, route);
1000 if (route.size() > 0) {
1001 assert(route.size() > 2);
1002 for (
int i = 1; i < (int)route.size() - 1; ++i) {
1003 if (route[i]->getNumericalID() >= numEdges || needBidi) {
1004 NBEdge* edge = route[i]->edge;
1005 if (addBidiEdges.count(edge) == 0) {
1006 bool isStop = i == 1 || i == (int)route.size() - 2;
1009 addBidiEdges.insert(edge);
1011 addBidiStops.insert(edge);
1015 WRITE_WARNINGF(
TL(
"Stop on edge '%' can only be reached in reverse but edge has the wrong spreadType."), fromEdge->
getID());
1018 }
else if (isStop && needBidi) {
1041 for (
NBEdge* edge : addBidiEdges) {
1042 if (!edge->isBidiRail()) {
1045 if (e2 !=
nullptr) {
1055 if (addBidiEdges.size() > 0 || numDisconnected > 0) {
1056 WRITE_MESSAGE(
"Added " +
toString(addBidiStops.size()) +
" bidi-edges for public transport stops and a total of "
1057 +
toString(added) +
" bidi-edges to ensure connectivity of stops ("
1058 +
toString(numDisconnected) +
" stops remain disconnected)");
1062 for (
Track* t : tracks) {
1066 return (
int)addBidiEdges.size();
1074 for (
const auto& e : ec) {
1075 if (!
hasRailway(e.second->getPermissions())) {
1078 NBNode*
const from = e.second->getFromNode();
1079 NBNode*
const to = e.second->getToNode();
1080 if (brokenNodes.count(from) == 0 && brokenNodes.count(to) == 0) {
1083 if (e.second->isBidiRail()) {
1086 EdgeVector inRailFrom, outRailFrom, inRailTo, outRailTo;
1091 bool haveStraight =
false;
1092 bool haveStraightReverse =
false;
1093 if (!geometryLike || outRailFrom.size() + inRailFrom.size() == 2) {
1094 for (
const NBEdge* fromStraightCand : outRailFrom) {
1095 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1096 haveStraightReverse =
true;
1101 if (haveStraightReverse) {
1102 for (
const NBEdge* fromStraightCand : inRailFrom) {
1103 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1104 haveStraight =
true;
1111 if ((!haveStraightReverse || haveStraight) && (!geometryLike || outRailTo.size() + inRailTo.size() == 2)) {
1114 haveStraight =
false;
1115 haveStraightReverse =
false;
1116 for (
const NBEdge* toStraightCand : inRailTo) {
1117 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1118 haveStraightReverse =
true;
1123 if (haveStraightReverse) {
1124 for (
const NBEdge* toStraightCand : outRailTo) {
1125 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1126 haveStraight =
true;
1134 if (haveStraightReverse && !haveStraight) {
1137 if (e2 !=
nullptr) {
1146 WRITE_MESSAGE(
"Added " +
toString(added) +
" bidi-edges to ensure connectivity of straight tracks at geometry-like nodes.");
1148 WRITE_MESSAGE(
"Added " +
toString(added) +
" bidi-edges to ensure connectivity of straight tracks at switches.");
1185 std::set<NBEdge*, ComparatorIdLess> bidi;
1190 if (!edge->isBidiRail()) {
1191 edge->setPriority(4);
1197 if (edge->getPriority() >= 0) {
1206 if (uni.size() == 0) {
1207 if (bidi.size() != 0) {
1208 WRITE_WARNING(
TL(
"Cannot extend track direction priority because there are no track edges with positive priority"));
1215 while (!check.empty()) {
1216 NBEdge* edge = *check.begin();
1218 if (seen.count(edge) != 0) {
1224 forward.insert(straightOut);
1225 check.insert(straightOut);
1229 forward.insert(straightIn);
1230 check.insert(straightIn);
1232#ifdef DEBUG_DIRECTION_PRIORITY
1240 for (
NBEdge* edge : bidi) {
1241 NBEdge* bidiEdge =
const_cast<NBEdge*
>(edge->getBidiEdge());
1244 if (forward.count(edge) != 0) {
1245 if (forward.count(bidiEdge) == 0) {
1254 if (forward.count(bidiEdge) != 0) {
1263 if (bidiEdge ==
nullptr) {
1264 WRITE_WARNINGF(
TL(
"Edge '%' was loaded with undefined priority (%) but has unambiguous main direction (no bidi edge)"), edge->getID(), edge->getPriority());
1266 if (edge->getPriority() >= 0) {
1269 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() >= 0) {
1272 if (edge->getPriority() < 0) {
1273 edge->setPriority(prio);
1275 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() < 0) {
1279 std::map<int, int> numPrios;
1280 for (
NBEdge* edge : bidi) {
1281 numPrios[edge->getPriority()]++;
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
#define SHARP_THRESHOLD_SAMEDIR
std::set< NBEdge * > EdgeSet
container for unique edges
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SUMO_TAG_NODE
alternative definition for junction
bool gDebugFlag1
global utility flags for debugging
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
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.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
EdgeVector getAllEdges() const
return all edges
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
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
NBNode * getToNode() const
Returns the destination node of the edge.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
NBEdge * getStraightContinuation(SVCPermissions permissions) const
return the straightest follower edge for the given permissions or nullptr (never returns turn-arounds...
static double getTravelTimeStatic(const NBEdge *const edge, const NBVehicle *const, double)
NBEdge * getStraightPredecessor(SVCPermissions permissions) const
return the straightest predecessor edge for the given permissions or nullptr (never returns turn-arou...
const std::string & getID() const
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
NBNode * getFromNode() const
Returns the origin node of the edge.
NBEdge * getTurnDestination(bool possibleDestination=false) const
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
void setPriority(int priority)
Sets the priority of the edge.
int getPriority() const
Returns the priority of the edge.
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
static void loadEdgesFromFile(const std::string &file, std::set< std::string > &into)
Add edge ids defined in file (either ID or edge:ID per line) into the given set.
Represents a single node (junction) during network building.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
const std::map< std::string, NBPTLine * > & getLines() const
bool isConsistent(const std::vector< NBEdge * > &stops) const
return whether the mentioned edges appear in that order in the route
std::vector< std::pair< NBEdge *, std::string > > getStopEdges(const NBEdgeCont &ec) const
get stop edges and stop ids
const std::string & getRef() const
get line reference (not unique)
NBEdge * getRouteEnd(const NBEdgeCont &ec) const
return last valid edge of myRoute (if it doest not lie before the last stop)
NBEdge * getRouteStart(const NBEdgeCont &ec) const
return first valid edge of myRoute (if it doest not lie after the first stop)
bool insert(NBPTStop *ptStop, bool floating=false)
Inserts a node into the map.
NBPTStop * get(std::string id) const
Retrieve a previously inserted pt stop.
NBPTStop * getReverseStop(NBPTStop *pStop, const NBEdgeCont &ec)
const std::map< std::string, NBPTStop * > & getStops() const
The representation of a single pt stop.
void setBidiStop(NBPTStop *bidiStop)
SVCPermissions minPermissions
const std::vector< std::pair< const Track *, const Track * > > & getViaSuccessors(SUMOVehicleClass svc=SVC_IGNORING) const
const std::vector< Track * > & getSuccessors(SUMOVehicleClass svc=SVC_IGNORING) const
std::vector< Track * > successors
void addSuccessor(Track *track)
std::vector< std::pair< const Track *, const Track * > > viaSuccessors
static NBEdge * isBidiSwitch(const NBNode *n)
static int addBidiEdgesForStops(NBEdgeCont &ec, NBPTLineCont &lc, NBPTStopCont &sc)
add bidi-edges to connect successive public transport stops
static int repairTopology(NBEdgeCont &ec, NBPTStopCont &sc, NBPTLineCont &lc)
static void getRailEdges(const NBNode *node, EdgeVector &inEdges, EdgeVector &outEdges)
filter out rail edges among all edges of a the given node
static void extendDirectionPriority(NBEdgeCont &ec, bool fromUniDir)
static std::set< NBNode * > getRailNodes(NBEdgeCont &ec, bool verbose=false)
static void updateTurns(NBEdge *edge)
recompute turning directions for both nodes of the given edge
static bool isStraight(const NBNode *node, const NBEdge *e1, const NBEdge *e2)
static void analyzeTopology(NBEdgeCont &ec)
static std::set< NBPTLine * > findBidiCandidates(NBPTLineCont &lc)
identify lines that are likely to require bidirectional tracks
static int addBidiEdgesForStraightConnectivity(NBEdgeCont &ec, bool geometryLike)
add bidi-edges to connect straight tracks
static bool allSharp(const NBNode *node, const EdgeVector &in, const EdgeVector &out, bool countBidiAsSharp=false)
static bool allBroken(const NBNode *node, NBEdge *candOut, const EdgeVector &in, const EdgeVector &out)
static std::set< NBNode * > getBrokenRailNodes(NBEdgeCont &ec, bool verbose=false)
static int addBidiEdgesBetweenSwitches(NBEdgeCont &ec)
add bidi-edges to connect switches that are approached in both directions
static bool allBidi(const EdgeVector &edges)
static int makeAllBidi(NBEdgeCont &ec)
static double getTravelTimeStatic(const Track *const track, const NBVehicle *const veh, double time)
static bool hasRailway(SVCPermissions permissions)
filter for rail edges but do not return (legacy) all purpose edges
static int reverseEdges(NBEdgeCont &ec, NBPTStopCont &sc)
reverse edges sequences that are to broken nodes on both sides
static bool hasStraightPair(const NBNode *node, const EdgeVector &edges, const EdgeVector &edges2)
static int addBidiEdgesForBufferStops(NBEdgeCont &ec)
add bidi-edges to connect buffers stops in both directions
static NBEdge * addBidiEdge(NBEdgeCont &ec, NBEdge *edge, bool update=true)
add bidi-edge for the given edge
static int extendBidiEdges(NBEdgeCont &ec)
add further bidi-edges near existing bidi-edges
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any)
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
const std::string & getID() const
Returns the id.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
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.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
PositionVector reverse() const
reverse position 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...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects