#pragma once
#include <config.h>
#define TL_RED_PENALTY 20
template<class E, class L, class N, class V>
class PedestrianEdge : public IntermodalEdge<E, L, N, V> {
public:
PedestrianEdge(int numericalID, const E* edge, const L* lane, bool forward, const double pos = -1.) :
IntermodalEdge<E, L, N, V>(edge->getID() + (edge->isWalkingArea() ? "" : (forward ? "_fwd" : "_bwd")) + toString(pos), numericalID, edge, "!ped"),
myLane(lane),
myForward(forward),
myStartPos(pos >= 0 ? pos : (forward ? 0. : edge->getLength())),
myIsOpposite(false) {
if (!forward && (
edge->getFunction() == SumoXMLEdgeFunc::NORMAL
|| edge->getFunction() == SumoXMLEdgeFunc::INTERNAL)) {
const L* sidewalk = getSidewalk<E, L>(edge);
if (sidewalk != nullptr && sidewalk->getPermissions() != SVC_PEDESTRIAN) {
myIsOpposite = true;
}
}
}
bool includeInRoute(bool allEdges) const {
return allEdges || (!this->getEdge()->isCrossing() && !this->getEdge()->isWalkingArea() && !this->getEdge()->isInternal());
}
bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
if (trip->node == 0) {
return false;
} else {
return (this->getEdge()->getFromJunction() != trip->node
&& this->getEdge()->getToJunction() != trip->node);
}
}
double getPartialLength(const IntermodalTrip<E, N, V>* const trip) const {
double length = this->getLength();
if (this->getEdge() == trip->from && !myForward && trip->departPos < myStartPos) {
length = trip->departPos - (myStartPos - this->getLength());
}
if (this->getEdge() == trip->to && myForward && trip->arrivalPos < myStartPos + this->getLength()) {
length = trip->arrivalPos - myStartPos;
}
if (this->getEdge() == trip->from && myForward && trip->departPos > myStartPos) {
length -= (trip->departPos - myStartPos);
}
if (this->getEdge() == trip->to && !myForward && trip->arrivalPos > myStartPos - this->getLength()) {
length -= (trip->arrivalPos - (myStartPos - this->getLength()));
}
length = MAX2(length, NUMERICAL_EPS);
return length;
}
double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const {
const double length = getPartialLength(trip);
double tlsDelay = 0;
if (this->getEdge()->isCrossing()) {
double timeToCrossing = (time - STEPS2TIME(trip->departTime));
if (myLane->getIncomingLinkState() == LINKSTATE_TL_RED) {
tlsDelay += MAX2(double(0), TL_RED_PENALTY - timeToCrossing);
} else if (myLane->getIncomingLinkState() == LINKSTATE_TL_GREEN_MAJOR && timeToCrossing > TL_RED_PENALTY / 2) {
tlsDelay += TL_RED_PENALTY;
}
tlsDelay += this->getEdge()->getTimePenalty();
}
#ifdef IntermodalRouter_DEBUG_EFFORTS
std::cout << " effort for " << trip->getID() << " at " << time << " edge=" << this->getID() << " effort=" << length / trip->speed + tlsDelay << " l=" << length << " fullLength=" << this->getLength() << " s=" << trip->speed << " tlsDelay=" << tlsDelay << "\n";
#endif
return length / (trip->speed * (myIsOpposite ? gWeightsWalkOppositeFactor : 1)) + tlsDelay;
}
double getStartPos() const {
return myStartPos;
}
double getEndPos() const {
return myForward ? myStartPos + this->getLength() : myStartPos - this->getLength();
}
private:
const L* myLane;
const bool myForward;
const double myStartPos;
bool myIsOpposite;
};