#pragma once
#include <config.h>
#include <set>
#include <vector>
class NBEdge;
class NBEdgeCont;
class NBPTStopCont;
class NBPTLine;
class NBPTLineCont;
class OptionsCont;
class NBVehicle;
class NBRailwayTopologyAnalyzer {
public:
static void analyzeTopology(NBEdgeCont& ec);
static int repairTopology(NBEdgeCont& ec, NBPTStopCont& sc, NBPTLineCont& lc);
static int makeAllBidi(NBEdgeCont& ec);
static void extendDirectionPriority(NBEdgeCont& ec, bool fromUniDir);
class Track {
public:
Track(NBEdge* e, int i = -1, const std::string& _id = "", double _penalty = 1) :
edge(e),
penalty(_penalty),
index(i < 0 ? edge->getNumericalID() : i),
id(_id == "" ? edge->getID() : _id),
minPermissions(edge->getPermissions()) {
}
void addSuccessor(Track* track);
const std::vector<Track*>& getSuccessors(SUMOVehicleClass svc = SVC_IGNORING) const;
const std::vector<std::pair<const Track*, const Track*> >& getViaSuccessors(SUMOVehicleClass svc = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
const std::string& getID() const {
return id;
}
int getNumericalID() const {
return index;
}
double getLength() const {
return 0;
}
const Track* getBidiEdge() const {
return this;
}
bool isInternal() const {
return false;
}
inline bool prohibits(const NBVehicle* const ) const {
return false;
}
inline bool restricts(const NBVehicle* const ) const {
return false;
}
NBEdge* edge;
double penalty;
private:
const int index;
const std::string id;
std::vector<Track*> successors;
std::vector<std::pair<const Track*, const Track*> > viaSuccessors;
SVCPermissions minPermissions;
mutable std::map<SUMOVehicleClass, std::vector<Track*> > svcSuccessors;
mutable std::map<SUMOVehicleClass, std::vector<std::pair<const Track*, const Track*> > > svcViaSuccessors;
Track& operator=(const Track&) = delete;
};
static double getTravelTimeStatic(const Track* const track, const NBVehicle* const veh, double time);
static std::set<NBNode*> getRailNodes(NBEdgeCont& ec, bool verbose = false);
private:
static std::set<NBNode*> getBrokenRailNodes(NBEdgeCont& ec, bool verbose = false);
static void getRailEdges(const NBNode* node, EdgeVector& inEdges, EdgeVector& outEdges);
static bool hasRailway(SVCPermissions permissions) {
return (permissions & SVC_RAIL_CLASSES) > 0 && permissions != SVCAll;
}
static bool isStraight(const NBNode* node, const NBEdge* e1, const NBEdge* e2);
static bool hasStraightPair(const NBNode* node, const EdgeVector& edges, const EdgeVector& edges2);
static bool allBroken(const NBNode* node, NBEdge* candOut, const EdgeVector& in, const EdgeVector& out);
static bool allSharp(const NBNode* node, const EdgeVector& in, const EdgeVector& out, bool countBidiAsSharp = false);
static bool allBidi(const EdgeVector& edges);
static NBEdge* isBidiSwitch(const NBNode* n);
static NBEdge* addBidiEdge(NBEdgeCont& ec, NBEdge* edge, bool update = true);
static int extendBidiEdges(NBEdgeCont& ec);
static int extendBidiEdges(NBEdgeCont& ec, NBNode* node, NBEdge* bidiIn);
static int reverseEdges(NBEdgeCont& ec, NBPTStopCont& sc);
static int addBidiEdgesForBufferStops(NBEdgeCont& ec);
static int addBidiEdgesBetweenSwitches(NBEdgeCont& ec);
static int addBidiEdgesForStops(NBEdgeCont& ec, NBPTLineCont& lc, NBPTStopCont& sc, bool minimal);
static int addBidiEdgesForStraightConnectivity(NBEdgeCont& ec, bool geometryLike);
static void updateTurns(NBEdge* edge);
static std::set<NBPTLine*> findBidiCandidates(NBPTLineCont& lc);
};
class NBRailwaySignalGuesser {
public:
static int guessRailSignals(NBEdgeCont& ec, NBPTStopCont& sc);
private:
static int guessByStops(NBEdgeCont& ec, NBPTStopCont& sc, double minLength);
static bool canBeSignal(const NBNode* node);
};
class NBRailwayGeometryHelper {
public:
static int straigthenCorrdidor(NBEdgeCont& ec, double maxAngle);
};