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
66 const 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];
84 const std::vector<std::pair<const NBRailwayTopologyAnalyzer::Track*, const NBRailwayTopologyAnalyzer::Track*> >&
86 if ((minPermissions & svc) != 0) {
89 if (svcViaSuccessors.count(svc) == 0) {
90 std::vector<std::pair<const Track*, const Track*> >& succ = svcViaSuccessors[svc];
91 for (
const Track*
const t : successors) {
92 if ((t->edge->getPermissions() & svc) != 0) {
93 succ.push_back(std::make_pair(t,
nullptr));
97 return svcViaSuccessors[svc];
131 int numRailEdges = 0;
132 int numBidiEdges = 0;
133 int numNotCenterEdges = 0;
134 int numAddedBidiEdges = 0;
136 std::vector<NBEdge*> edges;
137 if (inputfile ==
"") {
139 edges.push_back(edge);
142 std::set<std::string> edgeIDs;
144 for (
const std::string& edgeID : edgeIDs) {
146 if (edge !=
nullptr) {
147 edges.push_back(edge);
151 for (
NBEdge* edge : edges) {
156 if (!edge->isBidiRail()) {
170 WRITE_MESSAGE(
"Added " +
toString(numAddedBidiEdges) +
" bidi-edges to ensure that all tracks are usable in both directions.");
171 if (numNotCenterEdges) {
172 WRITE_WARNING(
"Ignore " +
toString(numNotCenterEdges) +
" edges because they have the wrong spreadType");
174 return numAddedBidiEdges;
181 const std::string id2 = (edge->
getID()[0] ==
'-'
182 ? edge->
getID().substr(1)
183 :
"-" + edge->
getID());
192 if (
isRailway(incoming->getPermissions())) {
193 incoming->invalidateConnections();
209 inEdges.push_back(e);
214 outEdges.push_back(e);
223 std::set<NBNode*> brokenNodes;
229 std::set<NBNode*> railNodes =
getRailNodes(nb, verbose);
230 std::map<std::pair<int, int>, std::set<NBNode*, ComparatorIdLess> > types;
231 std::set<NBEdge*, ComparatorIdLess> bidiEdges;
232 std::set<NBEdge*, ComparatorIdLess> bufferStops;
233 for (
NBNode* node : railNodes) {
236 types[std::make_pair((
int)inEdges.size(), (
int)outEdges.size())].insert(node);
237 for (
NBEdge* e : outEdges) {
238 if (e->isBidiRail() && bidiEdges.count(e->getTurnDestination(
true)) == 0) {
241 if (e->getID()[0] ==
'-') {
242 std::swap(primary, secondary);
243 }
else if (primary->
getID()[0] !=
'-' && secondary->
getID()[0] !=
'-' && secondary->
getID() < primary->
getID()) {
244 std::swap(primary, secondary);
246 if (bidiEdges.count(secondary) == 0) {
248 bidiEdges.insert(primary);
258 int numBufferStops = 0;
259 if (verbose && types.size() > 0) {
260 WRITE_MESSAGE(
"Railway nodes by number of incoming,outgoing edges:")
265 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are outgoing");
269 device.
writeAttr(
"meaning",
"edge pair angle supports driving but both are incoming");
273 device.
writeAttr(
"meaning",
"an incoming edge has a sharp angle to all outgoing edges");
277 device.
writeAttr(
"meaning",
"an outgoing edge has a sharp angle from all incoming edges");
281 for (
auto it : types) {
282 int numBrokenType = 0;
283 device.
openTag(
"railNodeType");
284 int in = it.first.first;
285 int out = it.first.second;
288 for (
NBNode* n : it.second) {
296 std::string broken =
"";
306 for (
NBEdge* e : inRail) {
317 for (
NBEdge* e : outRail) {
328 if (((in == 1 && out == 1) || (in == 2 && out == 2))
333 if (broken.size() > 0) {
335 brokenNodes.insert(n);
347 +
" count: " +
toString(it.second.size()) +
" broken: " +
toString(numBrokenType));
361 for (
NBEdge* e : bidiEdges) {
364 device.
writeAttr(
"bidi", e->getTurnDestination(
true)->getID());
378 std::set<NBNode*> railNodes;
381 int numRailEdges = 0;
382 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
383 if (
isRailway(it->second->getPermissions())) {
385 railNodes.
insert(it->second->getFromNode());
386 railNodes.insert(it->second->getToNode());
390 std::set<NBNode*> railSignals;
391 for (
NBNode* node : railNodes) {
393 railSignals.insert(node);
429 #ifdef DEBUG_SEQSTOREVERSE
434 for (
NBEdge* e1 : edges) {
435 for (
NBEdge* e2 : edges2) {
455 if (e != candOut &&
isStraight(node, e, candOut)) {
457 std::cout <<
" isStraight e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
463 if (e != candOut && !
isStraight(node, e, candOut)) {
465 std::cout <<
" isSharp e=" << e->getID() <<
" candOut=" << candOut->
getID() <<
"\n";
482 if (!e1->isBidiRail(
true)) {
488 return !
allBidi || countBidiAsSharp;
495 if (!e->isBidiRail()) {
507 for (
auto it = ec.
begin(); it != ec.
end(); it++) {
525 if (bidiOut ==
nullptr) {
530 tmpBidiOut.push_back(bidiOut);
532 tmpBidiIn.push_back(bidiIn);
536 for (
NBEdge* cand : outRail) {
538 if (!cand->isBidiRail() &&
isStraight(node, bidiIn, cand)
540 &&
allSharp(node, inRail, tmpBidiOut,
true)) {
547 for (
NBEdge* cand : inRail) {
549 if (!cand->isBidiRail() &&
isStraight(node, cand, bidiOut)
551 &&
allSharp(node, outRail, tmpBidiIn,
true)) {
566 std::vector<EdgeVector> seqsToReverse;
567 for (
NBNode* n : brokenNodes) {
570 for (
NBEdge* start : outRail) {
572 tmp.push_back(start);
574 if (!
allBroken(n, start, inRail, outRail)
575 || (inRail.size() == 1 && outRail.size() == 1)) {
576 #ifdef DEBUG_SEQSTOREVERSE
578 std::cout <<
" abort at start n=" << n->getID() <<
" (not all broken)\n";
587 seq.push_back(start);
589 NBNode* n2 = start->getToNode();
592 if (brokenNodes.count(n2) != 0) {
594 tmp2.push_back(start);
595 if (
allBroken(n2, start, outRail2, inRail2)) {
596 seqsToReverse.push_back(seq);
598 #ifdef DEBUG_SEQSTOREVERSE
600 std::cout <<
" abort at n2=" << n2->
getID() <<
" (not all broken)\n";
606 if (outRail2.size() == 0) {
609 #ifdef DEBUG_SEQSTOREVERSE
611 std::cout <<
" abort at n2=" << n2->
getID() <<
" (border)\n";
614 }
else if (outRail2.size() > 1 || inRail2.size() > 1) {
617 #ifdef DEBUG_SEQSTOREVERSE
619 std::cout <<
" abort at n2=" << n2->
getID() <<
" (switch)\n";
623 start = outRail2.front();
630 if (seqsToReverse.size() > 0) {
631 WRITE_MESSAGE(
"Found " +
toString(seqsToReverse.size()) +
" reversible edge sequences between broken rail nodes");
633 std::sort(seqsToReverse.begin(), seqsToReverse.end(),
635 return a.size() < b.size();
638 std::set<NBNode*> affectedEndpoints;
639 std::set<std::string> reversedIDs;
640 std::map<int, int> seqLengths;
642 NBNode* seqStart = seq.front()->getFromNode();
643 NBNode* seqEnd = seq.back()->getToNode();
645 if (affectedEndpoints.count(seqStart) == 0
646 && affectedEndpoints.count(seqEnd) == 0) {
647 affectedEndpoints.insert(seqStart);
648 affectedEndpoints.insert(seqEnd);
651 e->reinitNodes(e->getToNode(), e->getFromNode());
652 e->setGeometry(e->getGeometry().reverse());
653 reversedIDs.insert(e->getID());
655 seqLengths[(int)seq.size()]++;
659 if (numReversed > 0) {
662 if (reversedIDs.count(item.second->getEdgeId())) {
663 item.second->findLaneAndComputeBusStopExtent(nb.
getEdgeCont());
676 int numBufferStops = 0;
677 int numAddedBidiTotal = 0;
678 for (
NBNode* node : railNodes) {
680 if (node->getEdges().size() != 1) {
681 WRITE_WARNING(
"Ignoring buffer stop junction '" + node->getID() +
"' with " +
toString(node->getEdges().size()) +
" edges\n");
684 int numAddedBidi = 0;
691 while (prev ==
nullptr || (inRail.size() + outRail.size()) == 3) {
693 if (prev ==
nullptr) {
694 assert(node->getEdges().size() == 1);
695 e = node->getEdges().front();
700 assert(inRail.size() == 2);
701 e = inRail.front() == prev2 ? inRail.back() : inRail.front();
704 assert(outRail.size() == 2);
705 e = outRail.front() == prev2 ? outRail.back() : outRail.front();
737 if (numAddedBidiTotal > 0) {
738 WRITE_MESSAGE(
"Added " +
toString(numAddedBidiTotal) +
" edges to connect " +
toString(numBufferStops) +
" buffer stops in both directions.");
740 return numAddedBidiTotal;
747 if (inRail.size() == 2 && outRail.size() == 1 &&
isStraight(n, inRail.front(), inRail.back())) {
748 if (
isStraight(n, inRail.front(), outRail.front())) {
749 return inRail.front();
750 }
else if (
isStraight(n, inRail.back(), outRail.front())) {
751 return inRail.back();
754 if (inRail.size() == 1 && outRail.size() == 2 &&
isStraight(n, outRail.front(), outRail.back())) {
755 if (
isStraight(n, outRail.front(), inRail.front())) {
756 return outRail.front();
757 }
else if (
isStraight(n, outRail.back(), inRail.front())) {
758 return outRail.back();
768 std::map<int, int> seqLengths;
771 for (
NBNode* n : brokenNodes) {
773 if (edge !=
nullptr) {
774 std::vector<NBNode*> nodeSeq;
777 nodeSeq.push_back(prev);
778 edgeSeq.push_back(edge);
786 if (allRail.size() == 2 &&
isStraight(next, allRail.front(), allRail.back())) {
788 edge = allRail.front() == edge ? allRail.back() : allRail.front();
789 nodeSeq.push_back(prev);
790 edgeSeq.push_back(edge);
799 for (
NBEdge* e : edgeSeq) {
802 seqLengths[(int)edgeSeq.size()]++;
804 numAdded += (int)edgeSeq.size();
818 if (seqLengths.size() > 0) {
830 std::vector<Track*> tracks;
832 tracks.push_back(
new Track(edge));
834 const int numEdges = (int)tracks.
size();
836 tracks.push_back(
new Track(edge, (
int)tracks.size(), edge->getID() +
"_reverse"));
839 std::map<NBEdge*, std::pair<Track*, Track*> > stopTracks;
842 Track* start =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_start");
843 tracks.push_back(start);
844 Track* end =
new Track(edge, (
int)tracks.size(), edge->getID() +
"_end");
845 tracks.push_back(end);
846 stopTracks[edge] = std::make_pair(start, end);
853 for (
NBEdge* e1 : railEdges) {
854 for (
NBEdge* e2 : railEdges) {
856 int i = e1->getNumericalID();
857 int i2 = e2->getNumericalID();
858 if (e1->getToNode() == node) {
859 if (e2->getFromNode() == node) {
861 tracks[i]->addSuccessor(tracks[i2]);
863 tracks[i2 + numEdges]->addSuccessor(tracks[i + numEdges]);
866 tracks[i]->addSuccessor(tracks[i2 + numEdges]);
867 tracks[i2]->addSuccessor(tracks[i + numEdges]);
870 if (e2->getFromNode() == node) {
872 tracks[i + numEdges]->addSuccessor(tracks[i2]);
873 tracks[i2 + numEdges]->addSuccessor(tracks[i]);
884 for (
auto& item : stopTracks) {
885 const int index = item.first->getNumericalID();
887 item.second.first->addSuccessor(tracks[index]);
888 item.second.first->addSuccessor(tracks[index + numEdges]);
890 tracks[index]->addSuccessor(item.second.second);
891 tracks[index + numEdges]->addSuccessor(item.second.second);
907 int numDisconnected = 0;
908 std::set<NBEdge*, ComparatorIdLess> addBidiStops;
909 std::set<NBEdge*, ComparatorIdLess> addBidiEdges;
910 std::set<std::pair<NBEdge*, NBEdge*> > visited;
916 if (routeStart !=
nullptr) {
917 stops.insert(stops.begin(), routeStart);
919 if (routeEnd !=
nullptr) {
920 stops.push_back(routeEnd);
922 if (stops.size() < 2) {
925 for (
auto it = stops.begin(); it + 1 != stops.end(); ++it) {
927 NBEdge* toEdge = *(it + 1);
928 std::pair<NBEdge*, NBEdge*> trip(fromEdge, toEdge);
930 if (visited.count(trip) != 0) {
933 visited.insert(trip);
935 if (stopTracks.count(fromEdge) == 0
936 || stopTracks.count(toEdge) == 0) {
940 std::vector<const Track*> route;
941 router->
compute(stopTracks[fromEdge].first, stopTracks[toEdge].second, &veh, 0, route);
945 if (route.size() > 0) {
946 assert(route.size() > 2);
947 for (
int i = 1; i < (int)route.size() - 1; ++i) {
948 if (route[i]->getNumericalID() >= numEdges) {
949 NBEdge* edge = route[i]->edge;
950 if (addBidiEdges.count(edge) == 0) {
952 bool isStop = i == 1 || i == (int)route.size() - 2;
954 addBidiEdges.insert(edge);
956 addBidiStops.insert(edge);
960 WRITE_WARNINGF(
"Stop on edge '%' can only be reached in reverse but edge has the wrong spreadType.", fromEdge->
getID());
973 for (
NBEdge* edge : addBidiEdges) {
974 if (!edge->isBidiRail()) {
987 if (addBidiEdges.size() > 0 || numDisconnected > 0) {
988 WRITE_MESSAGE(
"Added " +
toString(addBidiStops.size()) +
" bidi-edges for public transport stops and a total of "
989 +
toString(added) +
" bidi-edges to ensure connectivity of stops ("
990 +
toString(numDisconnected) +
" stops remain disconnected)");
994 for (
Track* t : tracks) {
998 return (
int)addBidiEdges.size();
1007 if (!
isRailway(e.second->getPermissions())) {
1010 NBNode*
const from = e.second->getFromNode();
1011 NBNode*
const to = e.second->getToNode();
1012 if (brokenNodes.count(from) == 0 && brokenNodes.count(to) == 0) {
1015 if (e.second->isBidiRail()) {
1018 EdgeVector inRailFrom, outRailFrom, inRailTo, outRailTo;
1023 bool haveStraight =
false;
1024 bool haveStraightReverse =
false;
1025 if (!geometryLike || outRailFrom.size() + inRailFrom.size() == 2) {
1026 for (
const NBEdge* fromStraightCand : outRailFrom) {
1027 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1028 haveStraightReverse =
true;
1033 if (haveStraightReverse) {
1034 for (
const NBEdge* fromStraightCand : inRailFrom) {
1035 if (fromStraightCand != e.second &&
isStraight(from, fromStraightCand, e.second)) {
1036 haveStraight =
true;
1043 if ((!haveStraightReverse || haveStraight) && (!geometryLike || outRailTo.size() + inRailTo.size() == 2)) {
1046 haveStraight =
false;
1047 haveStraightReverse =
false;
1048 for (
const NBEdge* toStraightCand : inRailTo) {
1049 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1050 haveStraightReverse =
true;
1055 if (haveStraightReverse) {
1056 for (
const NBEdge* toStraightCand : outRailTo) {
1057 if (toStraightCand != e.second &&
isStraight(to, toStraightCand, e.second)) {
1058 haveStraight =
true;
1066 if (haveStraightReverse && !haveStraight) {
1069 if (e2 !=
nullptr) {
1078 WRITE_MESSAGE(
"Added " +
toString(added) +
" bidi-edges to ensure connectivity of straight tracks at geometry-like nodes.");
1080 WRITE_MESSAGE(
"Added " +
toString(added) +
" bidi-edges to ensure connectivity of straight tracks at switches.");
1120 if (
isRailway(edge->getPermissions())) {
1122 if (!edge->isBidiRail()) {
1123 edge->setPriority(4);
1129 if (edge->getPriority() >= 0) {
1138 if (uni.size() == 0) {
1139 if (bidi.size() != 0) {
1140 WRITE_WARNING(
"Cannot extend track direction priority because there are no track edges with positive priority");
1147 while (!check.empty()) {
1148 NBEdge* edge = *check.begin();
1150 if (seen.count(edge) != 0) {
1156 forward.insert(straightOut);
1157 check.insert(straightOut);
1161 forward.insert(straightIn);
1162 check.insert(straightIn);
1164 #ifdef DEBUG_DIRECTION_PRIORITY
1172 for (
NBEdge* edge : bidi) {
1173 NBEdge* bidiEdge =
const_cast<NBEdge*
>(edge->getBidiEdge());
1176 if (forward.count(edge) != 0) {
1177 if (forward.count(bidiEdge) == 0) {
1186 if (forward.count(bidiEdge) != 0) {
1195 if (edge->getPriority() >= 0) {
1201 if (edge->getPriority() < 0) {
1208 std::map<int, int> numPrios;
1209 for (
NBEdge* edge : bidi) {
1210 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
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.
int size() const
Returns the number of edges.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end 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.
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
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)
const std::string & getID() const
NBNode * getToNode() const
Returns the destination node of the edge.
NBEdge * getStraightPredecessor(SVCPermissions permissions) const
return the straightest predecessor edge for the given permissions or nullptr (never returns turn-arou...
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
const PositionVector & getGeometry() const
Returns the geometry of the edge.
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of 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.
NBNode * getFromNode() const
Returns the origin node 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.
Instance responsible for building networks.
NBPTLineCont & getPTLineCont()
Returns a reference to the pt line container.
NBEdgeCont & getEdgeCont()
NBPTStopCont & getPTStopCont()
Returns a reference to the pt stop container.
Represents a single node (junction) during network building.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const std::map< std::string, NBPTLine * > & getLines() const
NBEdge * getRouteEnd(const NBEdgeCont &ec) const
return last valid edge of myRoute (if it doest not lie before the last stop)
const std::string & getRef() const
get line reference (not unique)
NBEdge * getRouteStart(const NBEdgeCont &ec) const
return first valid edge of myRoute (if it doest not lie after the first stop)
std::vector< NBEdge * > getStopEdges(const NBEdgeCont &ec) const
get stop edges
const std::map< std::string, NBPTStop * > & getStops() const
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 addBidiEdgesForBufferStops(NBNetBuilder &nb)
add bidi-edges to connect buffers stops in both directions
static void getRailEdges(const NBNode *node, EdgeVector &inEdges, EdgeVector &outEdges)
filter out rail edges among all edges of a the given node
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 int repairTopology(NBNetBuilder &nb)
static NBEdge * addBidiEdge(NBNetBuilder &nb, NBEdge *edge, bool update=true)
add bidi-edge for the given edge
static std::set< NBNode * > getBrokenRailNodes(NBNetBuilder &nb, bool verbose=false)
static void analyzeTopology(NBNetBuilder &nb)
Computes highway on-/off-ramps (if wished)
static int extendBidiEdges(NBNetBuilder &nb)
add further bidi-edges near existing bidi-edges
static int makeAllBidi(NBNetBuilder &nb)
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 bool allBidi(const EdgeVector &edges)
static int reverseEdges(NBNetBuilder &nb)
reverse edges sequences that are to broken nodes on both sides
static int addBidiEdgesForStops(NBNetBuilder &nb)
add bidi-edges to connect successive public transport stops
static double getTravelTimeStatic(const Track *const track, const NBVehicle *const veh, double time)
static void extendDirectionPriority(NBNetBuilder &nb, bool fromUniDir)
static std::set< NBNode * > getRailNodes(NBNetBuilder &nb, bool verbose=false)
static bool hasStraightPair(const NBNode *node, const EdgeVector &edges, const EdgeVector &edges2)
static int addBidiEdgesBetweenSwitches(NBNetBuilder &nb)
add bidi-edges to connect switches that are approached in both directions
static int addBidiEdgesForStraightConnectivity(NBNetBuilder &nb, bool geometryLike)
add bidi-edges to connect straight tracks
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.
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
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.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
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