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];
134 int numRailEdges = 0;
135 int numBidiEdges = 0;
136 int numNotCenterEdges = 0;
137 int numAddedBidiEdges = 0;
139 std::vector<NBEdge*> edges;
140 if (inputfile ==
"") {
142 edges.push_back(edge);
145 std::set<std::string> edgeIDs;
147 for (
const std::string& edgeID : edgeIDs) {
149 if (edge !=
nullptr) {
150 edges.push_back(edge);
154 for (
NBEdge* edge : edges) {
159 if (!edge->isBidiRail()) {
173 WRITE_MESSAGEF(
TL(
"Added % bidi-edges to ensure that all tracks are usable in both directions."),
toString(numAddedBidiEdges));
174 if (numNotCenterEdges) {
177 return numAddedBidiEdges;
185 const std::string id2 = (edge->
getID()[0] ==
'-'
186 ? edge->
getID().substr(1)
187 :
"-" + edge->
getID());
205 incoming->invalidateConnections(
true);
222 inEdges.push_back(e);
227 outEdges.push_back(e);
235 std::set<NBNode*> brokenNodes;
241 std::set<NBNode*> railNodes =
getRailNodes(ec, verbose);
242 std::map<std::pair<int, int>, std::set<NBNode*, ComparatorIdLess> > types;
243 std::set<NBEdge*, ComparatorIdLess> bidiEdges;
244 std::set<NBEdge*, ComparatorIdLess> bufferStops;
245 for (
NBNode* node : railNodes) {
248 types[std::make_pair((
int)inEdges.size(), (
int)outEdges.size())].insert(node);
249 for (
NBEdge* e : outEdges) {
250 if (e->isBidiRail() && bidiEdges.count(e->getTurnDestination(
true)) == 0) {
253 if (e->getID()[0] ==
'-') {
255 }
else if (primary->
getID()[0] !=
'-' && secondary->
getID()[0] !=
'-' && secondary->
getID() < primary->
getID()) {
258 if (bidiEdges.count(secondary) == 0) {
260 bidiEdges.insert(primary);
270 int numBufferStops = 0;
271 if (verbose && types.size() > 0) {
272 WRITE_MESSAGE(
TL(
"Railway nodes by number of incoming,outgoing edges:"))
277 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are outgoing");
281 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are incoming");
285 device.
writeAttr(
"meaning",
"an incoming edge has a sharp angle to all outgoing edges");
289 device.
writeAttr(
"meaning",
"an outgoing edge has a sharp angle from all incoming edges");
293 for (
auto it : types) {
294 int numBrokenType = 0;
295 device.
openTag(
"railNodeType");
296 int in = it.first.first;
297 int out = it.first.second;
300 for (
NBNode* n : it.second) {
308 std::string broken =
"";
318 for (
NBEdge* e : inRail) {
329 for (
NBEdge* e : outRail) {
340 if (((in == 1 && out == 1) || (in == 2 && out == 2))
345 if (broken.size() > 0) {
347 brokenNodes.insert(n);
359 +
" count: " +
toString(it.second.size()) +
" broken: " +
toString(numBrokenType));
373 for (
NBEdge* e : bidiEdges) {
376 device.
writeAttr(
"bidi", e->getTurnDestination(
true)->getID());
390 std::set<NBNode*> railNodes;
391 int numRailEdges = 0;
392 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
393 if (
hasRailway(it->second->getPermissions())) {
395 railNodes.insert(it->second->getFromNode());
396 railNodes.insert(it->second->getToNode());
399 int numRailSignals = 0;
400 for (
const NBNode*
const node : railNodes) {
438#ifdef DEBUG_SEQSTOREVERSE
443 for (
NBEdge* e1 : edges) {
444 for (
NBEdge* e2 : edges2) {
464 if (e != candOut &&
isStraight(node, e, candOut)) {
466 std::cout <<
" isStraight e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
472 if (e != candOut && !
isStraight(node, e, candOut)) {
474 std::cout <<
" isSharp e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
491 if (!e1->isBidiRail(
true)) {
497 return !
allBidi || countBidiAsSharp;
504 if (!e->isBidiRail()) {
515 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
533 if (bidiOut ==
nullptr) {
538 tmpBidiOut.push_back(bidiOut);
540 tmpBidiIn.push_back(bidiIn);
544 for (
NBEdge* cand : outRail) {
546 if (!cand->isBidiRail() &&
isStraight(node, bidiIn, cand)
548 &&
allSharp(node, inRail, tmpBidiOut,
true)) {
555 for (
NBEdge* cand : inRail) {
557 if (!cand->isBidiRail() &&
isStraight(node, cand, bidiOut)
559 &&
allSharp(node, outRail, tmpBidiIn,
true)) {
574 std::vector<EdgeVector> seqsToReverse;
575 for (
NBNode* n : brokenNodes) {
578 for (
NBEdge* start : outRail) {
580 tmp.push_back(start);
582 if (!
allBroken(n, start, inRail, outRail)
583 || (inRail.size() == 1 && outRail.size() == 1)) {
584#ifdef DEBUG_SEQSTOREVERSE
586 std::cout <<
" abort at start n=" << n->getID() <<
" (not all broken)\n";
595 seq.push_back(start);
597 NBNode* n2 = start->getToNode();
600 if (brokenNodes.count(n2) != 0) {
602 tmp2.push_back(start);
603 if (
allBroken(n2, start, outRail2, inRail2)) {
604 seqsToReverse.push_back(seq);
606#ifdef DEBUG_SEQSTOREVERSE
608 std::cout <<
" abort at n2=" << n2->
getID() <<
" (not all broken)\n";
614 if (outRail2.size() == 0) {
617#ifdef DEBUG_SEQSTOREVERSE
619 std::cout <<
" abort at n2=" << n2->
getID() <<
" (border)\n";
622 }
else if (outRail2.size() > 1 || inRail2.size() > 1) {
625#ifdef DEBUG_SEQSTOREVERSE
627 std::cout <<
" abort at n2=" << n2->
getID() <<
" (switch)\n";
631 start = outRail2.front();
638 if (seqsToReverse.size() > 0) {
641 std::sort(seqsToReverse.begin(), seqsToReverse.end(),
643 return a.size() < b.size();
646 std::set<NBNode*> affectedEndpoints;
647 std::set<std::string> reversedIDs;
648 std::map<int, int> seqLengths;
650 NBNode* seqStart = seq.front()->getFromNode();
651 NBNode* seqEnd = seq.back()->getToNode();
653 if (affectedEndpoints.count(seqStart) == 0
654 && affectedEndpoints.count(seqEnd) == 0) {
655 affectedEndpoints.insert(seqStart);
656 affectedEndpoints.insert(seqEnd);
659 e->reinitNodes(e->getToNode(), e->getFromNode());
660 e->setGeometry(e->getGeometry().reverse());
661 reversedIDs.insert(e->getID());
663 seqLengths[(int)seq.size()]++;
667 if (numReversed > 0) {
670 if (reversedIDs.count(item.second->getEdgeId())) {
671 item.second->findLaneAndComputeBusStopExtent(ec);
684 int numBufferStops = 0;
685 int numAddedBidiTotal = 0;
686 for (
NBNode* node : railNodes) {
688 if (node->getEdges().size() != 1) {
689 WRITE_WARNINGF(
TL(
"Ignoring buffer stop junction '%' with % edges."), node->getID(), node->getEdges().size());
692 int numAddedBidi = 0;
699 while (prev ==
nullptr || (inRail.size() + outRail.size()) == 3) {
701 if (prev ==
nullptr) {
702 assert(node->getEdges().size() == 1);
703 e = node->getEdges().front();
708 assert(inRail.size() == 2);
709 e = inRail.front() == prev2 ? inRail.back() : inRail.front();
712 assert(outRail.size() == 2);
713 e = outRail.front() == prev2 ? outRail.back() : outRail.front();
745 if (numAddedBidiTotal > 0) {
748 return numAddedBidiTotal;
755 if (inRail.size() == 2 && outRail.size() == 1 &&
isStraight(n, inRail.front(), inRail.back())) {
756 if (
isStraight(n, inRail.front(), outRail.front())) {
757 return inRail.front();
758 }
else if (
isStraight(n, inRail.back(), outRail.front())) {
759 return inRail.back();
762 if (inRail.size() == 1 && outRail.size() == 2 &&
isStraight(n, outRail.front(), outRail.back())) {
763 if (
isStraight(n, outRail.front(), inRail.front())) {
764 return outRail.front();
765 }
else if (
isStraight(n, outRail.back(), inRail.front())) {
766 return outRail.back();
776 std::map<int, int> seqLengths;
779 for (
NBNode* n : brokenNodes) {
782 std::vector<NBNode*> nodeSeq;
785 nodeSeq.push_back(prev);
786 edgeSeq.push_back(edge);
794 if (allRail.size() == 2 &&
isStraight(next, allRail.front(), allRail.back())) {
796 edge = allRail.front() == edge ? allRail.back() : allRail.front();
797 nodeSeq.push_back(prev);
798 edgeSeq.push_back(edge);
807 for (
NBEdge* e : edgeSeq) {
810 seqLengths[(int)edgeSeq.size()]++;
812 numAdded += (int)edgeSeq.size();
826 if (seqLengths.size() > 0) {
835 std::set<NBPTLine*> result;
836 std::set<std::pair<std::shared_ptr<NBPTStop>, std::shared_ptr<NBPTStop> > > visited;
837 for (
const auto& item : lc.
getLines()) {
838 const std::vector<std::shared_ptr<NBPTStop> >& stops = item.second->getStops();
839 if (stops.size() > 1) {
840 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
841 std::shared_ptr<NBPTStop> fromStop = *it;
842 std::shared_ptr<NBPTStop> toStop = *(it + 1);
843 visited.insert({fromStop, toStop});
847 for (
const auto& item : lc.
getLines()) {
848 const std::vector<std::shared_ptr<NBPTStop> >& stops = item.second->getStops();
849 if (stops.size() > 1) {
850 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
851 std::shared_ptr<NBPTStop> fromStop = *it;
852 std::shared_ptr<NBPTStop> toStop = *(it + 1);
853 std::pair<std::shared_ptr<NBPTStop>, std::shared_ptr<NBPTStop> > reverseTrip({toStop, fromStop});
854 if (visited.count(reverseTrip)) {
855 result.insert(item.second);
868 std::vector<Track*> tracks;
870 tracks.push_back(
new Track(edge));
872 const int numEdges = (int)tracks.size();
874 tracks.push_back(
new Track(edge, (
int)tracks.size(), edge->getID() +
"_reverse"));
877 std::map<NBEdge*, std::pair<Track*, Track*> > stopTracks;
880 Track* start =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_start");
881 tracks.push_back(start);
882 Track* end =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_end");
883 tracks.push_back(end);
884 stopTracks[edge] = {start, end};
891 for (
NBEdge* e1 : railEdges) {
892 for (
NBEdge* e2 : railEdges) {
894 int i = e1->getNumericalID();
895 int i2 = e2->getNumericalID();
896 if (e1->getToNode() == node) {
897 if (e2->getFromNode() == node) {
899 tracks[i]->addSuccessor(tracks[i2]);
901 tracks[i2 + numEdges]->addSuccessor(tracks[i + numEdges]);
904 tracks[i]->addSuccessor(tracks[i2 + numEdges]);
905 tracks[i2]->addSuccessor(tracks[i + numEdges]);
908 if (e2->getFromNode() == node) {
910 tracks[i + numEdges]->addSuccessor(tracks[i2]);
911 tracks[i2 + numEdges]->addSuccessor(tracks[i]);
922 for (
auto& item : stopTracks) {
923 const int index = item.first->getNumericalID();
925 item.second.first->addSuccessor(tracks[index]);
926 item.second.first->addSuccessor(tracks[index + numEdges]);
928 tracks[index]->addSuccessor(item.second.second);
929 tracks[index + numEdges]->addSuccessor(item.second.second);
945 int numDisconnected = 0;
946 std::set<NBEdge*, ComparatorIdLess> addBidiStops;
947 std::set<NBEdge*, ComparatorIdLess> addBidiEdges;
948 std::set<std::pair<std::string, std::string> > visited;
955 for (
const auto& item : lc.
getLines()) {
957 std::vector<std::pair<NBEdge*, std::string> > stops = line->
getStopEdges(ec);
960 if (routeStart !=
nullptr) {
961 stops.insert(stops.begin(), {routeStart, routeStart->getID()});
963 if (routeEnd !=
nullptr) {
964 stops.push_back({routeEnd, routeEnd->
getID()});
966 if (stops.size() < 2) {
969 std::vector<NBEdge*> stopEdges;
970 for (
auto it : stops) {
971 stopEdges.push_back(it.first);
973 if (!line->
isConsistent(stopEdges) && requireBidi.count(line) == 0) {
974 WRITE_WARNINGF(
TL(
"Edge sequence is not consistent with stop sequence in line '%', not adding bidi edges."), item.first);
977 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
978 NBEdge* fromEdge = it->first;
979 NBEdge* toEdge = (it + 1)->first;
980 const std::string fromStop = it->second;
981 const std::string toStop = (it + 1)->second;
982 std::pair<std::string, std::string> trip(fromStop, toStop);
983 std::pair<std::string, std::string> reverseTrip(toStop, fromStop);
985 if (visited.count(trip) != 0) {
988 visited.insert(trip);
990 if (stopTracks.count(fromEdge) == 0
991 || stopTracks.count(toEdge) == 0) {
994 const bool needBidi = visited.count(reverseTrip) != 0;
996 std::vector<const Track*> route;
997 router->
compute(stopTracks[fromEdge].first, stopTracks[toEdge].second, &veh, 0, route);
1001 if (route.size() > 0) {
1002 assert(route.size() > 2);
1003 for (
int i = 1; i < (int)route.size() - 1; ++i) {
1004 if (route[i]->getNumericalID() >= numEdges || needBidi) {
1005 NBEdge* edge = route[i]->edge;
1006 if (addBidiEdges.count(edge) == 0) {
1007 bool isStop = i == 1 || i == (int)route.size() - 2;
1010 addBidiEdges.insert(edge);
1012 addBidiStops.insert(edge);
1016 WRITE_WARNINGF(
TL(
"Stop on edge '%' can only be reached in reverse but edge has the wrong spreadType."), fromEdge->
getID());
1019 }
else if (isStop && needBidi) {
1020 std::shared_ptr<NBPTStop> fs = sc.
get(fromStop);
1021 std::shared_ptr<NBPTStop> fromReverse = sc.
getReverseStop(fs, ec);
1024 fs->setBidiStop(fromReverse);
1026 std::shared_ptr<NBPTStop> ts = sc.
get(toStop);
1030 ts->setBidiStop(toReverse);
1042 for (
NBEdge* edge : addBidiEdges) {
1043 if (!edge->isBidiRail()) {
1046 if (e2 !=
nullptr) {
1056 if (addBidiEdges.size() > 0 || numDisconnected > 0) {
1057 WRITE_MESSAGE(
"Added " +
toString(addBidiStops.size()) +
" bidi-edges for public transport stops and a total of "
1058 +
toString(added) +
" bidi-edges to ensure connectivity of stops ("
1059 +
toString(numDisconnected) +
" stops remain disconnected)");
1063 for (
Track* t : tracks) {
1067 return (
int)addBidiEdges.size();
1075 for (
const auto& e : ec) {
1076 if (!
hasRailway(e.second->getPermissions())) {
1079 NBNode*
const from = e.second->getFromNode();
1080 NBNode*
const to = e.second->getToNode();
1081 if (brokenNodes.count(from) == 0 && brokenNodes.count(to) == 0) {
1084 if (e.second->isBidiRail()) {
1087 EdgeVector inRailFrom, outRailFrom, inRailTo, outRailTo;
1092 bool haveStraight =
false;
1093 bool haveStraightReverse =
false;
1094 if (!geometryLike || outRailFrom.size() + inRailFrom.size() == 2) {
1095 for (
const NBEdge* fromStraightCand : outRailFrom) {
1096 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1097 haveStraightReverse =
true;
1102 if (haveStraightReverse) {
1103 for (
const NBEdge* fromStraightCand : inRailFrom) {
1104 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1105 haveStraight =
true;
1112 if ((!haveStraightReverse || haveStraight) && (!geometryLike || outRailTo.size() + inRailTo.size() == 2)) {
1115 haveStraight =
false;
1116 haveStraightReverse =
false;
1117 for (
const NBEdge* toStraightCand : inRailTo) {
1118 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1119 haveStraightReverse =
true;
1124 if (haveStraightReverse) {
1125 for (
const NBEdge* toStraightCand : outRailTo) {
1126 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1127 haveStraight =
true;
1135 if (haveStraightReverse && !haveStraight) {
1138 if (e2 !=
nullptr) {
1147 WRITE_MESSAGEF(
TL(
"Added % bidi-edges to ensure connectivity of straight tracks at geometry-like nodes."),
toString(added));
1186 std::set<NBEdge*, ComparatorIdLess> bidi;
1191 if (!edge->isBidiRail()) {
1192 edge->setPriority(4);
1198 if (edge->getPriority() >= 0) {
1207 if (uni.size() == 0) {
1208 if (bidi.size() != 0) {
1209 WRITE_WARNING(
TL(
"Cannot extend track direction priority because there are no track edges with positive priority"));
1216 while (!check.empty()) {
1217 NBEdge* edge = *check.begin();
1219 if (seen.count(edge) != 0) {
1225 forward.insert(straightOut);
1226 check.insert(straightOut);
1230 forward.insert(straightIn);
1231 check.insert(straightIn);
1233#ifdef DEBUG_DIRECTION_PRIORITY
1241 for (
NBEdge* edge : bidi) {
1242 NBEdge* bidiEdge =
const_cast<NBEdge*
>(edge->getBidiEdge());
1245 if (forward.count(edge) != 0) {
1246 if (forward.count(bidiEdge) == 0) {
1255 if (forward.count(bidiEdge) != 0) {
1264 if (bidiEdge ==
nullptr) {
1265 WRITE_WARNINGF(
TL(
"Edge '%' was loaded with undefined priority (%) but has unambiguous main direction (no bidi edge)"), edge->getID(), edge->getPriority());
1267 if (edge->getPriority() >= 0) {
1270 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() >= 0) {
1273 if (edge->getPriority() < 0) {
1274 edge->setPriority(prio);
1276 if (bidiEdge !=
nullptr && bidiEdge->
getPriority() < 0) {
1280 std::map<int, int> numPrios;
1281 for (
NBEdge* edge : bidi) {
1282 numPrios[edge->getPriority()]++;
#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
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)
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.
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