#pragma once
#include <config.h>
#ifdef HAVE_FOX
#include <utils/foxtools/fxheader.h>
#endif
#include "IntermodalEdge.h"
template<class E, class L, class N, class V>
class CarEdge : public IntermodalEdge<E, L, N, V> {
private:
typedef IntermodalEdge<E, L, N, V> _IntermodalEdge;
public:
CarEdge(int numericalID, const E* edge, const double pos = -1.) :
_IntermodalEdge(edge->getID() + "_car" + toString(pos), numericalID, edge, "!car"),
myStartPos(pos >= 0 ? pos : 0.) { }
bool includeInRoute(bool ) const {
return true;
}
const std::vector<_IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const {
if (vClass == SVC_IGNORING) {
return this->myFollowingEdges;
}
#ifdef HAVE_FOX
FXMutexLock locker(myLock);
#endif
typename std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> >::const_iterator i = myClassesSuccessorMap.find(vClass);
if (i != myClassesSuccessorMap.end()) {
return i->second;
} else {
const std::set<const E*> classedCarFollowers = std::set<const E*>(this->getEdge()->getSuccessors(vClass).begin(), this->getEdge()->getSuccessors(vClass).end());
for (_IntermodalEdge* const e : this->myFollowingEdges) {
if (!e->includeInRoute(false) || e->getEdge() == this->getEdge() || classedCarFollowers.count(e->getEdge()) > 0) {
myClassesSuccessorMap[vClass].push_back(e);
}
}
return myClassesSuccessorMap[vClass];
}
}
virtual const std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
if (vClass == SVC_IGNORING) {
return this->myFollowingViaEdges;
}
#ifdef HAVE_FOX
FXMutexLock locker(myLock);
#endif
auto& viaMap = ignoreTransientPermissions ? myOrigClassesViaSuccessorMap : myClassesViaSuccessorMap;
typename std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > >::const_iterator i = viaMap.find(vClass);
if (i != viaMap.end()) {
return i->second;
} else {
std::set<const E*> classedCarFollowers;
for (const auto& pair : this->getEdge()->getViaSuccessors(vClass)) {
classedCarFollowers.insert(pair.first);
}
for (const std::pair<const _IntermodalEdge*, const _IntermodalEdge*>& e : this->myFollowingViaEdges) {
if (!e.first->includeInRoute(false) || e.first->getEdge() == this->getEdge() || classedCarFollowers.count(e.first->getEdge()) > 0) {
viaMap[vClass].push_back(e);
}
}
return viaMap[vClass];
}
}
bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
return trip->vehicle == 0 || this->getEdge()->prohibits(trip->vehicle);
}
double getPartialLength(const IntermodalTrip<E, N, V>* const trip) const {
double length = this->getLength();
if (this->getEdge() == trip->to && trip->arrivalPos >= myStartPos && trip->arrivalPos < myStartPos + this->getLength()) {
length = trip->arrivalPos - myStartPos;
}
if (this->getEdge() == trip->from && trip->departPos >= myStartPos && trip->departPos < myStartPos + this->getLength()) {
length -= trip->departPos - myStartPos;
}
return length;
}
double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const {
assert(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time) >= 0.);
return getPartialTravelTime(E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time), trip);
}
double getTravelTimeAggregated(const IntermodalTrip<E, N, V>* const trip, double time) const {
assert(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time) >= 0.);
return getPartialTravelTime(E::getTravelTimeAggregated(this->getEdge(), trip->vehicle, time), trip);
}
double getStartPos() const {
return myStartPos;
}
double getEndPos() const {
return myStartPos + this->getLength();
}
private:
inline double getPartialTravelTime(double fullTravelTime, const IntermodalTrip<E, N, V>* const trip) const {
const double distTravelled = getPartialLength(trip);
assert(fullTravelTime * distTravelled / this->getEdge()->getLength() >= 0.);
return fullTravelTime * distTravelled / this->getEdge()->getLength();
}
private:
const double myStartPos;
mutable std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> > myClassesSuccessorMap;
mutable std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > > myClassesViaSuccessorMap;
mutable std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > > myOrigClassesViaSuccessorMap;
#ifdef HAVE_FOX
mutable FXMutex myLock;
#endif
};