44#define DEBUGNODEID "gneJ34"
45#define DEBUGNODEID2 "28842974"
46#define DEBUGEDGEID "22820560#0"
47#define DEBUGCOND(obj) ((obj != 0 && (obj)->getID() == DEBUGNODEID))
49#define SHARP_THRESHOLD_SAMEDIR 100
50#define SHARP_THRESHOLD 80
67const std::vector<NBRailwayTopologyAnalyzer::Track*>&
69 if ((minPermissions & svc) != 0) {
72 if (svcSuccessors.count(svc) == 0) {
73 std::vector<Track*> succ;
74 for (
Track* t : successors) {
75 if ((t->edge->getPermissions() & svc) != 0) {
79 svcSuccessors[svc] = succ;
81 return svcSuccessors[svc];
86const std::vector<std::pair<const NBRailwayTopologyAnalyzer::Track*, const NBRailwayTopologyAnalyzer::Track*> >&
88 if ((minPermissions & svc) != 0) {
91 if (svcViaSuccessors.count(svc) == 0) {
92 std::vector<std::pair<const Track*, const Track*> >& succ = svcViaSuccessors[svc];
93 for (
const Track*
const t : successors) {
94 if ((t->edge->getPermissions() & svc) != 0) {
95 succ.push_back(std::make_pair(t,
nullptr));
99 return svcViaSuccessors[svc];
137 int numRailEdges = 0;
138 int numBidiEdges = 0;
139 int numNotCenterEdges = 0;
140 int numAddedBidiEdges = 0;
142 std::vector<NBEdge*> edges;
143 if (inputfile ==
"") {
145 edges.push_back(edge);
148 std::set<std::string> edgeIDs;
150 for (
const std::string& edgeID : edgeIDs) {
152 if (edge !=
nullptr) {
153 edges.push_back(edge);
157 for (
NBEdge* edge : edges) {
162 if (!edge->isBidiRail()) {
176 WRITE_MESSAGEF(
TL(
"Added % bidi-edges to ensure that all tracks are usable in both directions."),
toString(numAddedBidiEdges));
177 if (numNotCenterEdges) {
180 return numAddedBidiEdges;
188 const std::string id2 = (edge->
getID()[0] ==
'-'
189 ? edge->
getID().substr(1)
190 :
"-" + edge->
getID());
208 incoming->invalidateConnections(
true);
225 inEdges.push_back(e);
230 outEdges.push_back(e);
238 std::set<NBNode*> brokenNodes;
244 std::set<NBNode*> railNodes =
getRailNodes(ec, verbose);
245 std::map<std::pair<int, int>, std::set<NBNode*, ComparatorIdLess> > types;
246 std::set<NBEdge*, ComparatorIdLess> bidiEdges;
247 std::set<NBEdge*, ComparatorIdLess> bufferStops;
248 for (
NBNode* node : railNodes) {
251 types[std::make_pair((
int)inEdges.size(), (
int)outEdges.size())].insert(node);
252 for (
NBEdge* e : outEdges) {
253 if (e->isBidiRail() && bidiEdges.count(e->getTurnDestination(
true)) == 0) {
256 if (e->getID()[0] ==
'-') {
258 }
else if (primary->
getID()[0] !=
'-' && secondary->
getID()[0] !=
'-' && secondary->
getID() < primary->
getID()) {
261 if (bidiEdges.count(secondary) == 0) {
263 bidiEdges.insert(primary);
273 int numBufferStops = 0;
274 if (verbose && types.size() > 0) {
275 WRITE_MESSAGE(
TL(
"Railway nodes by number of incoming,outgoing edges:"))
280 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are outgoing");
284 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are incoming");
288 device.
writeAttr(
"meaning",
"an incoming edge has a sharp angle to all outgoing edges");
292 device.
writeAttr(
"meaning",
"an outgoing edge has a sharp angle from all incoming edges");
296 for (
auto it : types) {
297 int numBrokenType = 0;
298 device.
openTag(
"railNodeType");
299 int in = it.first.first;
300 int out = it.first.second;
303 for (
NBNode* n : it.second) {
311 std::string broken =
"";
321 for (
NBEdge* e : inRail) {
332 for (
NBEdge* e : outRail) {
343 if (((in == 1 && out == 1) || (in == 2 && out == 2))
348 if (broken.size() > 0) {
350 brokenNodes.insert(n);
362 +
" count: " +
toString(it.second.size()) +
" broken: " +
toString(numBrokenType));
376 for (
NBEdge* e : bidiEdges) {
379 device.
writeAttr(
"bidi", e->getTurnDestination(
true)->getID());
393 std::set<NBNode*> railNodes;
394 int numRailEdges = 0;
395 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
396 if (
hasRailway(it->second->getPermissions())) {
398 railNodes.insert(it->second->getFromNode());
399 railNodes.insert(it->second->getToNode());
402 int numRailSignals = 0;
403 for (
const NBNode*
const node : railNodes) {
441#ifdef DEBUG_SEQSTOREVERSE
446 for (
NBEdge* e1 : edges) {
447 for (
NBEdge* e2 : edges2) {
467 if (e != candOut &&
isStraight(node, e, candOut)) {
469 std::cout <<
" isStraight e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
475 if (e != candOut && !
isStraight(node, e, candOut)) {
477 std::cout <<
" isSharp e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
494 if (!e1->isBidiRail(
true)) {
500 return !
allBidi || countBidiAsSharp;
507 if (!e->isBidiRail()) {
518 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
536 if (bidiOut ==
nullptr) {
541 tmpBidiOut.push_back(bidiOut);
543 tmpBidiIn.push_back(bidiIn);
547 for (
NBEdge* cand : outRail) {
549 if (!cand->isBidiRail() &&
isStraight(node, bidiIn, cand)
551 &&
allSharp(node, inRail, tmpBidiOut,
true)) {
558 for (
NBEdge* cand : inRail) {
560 if (!cand->isBidiRail() &&
isStraight(node, cand, bidiOut)
562 &&
allSharp(node, outRail, tmpBidiIn,
true)) {
577 std::vector<EdgeVector> seqsToReverse;
578 for (
NBNode* n : brokenNodes) {
581 for (
NBEdge* start : outRail) {
583 tmp.push_back(start);
585 if (!
allBroken(n, start, inRail, outRail)
586 || (inRail.size() == 1 && outRail.size() == 1)) {
587#ifdef DEBUG_SEQSTOREVERSE
589 std::cout <<
" abort at start n=" << n->getID() <<
" (not all broken)\n";
598 seq.push_back(start);
600 NBNode* n2 = start->getToNode();
603 if (brokenNodes.count(n2) != 0) {
605 tmp2.push_back(start);
606 if (
allBroken(n2, start, outRail2, inRail2)) {
607 seqsToReverse.push_back(seq);
609#ifdef DEBUG_SEQSTOREVERSE
611 std::cout <<
" abort at n2=" << n2->
getID() <<
" (not all broken)\n";
617 if (outRail2.size() == 0) {
620#ifdef DEBUG_SEQSTOREVERSE
622 std::cout <<
" abort at n2=" << n2->
getID() <<
" (border)\n";
625 }
else if (outRail2.size() > 1 || inRail2.size() > 1) {
628#ifdef DEBUG_SEQSTOREVERSE
630 std::cout <<
" abort at n2=" << n2->
getID() <<
" (switch)\n";
634 start = outRail2.front();
641 if (seqsToReverse.size() > 0) {
644 std::sort(seqsToReverse.begin(), seqsToReverse.end(),
646 return a.size() < b.size();
649 std::set<NBNode*> affectedEndpoints;
650 std::set<std::string> reversedIDs;
651 std::map<int, int> seqLengths;
653 NBNode* seqStart = seq.front()->getFromNode();
654 NBNode* seqEnd = seq.back()->getToNode();
656 if (affectedEndpoints.count(seqStart) == 0
657 && affectedEndpoints.count(seqEnd) == 0) {
658 affectedEndpoints.insert(seqStart);
659 affectedEndpoints.insert(seqEnd);
662 e->reinitNodes(e->getToNode(), e->getFromNode());
663 e->setGeometry(e->getGeometry().reverse());
664 reversedIDs.insert(e->getID());
666 seqLengths[(int)seq.size()]++;
670 if (numReversed > 0) {
673 if (reversedIDs.count(item.second->getEdgeId())) {
674 item.second->findLaneAndComputeBusStopExtent(ec);
687 int numBufferStops = 0;
688 int numAddedBidiTotal = 0;
689 for (
NBNode* node : railNodes) {
691 if (node->getEdges().size() != 1) {
692 WRITE_WARNINGF(
TL(
"Ignoring buffer stop junction '%' with % edges."), node->getID(), node->getEdges().size());
695 int numAddedBidi = 0;
702 while (prev ==
nullptr || (inRail.size() + outRail.size()) == 3) {
704 if (prev ==
nullptr) {
705 assert(node->getEdges().size() == 1);
706 e = node->getEdges().front();
711 assert(inRail.size() == 2);
712 e = inRail.front() == prev2 ? inRail.back() : inRail.front();
715 assert(outRail.size() == 2);
716 e = outRail.front() == prev2 ? outRail.back() : outRail.front();
748 if (numAddedBidiTotal > 0) {
751 return numAddedBidiTotal;
758 if (inRail.size() == 2 && outRail.size() == 1 &&
isStraight(n, inRail.front(), inRail.back())) {
759 if (
isStraight(n, inRail.front(), outRail.front())) {
760 return inRail.front();
761 }
else if (
isStraight(n, inRail.back(), outRail.front())) {
762 return inRail.back();
765 if (inRail.size() == 1 && outRail.size() == 2 &&
isStraight(n, outRail.front(), outRail.back())) {
766 if (
isStraight(n, outRail.front(), inRail.front())) {
767 return outRail.front();
768 }
else if (
isStraight(n, outRail.back(), inRail.front())) {
769 return outRail.back();
779 std::map<int, int> seqLengths;
782 for (
NBNode* n : brokenNodes) {
785 std::vector<NBNode*> nodeSeq;
788 nodeSeq.push_back(prev);
789 edgeSeq.push_back(edge);
797 if (allRail.size() == 2 &&
isStraight(next, allRail.front(), allRail.back())) {
799 edge = allRail.front() == edge ? allRail.back() : allRail.front();
800 nodeSeq.push_back(prev);
801 edgeSeq.push_back(edge);
810 for (
NBEdge* e : edgeSeq) {
813 seqLengths[(int)edgeSeq.size()]++;
815 numAdded += (int)edgeSeq.size();
829 if (seqLengths.size() > 0) {
838 std::set<NBPTLine*> result;
839 std::set<std::pair<std::shared_ptr<NBPTStop>, std::shared_ptr<NBPTStop> > > visited;
840 for (
const auto& item : lc.
getLines()) {
841 const std::vector<std::shared_ptr<NBPTStop> >& stops = item.second->getStops();
842 if (stops.size() > 1) {
843 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
844 std::shared_ptr<NBPTStop> fromStop = *it;
845 std::shared_ptr<NBPTStop> toStop = *(it + 1);
846 visited.insert({fromStop, toStop});
850 for (
const auto& item : lc.
getLines()) {
851 const std::vector<std::shared_ptr<NBPTStop> >& stops = item.second->getStops();
852 if (stops.size() > 1) {
853 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
854 std::shared_ptr<NBPTStop> fromStop = *it;
855 std::shared_ptr<NBPTStop> toStop = *(it + 1);
856 std::pair<std::shared_ptr<NBPTStop>, std::shared_ptr<NBPTStop> > reverseTrip({toStop, fromStop});
857 if (visited.count(reverseTrip)) {
858 result.insert(item.second);
871 std::vector<Track*> tracks;
873 tracks.push_back(
new Track(edge));
875 const int numEdges = (int)tracks.size();
877 tracks.push_back(
new Track(edge, (
int)tracks.size(), edge->getID() +
"_reverse", penalty));
880 std::map<NBEdge*, std::pair<Track*, Track*> > stopTracks;
883 Track* start =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_start");
884 tracks.push_back(start);
885 Track* end =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_end");
886 tracks.push_back(end);
887 stopTracks[edge] = {start, end};
894 for (
NBEdge* e1 : railEdges) {
895 for (
NBEdge* e2 : railEdges) {
897 int i = e1->getNumericalID();
898 int i2 = e2->getNumericalID();
899 if (e1->getToNode() == node) {
900 if (e2->getFromNode() == node) {
902 tracks[i]->addSuccessor(tracks[i2]);
904 tracks[i2 + numEdges]->addSuccessor(tracks[i + numEdges]);
907 tracks[i]->addSuccessor(tracks[i2 + numEdges]);
908 tracks[i2]->addSuccessor(tracks[i + numEdges]);
911 if (e2->getFromNode() == node) {
913 tracks[i + numEdges]->addSuccessor(tracks[i2]);
914 tracks[i2 + numEdges]->addSuccessor(tracks[i]);
925 for (
auto& item : stopTracks) {
926 const int index = item.first->getNumericalID();
928 item.second.first->addSuccessor(tracks[index]);
929 item.second.first->addSuccessor(tracks[index + numEdges]);
931 tracks[index]->addSuccessor(item.second.second);
932 tracks[index + numEdges]->addSuccessor(item.second.second);
948 int numDisconnected = 0;
949 std::set<NBEdge*, ComparatorIdLess> addBidiStops;
950 std::set<NBEdge*, ComparatorIdLess> addBidiEdges;
951 std::set<std::pair<std::string, std::string> > visited;
958 for (
const auto& item : lc.
getLines()) {
960 std::vector<std::pair<NBEdge*, std::string> > stops = line->
getStopEdges(ec);
961 std::vector<NBEdge*> stopEdges;
962 for (
auto it : stops) {
963 stopEdges.push_back(it.first);
967 if (routeStart !=
nullptr) {
968 stops.insert(stops.begin(), {routeStart, routeStart->getID()});
970 if (routeEnd !=
nullptr) {
971 stops.push_back({routeEnd, routeEnd->
getID()});
973 if (stops.size() < 2) {
976 if (!line->
isConsistent(stopEdges) && requireBidi.count(line) == 0) {
977 WRITE_WARNINGF(
TL(
"Edge sequence is not consistent with stop sequence in line '%', not adding bidi edges."), item.first);
980 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
981 NBEdge* fromEdge = it->first;
982 NBEdge* toEdge = (it + 1)->first;
983 const std::string fromStop = it->second;
984 const std::string toStop = (it + 1)->second;
985 std::pair<std::string, std::string> trip(fromStop, toStop);
986 std::pair<std::string, std::string> reverseTrip(toStop, fromStop);
988 if (visited.count(trip) != 0) {
991 visited.insert(trip);
993 if (stopTracks.count(fromEdge) == 0
994 || stopTracks.count(toEdge) == 0) {
997 const bool needBidi = visited.count(reverseTrip) != 0;
999 std::vector<const Track*> route;
1000 router->
compute(stopTracks[fromEdge].first, stopTracks[toEdge].second, &veh, 0, route);
1004 if (route.size() > 0) {
1005 assert(route.size() > 2);
1006 for (
int i = 1; i < (int)route.size() - 1; ++i) {
1007 if (route[i]->getNumericalID() >= numEdges || needBidi) {
1008 NBEdge* edge = route[i]->edge;
1009 if (addBidiEdges.count(edge) == 0) {
1010 bool isStop = i == 1 || i == (int)route.size() - 2;
1013 addBidiEdges.insert(edge);
1015 addBidiStops.insert(edge);
1019 WRITE_WARNINGF(
TL(
"Stop on edge '%' can only be reached in reverse but edge has the wrong spreadType."), fromEdge->
getID());
1022 }
else if (isStop && needBidi) {
1023 std::shared_ptr<NBPTStop> fs = sc.
get(fromStop);
1025 std::shared_ptr<NBPTStop> fromReverse = sc.
getReverseStop(fs, ec);
1028 fs->setBidiStop(fromReverse);
1031 std::shared_ptr<NBPTStop> ts = sc.
get(toStop);
1036 ts->setBidiStop(toReverse);
1049 for (
NBEdge* edge : addBidiEdges) {
1050 if (!edge->isBidiRail()) {
1053 if (e2 !=
nullptr) {
1063 if (addBidiEdges.size() > 0 || numDisconnected > 0) {
1064 WRITE_MESSAGE(
"Added " +
toString(addBidiStops.size()) +
" bidi-edges for public transport stops and a total of "
1065 +
toString(added) +
" bidi-edges to ensure connectivity of stops ("
1066 +
toString(numDisconnected) +
" stops remain disconnected)");
1070 for (
Track* t : tracks) {
1074 return (
int)addBidiEdges.size();
1082 for (
const auto& e : ec) {
1083 if (!
hasRailway(e.second->getPermissions())) {
1086 NBNode*
const from = e.second->getFromNode();
1087 NBNode*
const to = e.second->getToNode();
1088 if (brokenNodes.count(from) == 0 && brokenNodes.count(to) == 0) {
1091 if (e.second->isBidiRail()) {
1094 EdgeVector inRailFrom, outRailFrom, inRailTo, outRailTo;
1099 bool haveStraight =
false;
1100 bool haveStraightReverse =
false;
1101 if (!geometryLike || outRailFrom.size() + inRailFrom.size() == 2) {
1102 for (
const NBEdge* fromStraightCand : outRailFrom) {
1103 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1104 haveStraightReverse =
true;
1109 if (haveStraightReverse) {
1110 for (
const NBEdge* fromStraightCand : inRailFrom) {
1111 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1112 haveStraight =
true;
1119 if ((!haveStraightReverse || haveStraight) && (!geometryLike || outRailTo.size() + inRailTo.size() == 2)) {
1122 haveStraight =
false;
1123 haveStraightReverse =
false;
1124 for (
const NBEdge* toStraightCand : inRailTo) {
1125 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1126 haveStraightReverse =
true;
1131 if (haveStraightReverse) {
1132 for (
const NBEdge* toStraightCand : outRailTo) {
1133 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1134 haveStraight =
true;
1142 if (haveStraightReverse && !haveStraight) {
1145 if (e2 !=
nullptr) {
1154 WRITE_MESSAGEF(
TL(
"Added % bidi-edges to ensure connectivity of straight tracks at geometry-like nodes."),
toString(added));
1193 std::set<NBEdge*, ComparatorIdLess> bidi;
1198 if (!edge->isBidiRail()) {
1199 edge->setPriority(4);
1205 if (edge->getPriority() >= 0) {
1214 if (uni.size() == 0) {
1215 if (bidi.size() != 0) {
1216 WRITE_WARNING(
TL(
"Cannot extend track direction priority because there are no track edges with positive priority"));
1223 while (!check.empty()) {
1224 NBEdge* edge = *check.begin();
1226 if (seen.count(edge) != 0) {
1232 forward.insert(straightOut);
1233 check.insert(straightOut);
1237 forward.insert(straightIn);
1238 check.insert(straightIn);
1240#ifdef DEBUG_DIRECTION_PRIORITY
1248 for (
NBEdge* edge : bidi) {
1249 NBEdge* bidiEdge =
const_cast<NBEdge*
>(edge->getBidiEdge());
1252 if (forward.count(edge) != 0) {
1253 if (forward.count(bidiEdge) == 0) {
1262 if (forward.count(bidiEdge) != 0) {
1271 if (bidiEdge ==
nullptr) {
1272 WRITE_WARNINGF(
TL(
"Edge '%' was loaded with undefined priority (%) but has unambiguous main direction (no bidi edge)"), edge->getID(), edge->getPriority());
1274 if (edge->getPriority() >= 0) {
1277 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() >= 0) {
1280 if (edge->getPriority() < 0) {
1281 edge->setPriority(prio);
1283 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() < 0) {
1287 std::map<int, int> numPrios;
1288 for (
NBEdge* edge : bidi) {
1289 numPrios[edge->getPriority()]++;
1305 int addedSignals = 0;
1306 if (oc.
exists(
"railway.signal.guess.by-stops")) {
1307 if (oc.
getBool(
"railway.signal.guess.by-stops")) {
1308 const double minLength = oc.
getFloat(
"osm.stop-output.length.train");
1309 addedSignals += guessByStops(ec, sc, minLength);
1312 return addedSignals;
1318 int addedSignals = 0;
1338 if (in->getFromNode() != stopEdge->
getToNode()) {
1360 return addedSignals;
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#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
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
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
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
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.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
SumoXMLNodeType getType() const
Returns the type of this node.
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 Position & getPosition() const
bool geometryLike() const
whether this is structurally similar to a geometry node
const std::map< std::string, NBPTLine * > & getLines() const
bool isConsistent(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)
Container for public transport stops during the net building process.
const std::map< std::string, std::shared_ptr< NBPTStop > > & getStops() const
Returns an unmodifiable reference to the stored pt stops.
std::shared_ptr< NBPTStop > get(std::string id) const
Retrieve a previously inserted pt stop.
std::shared_ptr< NBPTStop > getReverseStop(std::shared_ptr< NBPTStop > pStop, const NBEdgeCont &ec)
bool insert(std::shared_ptr< NBPTStop > ptStop, bool floating=false)
Inserts a node into the map.
static int guessByStops(NBEdgeCont &ec, NBPTStopCont &sc, double minLength)
static int guessRailSignals(NBEdgeCont &ec, NBPTStopCont &sc)
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 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 int addBidiEdgesForStops(NBEdgeCont &ec, NBPTLineCont &lc, NBPTStopCont &sc, bool minimal)
add bidi-edges to connect successive public transport stops
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.
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)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
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