Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSRoute.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Friedemann Wesner
17 : /// @author Sascha Krieg
18 : /// @author Michael Behrisch
19 : /// @author Jakob Erdmann
20 : /// @date Sept 2002
21 : ///
22 : // A vehicle route
23 : /****************************************************************************/
24 : #pragma once
25 : #include <config.h>
26 :
27 : #include <string>
28 : #include <map>
29 : #include <vector>
30 : #include <algorithm>
31 : #include <memory>
32 : #include <utils/common/Named.h>
33 : #include <utils/distribution/RandomDistributor.h>
34 : #include <utils/common/RGBColor.h>
35 : #include <utils/vehicle/SUMOVehicleParameter.h>
36 : #include <utils/common/Parameterised.h>
37 : #ifdef HAVE_FOX
38 : #include <utils/foxtools/fxheader.h>
39 : #include <FXThread.h>
40 : #endif
41 :
42 :
43 : // ===========================================================================
44 : // class declarations
45 : // ===========================================================================
46 : class MSEdge;
47 : class MSLane;
48 : class MSRoute;
49 : class OutputDevice;
50 :
51 :
52 : // ===========================================================================
53 : // types definitions
54 : // ===========================================================================
55 : typedef std::vector<const MSEdge*> ConstMSEdgeVector;
56 : typedef std::vector<MSEdge*> MSEdgeVector;
57 : typedef ConstMSEdgeVector::const_iterator MSRouteIterator;
58 : typedef std::shared_ptr<const MSRoute> ConstMSRoutePtr;
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 StopParVector& stops,
73 : SUMOTime replacedTime = -1,
74 : int replacedIndex = 0);
75 :
76 : /// Destructor
77 : virtual ~MSRoute();
78 :
79 : /// Returns the begin of the list of edges to pass
80 : MSRouteIterator begin() const;
81 :
82 : /// Returns the end of the list of edges to pass
83 : MSRouteIterator end() const;
84 :
85 : /// Returns the number of edges to pass
86 : int size() const;
87 :
88 : /// returns the destination edge
89 : const MSEdge* getLastEdge() const;
90 :
91 : /// returns the origin edge
92 : const MSEdge* getFirstEdge() const;
93 :
94 : /** @brief removes the route from the internal dict if it is not marked as permanent */
95 : void checkRemoval(bool force = false) const;
96 :
97 : /** @brief Output the edge ids up to but not including the id of the given edge
98 : * @param[in] os The stream to write the routes into (binary)
99 : * @param[in] firstIndex index of the first edge to be written
100 : * @param[in] lastIndex index of the first edge that shall not be written (-1 writes all remaining)
101 : * @param[in] withInternal Whether internal edges shall be included
102 : * @param[in] svc The vClass for determining internal edges
103 : * @return The number of edges written
104 : */
105 : int writeEdgeIDs(OutputDevice& os, int firstIndex = 0, int lastIndex = -1, bool withInternal = false, SUMOVehicleClass svc = SVC_IGNORING) const;
106 :
107 : bool contains(const MSEdge* const edge) const {
108 117053 : return std::find(myEdges.begin(), myEdges.end(), edge) != myEdges.end();
109 : }
110 :
111 : bool containsAnyOf(const MSEdgeVector& edgelist) const;
112 :
113 : const MSEdge* operator[](int index) const;
114 :
115 : /// @name State I/O
116 : /// @{
117 :
118 : /** @brief Saves all known routes into the given stream
119 : *
120 : * @param[in] os The stream to write the routes into (binary)
121 : */
122 : static void dict_saveState(OutputDevice& out);
123 :
124 : /** @brief Decrement all route references before quick-loading state */
125 : static void dict_clearState();
126 : /// @}
127 :
128 : const ConstMSEdgeVector& getEdges() const {
129 2507117 : return myEdges;
130 : }
131 :
132 : /** @brief Compute the distance between 2 given edges on this route, optionally including the length of internal lanes.
133 : * Note, that for routes which contain loops:
134 : * - the first occurance of fromEdge after routePosition will be used
135 : * - the first occurance of toEdge after the above occurance of fromEdge will be used
136 : * If fromEdge or toEdge are not in the route or the toPos on toEdge is not downstream of fromPos on fromEdge
137 : * std::numeric_limits<double>::max() will be returned.
138 : *
139 : * The code will work with internal edges as fromEdge and toEdge and also the route may contain internal edges
140 : * but only at the start or the end, not between two regular edges. If the route contains internal edges at the begin
141 : * routePosition needs to be 0.
142 : *
143 : * @param[in] fromPos position on the first edge, at wich the computed distance begins
144 : * @param[in] toPos position on the last edge, at which the computed distance ends
145 : * @param[in] fromLane lane at wich computation begins
146 : * @param[in] toLane lane at which distance computation shall stop
147 : * @param[in] routePosition Optional offset when searching for the fromEdge within the route
148 : * @return distance between the position fromPos on fromEdge and toPos on toEdge
149 : */
150 : double getDistanceBetween(double fromPos, double toPos, const MSLane* fromLane, const MSLane* toLane, int routePosition = 0) const;
151 :
152 : /** @brief Compute the distance between 2 given edges on this route, optionally including the length of internal lanes.
153 : * This has the same semantics as above but uses iterators instead of edge
154 : * points so looping routes are not an issue.
155 : *
156 : * @param[in] fromPos position on the first edge, at wich the computed distance begins
157 : * @param[in] toPos position on the last edge, at which the coumputed distance endsance
158 : * @param[in] fromEdge edge at wich computation begins
159 : * @param[in] toEdge edge at which distance computation shall stop
160 : * @param[in] includeInternal Whether the lengths of internal edges shall be counted
161 : * @return distance between the position fromPos on fromEdge and toPos on toEdge
162 : */
163 : double getDistanceBetween(double fromPos, double toPos, const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal = true) const;
164 :
165 :
166 : /// @brief Returns the color
167 : const RGBColor& getColor() const;
168 :
169 : /// @brief returns the period
170 : SUMOTime getPeriod() const {
171 2047285 : return myPeriod;
172 : }
173 :
174 : /** @brief Returns the costs of the route
175 : *
176 : * @return The route's costs (normally the time needed to pass it)
177 : */
178 : double getCosts() const {
179 47463 : return myCosts;
180 : }
181 :
182 : /** @brief Returns the estimated savings due to using this route (compare to the route before rerouting)
183 : *
184 : * @return The route's estimated savings (the difference in costs of this route to the previous one)
185 : */
186 : double getSavings() const {
187 47445 : return mySavings;
188 : }
189 :
190 : /// @brief Returns the time at which this route was replaced (or -1)
191 : SUMOTime getReplacedTime() const {
192 1571 : return myReplacedTime;
193 : }
194 :
195 : /// @brief Returns the index at which this route was replaced
196 : int getReplacedIndex() const {
197 1571 : return myReplacedIndex;
198 : }
199 :
200 : /// @brief sets the period
201 : void setPeriod(SUMOTime period) {
202 205818 : myPeriod = period;
203 : }
204 :
205 : /** @brief Sets the costs of the route
206 : *
207 : * @param[in] costs The new route costs
208 : */
209 : void setCosts(double costs) {
210 1728643 : myCosts = costs;
211 : }
212 : /** @brief Sets the savings of the route
213 : *
214 : * @param[in] costs The new route costs
215 : */
216 : void setSavings(double savings) {
217 1522825 : mySavings = savings;
218 : }
219 :
220 : bool mustReroute() const {
221 329170 : return myReroute;
222 : }
223 :
224 : void setReroute(bool reroute = true) {
225 205818 : myReroute = reroute;
226 : }
227 :
228 : /// Returns the stops
229 : const StopParVector& getStops() const;
230 :
231 : public:
232 : /** @brief Adds a route to the dictionary.
233 : *
234 : * Returns true if the route could be added,
235 : * false if a route (distribution) with the same name already exists.
236 : *
237 : * @param[in] id the id for the new route
238 : * @param[in] route pointer to the route object
239 : * @return whether adding was successful
240 : */
241 : static bool dictionary(const std::string& id, ConstMSRoutePtr route);
242 :
243 : /** @brief Adds a route distribution to the dictionary.
244 : *
245 : * Returns true if the distribution could be added,
246 : * false if a route (distribution) with the same name already exists.
247 : *
248 : * @param[in] id the id for the new route distribution
249 : * @param[in] routeDist pointer to the distribution object
250 : * @param[in] permanent whether the new route distribution survives more than one vehicle / flow
251 : * @return whether adding was successful
252 : */
253 : static bool dictionary(const std::string& id, RandomDistributor<ConstMSRoutePtr>* const routeDist, const bool permanent = true);
254 :
255 : /** @brief Returns the named route or a sample from the named distribution.
256 : *
257 : * Returns 0 if no route and no distribution with the given name exists
258 : * or if the distribution exists and is empty.
259 : *
260 : * @param[in] id the id of the route or the distribution
261 : * @return the route (sample)
262 : */
263 : static ConstMSRoutePtr dictionary(const std::string& id, SumoRNG* rng = 0);
264 :
265 : /// @brief returns whether a route with the given id exists
266 : static bool hasRoute(const std::string& id);
267 :
268 : /** @brief Returns the named route distribution.
269 : *
270 : * Returns 0 if no route distribution with the given name exists.
271 : *
272 : * @param[in] id the id of the route distribution
273 : * @return the route distribution
274 : */
275 : static RandomDistributor<ConstMSRoutePtr>* distDictionary(const std::string& id);
276 :
277 : /// Clears the dictionary (delete all known routes, too)
278 : static void clear();
279 :
280 : /// Checks the distribution whether it is permanent and deletes it if not
281 : static void checkDist(const std::string& id);
282 :
283 : static void insertIDs(std::vector<std::string>& into);
284 :
285 : private:
286 : /// The list of edges to pass
287 : ConstMSEdgeVector myEdges;
288 :
289 : /// whether the route may be deleted after the last vehicle abandoned it
290 : const bool myAmPermanent;
291 :
292 : /// The color
293 : const RGBColor* const myColor;
294 :
295 : /// The period when repeating this route
296 : SUMOTime myPeriod;
297 :
298 : /// @brief The assigned or calculated costs
299 : double myCosts;
300 :
301 : /// @brief The estimated savings when rerouting
302 : double mySavings;
303 :
304 : /// @brief Whether this route is incomplete and requires rerouting
305 : bool myReroute;
306 :
307 : /// @brief List of the stops on the parsed route
308 : StopParVector myStops;
309 :
310 : /// The time where this route was replaced with an alternative route (or -1)
311 : SUMOTime myReplacedTime;
312 :
313 : /// The index where this route was replaced with an alternative route
314 : int myReplacedIndex;
315 :
316 : private:
317 : /// Definition of the dictionary container
318 : typedef std::map<std::string, ConstMSRoutePtr> RouteDict;
319 :
320 : /// The dictionary container
321 : static RouteDict myDict;
322 :
323 : /// Definition of the dictionary container
324 : typedef std::map<std::string, std::pair<RandomDistributor<ConstMSRoutePtr>*, bool> > RouteDistDict;
325 :
326 : /// The dictionary container
327 : static RouteDistDict myDistDict;
328 :
329 : #ifdef HAVE_FOX
330 : /// @brief the mutex for the route dictionaries
331 : static FXMutex myDictMutex;
332 : #endif
333 : private:
334 : /** invalid assignment operator */
335 : MSRoute& operator=(const MSRoute& s);
336 :
337 : };
|