1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-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    MSRoute.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Friedemann Wesner
13 /// @author  Sascha Krieg
14 /// @author  Michael Behrisch
15 /// @author  Jakob Erdmann
16 /// @date    Sept 2002
17 /// @version $Id$
18 ///
19 // A vehicle route
20 /****************************************************************************/
21 #ifndef MSRoute_h
22 #define MSRoute_h
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <string>
31 #include <map>
32 #include <vector>
33 #include <algorithm>
34 #include <utils/common/Named.h>
35 #include <utils/distribution/RandomDistributor.h>
36 #include <utils/common/RGBColor.h>
37 #include <utils/vehicle/SUMOVehicleParameter.h>
38 #include <utils/common/Parameterised.h>
39 #ifdef HAVE_FOX
40 #include <fx.h>
41 #include <FXThread.h>
42 #endif
43 
44 
45 // ===========================================================================
46 // class declarations
47 // ===========================================================================
48 class MSEdge;
49 class BinaryInputDevice;
50 class OutputDevice;
51 
52 
53 // ===========================================================================
54 // types definitions
55 // ===========================================================================
56 typedef std::vector<const MSEdge*> ConstMSEdgeVector;
57 typedef std::vector<MSEdge*> MSEdgeVector;
58 typedef ConstMSEdgeVector::const_iterator MSRouteIterator;
59 
60 
61 // ===========================================================================
62 // class definitions
63 // ===========================================================================
64 /**
65  * @class MSRoute
66  */
67 class MSRoute : public Named, public Parameterised {
68 public:
69     /// Constructor
70     MSRoute(const std::string& id, const ConstMSEdgeVector& edges,
71             const bool isPermanent, const RGBColor* const c,
72             const std::vector<SUMOVehicleParameter::Stop>& stops);
73 
74     /// Destructor
75     virtual ~MSRoute();
76 
77     /// Returns the begin of the list of edges to pass
78     MSRouteIterator begin() const;
79 
80     /// Returns the end of the list of edges to pass
81     MSRouteIterator end() const;
82 
83     /// Returns the number of edges to pass
84     int size() const;
85 
86     /// returns the destination edge
87     const MSEdge* getLastEdge() const;
88 
89     /** @brief increments the reference counter for the route */
90     void addReference() const;
91 
92     /** @brief deletes the route if there are no further references to it*/
93     void release() const;
94 
95     /** @brief Output the edge ids up to but not including the id of the given edge
96      * @param[in] os The stream to write the routes into (binary)
97      * @param[in] from The first edge to be written
98      * @param[in] upTo The first edge that shall not be written
99      * @return The number of edges written
100      */
101     int writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo = 0) const;
102 
contains(const MSEdge * const edge)103     bool contains(const MSEdge* const edge) const {
104         return std::find(myEdges.begin(), myEdges.end(), edge) != myEdges.end();
105     }
106 
107     bool containsAnyOf(const MSEdgeVector& edgelist) const;
108 
109     const MSEdge* operator[](int index) const;
110 
111     /// @name State I/O (mesosim only)
112     /// @{
113 
114     /** @brief Saves all known routes into the given stream
115      *
116      * @param[in] os The stream to write the routes into (binary)
117      */
118     static void dict_saveState(OutputDevice& out);
119     /// @}
120 
getEdges()121     const ConstMSEdgeVector& getEdges() const {
122         return myEdges;
123     }
124 
125     /** @brief Compute the distance between 2 given edges on this route, including the length of internal lanes.
126      * Note, that for edges which contain loops:
127      * - the first occurance of fromEdge will be used
128      * - the first occurance of toEdge after the first occurance of fromEdge will be used
129      *
130      * @param[in] fromPos  position on the first edge, at wich the computed distance begins
131      * @param[in] toPos    position on the last edge, at which the coumputed distance endsance
132      * @param[in] fromEdge edge at wich computation begins
133      * @param[in] toEdge   edge at which distance computation shall stop
134      * @param[in] includeInternal Whether the lengths of internal edges shall be counted
135      * @param[in] routePosition Optional offset when searching for the fromEdge within the route
136      * @return             distance between the position fromPos on fromEdge and toPos on toEdge
137      */
138     double getDistanceBetween(double fromPos, double toPos, const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal = true, int routePosition = 0) const;
139 
140     /** @brief Compute the distance between 2 given edges on this route, including the length of internal lanes.
141      * This has the same semantics as above but uses iterators instead of edge
142      * points so looping routes are not an issue.
143      *
144      * @param[in] fromPos  position on the first edge, at wich the computed distance begins
145      * @param[in] toPos    position on the last edge, at which the coumputed distance endsance
146      * @param[in] fromEdge edge at wich computation begins
147      * @param[in] toEdge   edge at which distance computation shall stop
148      * @param[in] includeInternal Whether the lengths of internal edges shall be counted
149      * @return             distance between the position fromPos on fromEdge and toPos on toEdge
150      */
151     double getDistanceBetween(double fromPos, double toPos, const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal = true) const;
152 
153     /// Returns the color
154     const RGBColor& getColor() const;
155 
156     /** @brief Returns the costs of the route
157      *
158      * @return The route's costs (normally the time needed to pass it)
159      */
getCosts()160     double getCosts() const {
161         return myCosts;
162     }
163 
164     /** @brief Returns the estimated savings due to using this route (compare to the route before rerouting)
165      *
166      * @return The route's estimated savings (the difference in costs of this route to the previous one)
167      */
getSavings()168     double getSavings() const {
169         return mySavings;
170     }
171 
172     /** @brief Sets the costs of the route
173      *
174      * @param[in] costs The new route costs
175      */
setCosts(double costs)176     void setCosts(double costs) {
177         myCosts = costs;
178     }
179     /** @brief Sets the savings of the route
180      *
181      * @param[in] costs The new route costs
182      */
setSavings(double savings)183     void setSavings(double savings) {
184         mySavings = savings;
185     }
186 
187     /// Returns the stops
188     const std::vector<SUMOVehicleParameter::Stop>& getStops() const;
189 
190 public:
191     /** @brief Adds a route to the dictionary.
192      *
193      *  Returns true if the route could be added,
194      *  false if a route (distribution) with the same name already exists.
195      *
196      * @param[in] id    the id for the new route
197      * @param[in] route pointer to the route object
198      * @return          whether adding was successful
199      */
200     static bool dictionary(const std::string& id, const MSRoute* route);
201 
202     /** @brief Adds a route distribution to the dictionary.
203      *
204      *  Returns true if the distribution could be added,
205      *  false if a route (distribution) with the same name already exists.
206      *
207      * @param[in] id         the id for the new route distribution
208      * @param[in] routeDist  pointer to the distribution object
209      * @param[in] permanent  whether the new route distribution survives more than one vehicle / flow
210      * @return               whether adding was successful
211      */
212     static bool dictionary(const std::string& id, RandomDistributor<const MSRoute*>* const routeDist, const bool permanent = true);
213 
214     /** @brief Returns the named route or a sample from the named distribution.
215      *
216      *  Returns 0 if no route and no distribution with the given name exists
217      *  or if the distribution exists and is empty.
218      *
219      * @param[in] id    the id of the route or the distribution
220      * @return          the route (sample)
221      */
222     static const MSRoute* dictionary(const std::string& id, std::mt19937* rng = 0);
223 
224     /** @brief Returns the named route distribution.
225      *
226      *  Returns 0 if no route distribution with the given name exists.
227      *
228      * @param[in] id    the id of the route distribution
229      * @return          the route distribution
230      */
231     static RandomDistributor<const MSRoute*>* distDictionary(const std::string& id);
232 
233     /// Clears the dictionary (delete all known routes, too)
234     static void clear();
235 
236     /// Checks the distribution whether it is permanent and deletes it if not
237     static void checkDist(const std::string& id);
238 
239     static void insertIDs(std::vector<std::string>& into);
240 
241 private:
242     /// The list of edges to pass
243     ConstMSEdgeVector myEdges;
244 
245     /// whether the route may be deleted after the last vehicle abandoned it
246     const bool myAmPermanent;
247 
248     /// Information by how many vehicles the route is used
249     mutable int myReferenceCounter;
250 
251     /// The color
252     const RGBColor* const myColor;
253 
254     /// @brief The assigned or calculated costs
255     double myCosts;
256 
257     /// @brief The estimated savings when rerouting
258     double mySavings;
259 
260     /// @brief List of the stops on the parsed route
261     std::vector<SUMOVehicleParameter::Stop> myStops;
262 
263 private:
264     /// Definition of the dictionary container
265     typedef std::map<std::string, const MSRoute*> RouteDict;
266 
267     /// The dictionary container
268     static RouteDict myDict;
269 
270     /// Definition of the dictionary container
271     typedef std::map<std::string, std::pair<RandomDistributor<const MSRoute*>*, bool> > RouteDistDict;
272 
273     /// The dictionary container
274     static RouteDistDict myDistDict;
275 
276 #ifdef HAVE_FOX
277     /// @brief the mutex for the route dictionaries
278     static FXMutex myDictMutex;
279 #endif
280 private:
281     /** invalid assignment operator */
282     MSRoute& operator=(const MSRoute& s);
283 
284 };
285 
286 
287 #endif
288 
289 /****************************************************************************/
290 
291