#pragma once
#include <config.h>
#include <string>
#include <vector>
#include <utils/common/SUMOVehicleClass.h>
#include <utils/common/ValueTimeLine.h>
#include <utils/common/RandHelper.h>
#include <utils/common/Named.h>
#include "IntermodalTrip.h"
template <class E, class L>
inline const L* getSidewalk(const E* edge, SUMOVehicleClass svc = SVC_PEDESTRIAN) {
if (edge == nullptr) {
return nullptr;
}
const std::vector<L*>& lanes = edge->getLanes();
for (const L* const lane : lanes) {
if (lane->getPermissions() == svc) {
return lane;
}
}
for (const L* const lane : lanes) {
if (lane->allowsVehicleClass(svc)) {
return lane;
}
}
if (svc != SVC_PEDESTRIAN) {
for (const L* const lane : lanes) {
if (lane->getPermissions() == SVC_PEDESTRIAN) {
return lane;
}
}
for (const L* const lane : lanes) {
if (lane->allowsVehicleClass(SVC_PEDESTRIAN)) {
return lane;
}
}
}
return nullptr;
}
template<class E, class L, class N, class V>
class IntermodalEdge : public Named {
public:
IntermodalEdge(const std::string id, int numericalID, const E* edge, const std::string& line, const double length = -1) :
Named(id),
myNumericalID(numericalID),
myEdge(edge),
myLine(line),
myLength(edge == nullptr || length >= 0. ? MAX2(0.0, length) : edge->getLength()),
myEfforts(nullptr) { }
virtual ~IntermodalEdge() {}
virtual bool includeInRoute(bool ) const {
return false;
}
inline const std::string& getLine() const {
return myLine;
}
inline const E* getEdge() const {
return myEdge;
}
int getNumericalID() const {
return myNumericalID;
}
void addSuccessor(IntermodalEdge* const s, IntermodalEdge* const via = nullptr) {
myFollowingEdges.push_back(s);
myFollowingViaEdges.push_back(std::make_pair(s, via));
}
void transferSuccessors(IntermodalEdge* to) {
to->myFollowingEdges = myFollowingEdges;
to->myFollowingViaEdges = myFollowingViaEdges;
myFollowingEdges.clear();
myFollowingViaEdges.clear();
}
bool removeSuccessor(const IntermodalEdge* const edge) {
auto it = std::find(myFollowingEdges.begin(), myFollowingEdges.end(), edge);
if (it != myFollowingEdges.end()) {
myFollowingEdges.erase(it);
} else {
return false;
}
for (auto viaIt = myFollowingViaEdges.begin(); viaIt != myFollowingViaEdges.end();) {
if (viaIt->first == edge) {
viaIt = myFollowingViaEdges.erase(viaIt);
} else {
++viaIt;
}
}
return true;
}
virtual const std::vector<IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const {
UNUSED_PARAMETER(vClass);
return myFollowingEdges;
}
virtual const std::vector<std::pair<const IntermodalEdge*, const IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
UNUSED_PARAMETER(vClass);
UNUSED_PARAMETER(ignoreTransientPermissions);
return myFollowingViaEdges;
}
virtual bool prohibits(const IntermodalTrip<E, N, V>* const ) const {
return false;
}
virtual bool restricts(const IntermodalTrip<E, N, V>* const ) const {
return false;
}
virtual inline double getPartialLength(const IntermodalTrip<E, N, V>* const ) const {
return myLength;
}
virtual inline double getTravelTime(const IntermodalTrip<E, N, V>* const , double ) const {
return 0.;
}
virtual inline double getTravelTimeAggregated(const IntermodalTrip<E, N, V>* const trip, double time) const {
return getTravelTime(trip, time);
}
virtual inline double getIntended(const double , std::string& ) const {
return 0.;
}
static inline double getTravelTimeStatic(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
return edge == nullptr ? 0. : edge->getTravelTime(trip, time);
}
static inline double getTravelTimeStaticRandomized(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
return edge == nullptr ? 0. : edge->getTravelTime(trip, time) * RandHelper::rand(1., gWeightsRandomFactor);
}
static inline double getTravelTimeAggregated(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
return edge == nullptr ? 0. : edge->getTravelTimeAggregated(trip, time);
}
virtual double getEffort(const IntermodalTrip<E, N, V>* const , double ) const {
return 0.;
}
static inline double getEffortStatic(const IntermodalEdge* const edge, const IntermodalTrip<E, N, V>* const trip, double time) {
return edge == nullptr || !edge->hasEffort() ? 0. : edge->getEffort(trip, time);
}
inline double getLength() const {
return myLength;
}
inline void setLength(const double length) {
assert(length >= 0);
myLength = length;
}
inline bool isInternal() const {
return myEdge != nullptr && myEdge->isInternal();
}
virtual bool hasEffort() const {
return myEfforts != nullptr;
}
virtual double getStartPos() const {
return 0.;
}
virtual double getEndPos() const {
return myLength;
}
inline double getSpeedLimit() const {
return myEdge != nullptr ? myEdge->getSpeedLimit() : 200. / 3.6;
}
inline double getLengthGeometryFactor() const {
return myEdge != nullptr ? myEdge->getLengthGeometryFactor() : 1;
}
inline double getDistanceTo(const IntermodalEdge* other) const {
return myEdge != nullptr && other->myEdge != nullptr && myEdge != other->myEdge ? myEdge->getDistanceTo(other->myEdge, true) : 0.;
}
inline double getMinimumTravelTime(const IntermodalTrip<E, N, V>* const trip) const {
return myLength / trip->getMaxSpeed();
}
IntermodalEdge* getBidiEdge() const {
return nullptr;
}
protected:
std::vector<IntermodalEdge*> myFollowingEdges;
std::vector<std::pair<const IntermodalEdge*, const IntermodalEdge*> > myFollowingViaEdges;
private:
const int myNumericalID;
const E* const myEdge;
const std::string myLine;
double myLength;
ValueTimeLine<double>* myEfforts;
private:
IntermodalEdge(const IntermodalEdge& src);
IntermodalEdge& operator=(const IntermodalEdge& src);
};