1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file CarEdge.h 11 /// @author Michael Behrisch 12 /// @date Mon, 03 March 2014 13 /// @version $Id$ 14 /// 15 // The CarEdge is a special intermodal edge representing the SUMO network edge 16 /****************************************************************************/ 17 #ifndef CarEdge_h 18 #define CarEdge_h 19 20 21 // =========================================================================== 22 // included modules 23 // =========================================================================== 24 #include <config.h> 25 26 #ifdef HAVE_FOX 27 #include <fx.h> 28 #endif 29 #include "IntermodalEdge.h" 30 31 32 // =========================================================================== 33 // class definitions 34 // =========================================================================== 35 /// @brief the car edge type that is given to the internal router (SUMOAbstractRouter) 36 template<class E, class L, class N, class V> 37 class CarEdge : public IntermodalEdge<E, L, N, V> { 38 private: 39 typedef IntermodalEdge<E, L, N, V> _IntermodalEdge; 40 41 public: 42 CarEdge(int numericalID, const E* edge, const double pos = -1.) : 43 _IntermodalEdge(edge->getID() + "_car" + toString(pos), numericalID, edge, "!car"), 44 myStartPos(pos >= 0 ? pos : 0.) { } 45 includeInRoute(bool)46 bool includeInRoute(bool /* allEdges */) const { 47 return true; 48 } 49 50 const std::vector<_IntermodalEdge*>& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { 51 if (vClass == SVC_IGNORING) { 52 return this->myFollowingEdges; 53 } 54 #ifdef HAVE_FOX 55 FXMutexLock locker(myLock); 56 #endif 57 typename std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> >::const_iterator i = myClassesSuccessorMap.find(vClass); 58 if (i != myClassesSuccessorMap.end()) { 59 // can use cached value 60 return i->second; 61 } else { 62 // this vClass is requested for the first time. rebuild all successors 63 const std::set<const E*> classedCarFollowers = std::set<const E*>(this->getEdge()->getSuccessors(vClass).begin(), this->getEdge()->getSuccessors(vClass).end()); 64 for (_IntermodalEdge* const e : this->myFollowingEdges) { 65 if (!e->includeInRoute(false) || e->getEdge() == this->getEdge() || classedCarFollowers.count(e->getEdge()) > 0) { 66 myClassesSuccessorMap[vClass].push_back(e); 67 } 68 } 69 return myClassesSuccessorMap[vClass]; 70 } 71 } 72 73 virtual const std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { 74 if (vClass == SVC_IGNORING) { 75 return this->myFollowingViaEdges; 76 } 77 #ifdef HAVE_FOX 78 FXMutexLock locker(myLock); 79 #endif 80 typename std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > >::const_iterator i = myClassesViaSuccessorMap.find(vClass); 81 if (i != myClassesViaSuccessorMap.end()) { 82 // can use cached value 83 return i->second; 84 } else { 85 // this vClass is requested for the first time. rebuild all successors 86 const std::set<std::pair<const E*, const E*> > classedCarFollowers = std::set<std::pair<const E*, const E*> >(this->getEdge()->getViaSuccessors(vClass).begin(), this->getEdge()->getViaSuccessors(vClass).end()); 87 for (const std::pair<const _IntermodalEdge*, const _IntermodalEdge*>& e : this->myFollowingViaEdges) { 88 const auto viaPair = std::make_pair(e.first->getEdge(), e.second == nullptr ? nullptr : e.second->getEdge()); 89 if (!e.first->includeInRoute(false) || e.first->getEdge() == this->getEdge() || classedCarFollowers.count(viaPair) > 0) { 90 myClassesViaSuccessorMap[vClass].push_back(e); 91 } 92 } 93 return myClassesViaSuccessorMap[vClass]; 94 } 95 } 96 prohibits(const IntermodalTrip<E,N,V> * const trip)97 bool prohibits(const IntermodalTrip<E, N, V>* const trip) const { 98 return trip->vehicle == 0 || this->getEdge()->prohibits(trip->vehicle); 99 } 100 getTravelTime(const IntermodalTrip<E,N,V> * const trip,double time)101 double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const { 102 const double travelTime = E::getTravelTimeStatic(this->getEdge(), trip->vehicle, time); 103 double distTravelled = this->getLength(); 104 // checking arrivalPos first to have it correct for identical depart and arrival edge 105 if (this->getEdge() == trip->to) { 106 distTravelled = trip->arrivalPos - myStartPos; 107 } 108 if (this->getEdge() == trip->from) { 109 distTravelled -= trip->departPos - myStartPos; 110 } 111 return travelTime * distTravelled / this->getEdge()->getLength(); 112 } 113 getStartPos()114 double getStartPos() const { 115 return myStartPos; 116 } 117 getEndPos()118 double getEndPos() const { 119 return myStartPos + this->getLength(); 120 } 121 122 private: 123 /// @brief the starting position for split edges 124 const double myStartPos; 125 126 /// @brief The successors available for a given vClass 127 mutable std::map<SUMOVehicleClass, std::vector<_IntermodalEdge*> > myClassesSuccessorMap; 128 129 /// @brief The successors available for a given vClass 130 mutable std::map<SUMOVehicleClass, std::vector<std::pair<const _IntermodalEdge*, const _IntermodalEdge*> > > myClassesViaSuccessorMap; 131 132 #ifdef HAVE_FOX 133 /// The mutex used to avoid concurrent updates of myClassesSuccessorMap 134 mutable FXMutex myLock; 135 #endif 136 }; 137 138 139 #endif 140 141 /****************************************************************************/ 142