Eclipse SUMO - Simulation of Urban MObility
MSRoute.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2002-2023 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/****************************************************************************/
21// A vehicle route
22/****************************************************************************/
23#include <config.h>
24
25#include <cassert>
26#include <algorithm>
27#include <limits>
31#include "MSEdge.h"
32#include "MSLane.h"
33#include "MSRoute.h"
34
35
36// ===========================================================================
37// static member variables
38// ===========================================================================
41#ifdef HAVE_FOX
42FXMutex MSRoute::myDictMutex(true);
43#endif
44
45
46// ===========================================================================
47// member method definitions
48// ===========================================================================
49MSRoute::MSRoute(const std::string& id,
50 const ConstMSEdgeVector& edges,
51 const bool isPermanent, const RGBColor* const c,
52 const std::vector<SUMOVehicleParameter::Stop>& stops,
53 SUMOTime replacedTime,
54 int replacedIndex) :
55 Named(id), myEdges(edges), myAmPermanent(isPermanent),
56 myColor(c),
57 myPeriod(0),
58 myCosts(-1),
59 mySavings(0),
60 myReroute(false),
61 myStops(stops),
62 myReplacedTime(replacedTime),
63 myReplacedIndex(replacedIndex)
64{}
65
66
68 delete myColor;
69}
70
71
74 return myEdges.begin();
75}
76
77
79MSRoute::end() const {
80 return myEdges.end();
81}
82
83
84int
86 return (int)myEdges.size();
87}
88
89
90const MSEdge*
92 assert(myEdges.size() > 0);
93 return myEdges.back();
94}
95
96
97void
99#ifdef HAVE_FOX
100 FXMutexLock f(myDictMutex);
101#endif
102 if (!myAmPermanent) {
103 myDict.erase(getID());
104 }
105}
106
107
108bool
109MSRoute::dictionary(const std::string& id, ConstMSRoutePtr route) {
110#ifdef HAVE_FOX
111 FXMutexLock f(myDictMutex);
112#endif
113 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
114 myDict[id] = route;
115 return true;
116 }
117 return false;
118}
119
120
121bool
122MSRoute::dictionary(const std::string& id, RandomDistributor<ConstMSRoutePtr>* const routeDist, const bool permanent) {
123#ifdef HAVE_FOX
124 FXMutexLock f(myDictMutex);
125#endif
126 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
127 myDistDict[id] = std::make_pair(routeDist, permanent);
128 return true;
129 }
130 return false;
131}
132
133
135MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
136#ifdef HAVE_FOX
137 FXMutexLock f(myDictMutex);
138#endif
139 RouteDict::iterator it = myDict.find(id);
140 if (it == myDict.end()) {
141 RouteDistDict::iterator it2 = myDistDict.find(id);
142 if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
143 return nullptr;
144 }
145 return it2->second.first->get(rng);
146 }
147 return it->second;
148}
149
150
151bool
152MSRoute::hasRoute(const std::string& id) {
153#ifdef HAVE_FOX
154 FXMutexLock f(myDictMutex);
155#endif
156 return myDict.find(id) != myDict.end();
157}
158
159
161MSRoute::distDictionary(const std::string& id) {
162#ifdef HAVE_FOX
163 FXMutexLock f(myDictMutex);
164#endif
165 RouteDistDict::iterator it2 = myDistDict.find(id);
166 if (it2 == myDistDict.end()) {
167 return nullptr;
168 }
169 return it2->second.first;
170}
171
172
173void
175#ifdef HAVE_FOX
176 FXMutexLock f(myDictMutex);
177#endif
178 for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
179 delete i->second.first;
180 }
181 myDistDict.clear();
182 myDict.clear();
183}
184
185
186void
187MSRoute::checkDist(const std::string& id) {
188#ifdef HAVE_FOX
189 FXMutexLock f(myDictMutex);
190#endif
191 RouteDistDict::iterator it = myDistDict.find(id);
192 if (it != myDistDict.end() && !it->second.second) {
193 delete it->second.first;
194 myDistDict.erase(it);
195 }
196}
197
198
199void
200MSRoute::insertIDs(std::vector<std::string>& into) {
201#ifdef HAVE_FOX
202 FXMutexLock f(myDictMutex);
203#endif
204 into.reserve(myDict.size() + myDistDict.size() + into.size());
205 for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
206 into.push_back((*i).first);
207 }
208 for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
209 into.push_back((*i).first);
210 }
211}
212
213
214int
215MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex, bool withInternal, SUMOVehicleClass svc) const {
216 //std::cout << SIMTIME << " writeEdgeIDs " << getID() << " first=" << firstIndex << " lastIndex=" << lastIndex << " edges=" << toString(myEdges) << "\n";
217 if (lastIndex < 0) {
218 lastIndex = (int)myEdges.size();
219 }
220 int internal = 0;
221 for (int i = firstIndex; i < lastIndex; i++) {
222 os << myEdges[i]->getID() << ' ';
223 if (withInternal && i + 1 < lastIndex) {
224 const MSEdge* next = myEdges[i + 1];
225 const MSEdge* edge = myEdges[i]->getInternalFollowingEdge(next, svc);
226 // Take into account non-internal lengths until next non-internal edge
227 while (edge != nullptr && edge->isInternal()) {
228 os << edge->getID() << ' ';
229 internal++;
230 edge = edge->getInternalFollowingEdge(next, svc);
231 }
232 }
233 }
234 return internal + lastIndex - firstIndex;
235}
236
237
238bool
239MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
240 MSEdgeVector::const_iterator i = edgelist.begin();
241 for (; i != edgelist.end(); ++i) {
242 if (contains(*i)) {
243 return true;
244 }
245 }
246 return false;
247}
248
249
250const MSEdge*
251MSRoute::operator[](int index) const {
252 return myEdges[index];
253}
254
255
256void
258#ifdef HAVE_FOX
259 FXMutexLock f(myDictMutex);
260#endif
261 for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
262 ConstMSRoutePtr r = (*it).second;
264 out.writeAttr(SUMO_ATTR_ID, r->getID());
265 out.writeAttr(SUMO_ATTR_STATE, r->myAmPermanent);
266 out.writeAttr(SUMO_ATTR_EDGES, r->myEdges);
267 if (r->myColor != nullptr) {
268 out.writeAttr(SUMO_ATTR_COLOR, *r->myColor);
269 }
270 for (auto stop : r->getStops()) {
271 stop.write(out);
272 }
273 out.closeTag();
274 }
275 for (const auto& item : myDistDict) {
276 if (item.second.first->getVals().size() > 0) {
278 out.writeAttr(SUMO_ATTR_STATE, item.second.second);
279 std::ostringstream oss;
280 bool space = false;
281 for (const auto& route : item.second.first->getVals()) {
282 if (space) {
283 oss << " ";
284 }
285 oss << route->getID();
286 space = true;
287 }
288 out.writeAttr(SUMO_ATTR_ROUTES, oss.str());
289 out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
290 out.closeTag();
291 }
292 }
293}
294
295
296void
298#ifdef HAVE_FOX
299 FXMutexLock f(myDictMutex);
300#endif
301 myDistDict.clear();
302 myDict.clear();
303}
304
305
306double
307MSRoute::getDistanceBetween(double fromPos, double toPos,
308 const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal, int routePosition) const {
309 //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
310 if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
311 throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
312 }
313 if (fromEdge->isInternal() && toEdge->isInternal() && fromEdge->getToJunction() == toEdge->getToJunction()) {
314 // internal edges within the same junction
315 if (fromEdge == toEdge) {
316 if (fromPos <= toPos) {
317 return toPos - fromPos;
318 }
319 } else if (fromEdge->getSuccessors().front() == toEdge) {
320 return fromEdge->getLength() - fromPos + toPos;
321 }
322 }
323 if (fromEdge->isInternal()) {
324 if (fromEdge == myEdges.front()) {
325 const MSEdge* succ = fromEdge->getSuccessors().front();
326 assert(succ != 0);
327 //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
328 return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
329 } else {
330 const MSEdge* pred = fromEdge->getPredecessors().front();
331 assert(pred != 0);
332 //std::cout << " recurse fromPred=" << pred->getID() << "\n";
333 return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
334 }
335 }
336 if (toEdge->isInternal()) {
337 const MSEdge* pred = toEdge->getPredecessors().front();
338 assert(pred != 0);
339 //std::cout << " recurse toPred=" << pred->getID() << "\n";
340 return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
341 }
342 ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
343 if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
344 // start or destination not contained in route
345 return std::numeric_limits<double>::max();
346 }
347 ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
348
349 if (fromEdge == toEdge) {
350 if (fromPos <= toPos) {
351 return toPos - fromPos;
352 } else if (it2 == myEdges.end()) {
353 // we don't visit the edge again
354 return std::numeric_limits<double>::max();
355 }
356 }
357 return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
358}
359
360
361double
362MSRoute::getDistanceBetween(double fromPos, double toPos,
363 const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
364 bool isFirstIteration = true;
365 double distance = -fromPos;
366 MSRouteIterator it = fromEdge;
367 if (fromEdge == toEdge) {
368 // destination position is on start edge
369 if (fromPos <= toPos) {
370 return toPos - fromPos;
371 } else {
372 // we cannot go backwards. Something is wrong here
373 return std::numeric_limits<double>::max();
374 }
375 } else if (fromEdge > toEdge) {
376 // we don't visit the edge again
377 return std::numeric_limits<double>::max();
378 }
379 for (; it != end(); ++it) {
380 if (it == toEdge && !isFirstIteration) {
381 distance += toPos;
382 break;
383 } else {
384 distance += (*it)->getLength();
385 if (includeInternal && (it + 1) != end()) {
386 // XXX the length may be wrong if there are parallel internal edges for different vClasses
387 distance += (*it)->getInternalFollowingLengthTo(*(it + 1), SVC_IGNORING);
388 }
389 }
390 isFirstIteration = false;
391 }
392 return distance;
393}
394
395
396const RGBColor&
398 if (myColor == nullptr) {
400 }
401 return *myColor;
402}
403
404
405const std::vector<SUMOVehicleParameter::Stop>&
407 return myStops;
408}
409
410
411/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:56
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition: Route.h:32
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_ATTR_PROBS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_ROUTES
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A road/street connecting two junctions.
Definition: MSEdge.h:77
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
double getLength() const
return the length of the edge
Definition: MSEdge.h:658
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:265
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:406
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition: MSEdge.cpp:798
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1156
static void dict_clearState()
Decrement all route references before quick-loading state.
Definition: MSRoute.cpp:297
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:85
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:317
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition: MSRoute.cpp:257
const RGBColor *const myColor
The color.
Definition: MSRoute.h:283
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:311
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:298
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:406
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:79
int writeEdgeIDs(OutputDevice &os, int firstIndex=0, int lastIndex=-1, bool withInternal=false, SUMOVehicleClass svc=SVC_IGNORING) const
Output the edge ids up to but not including the id of the given edge.
Definition: MSRoute.cpp:215
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition: MSRoute.cpp:152
std::map< std::string, ConstMSRoutePtr > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:308
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:67
void checkRemoval() const
removes the route from the internal dict if it is not marked as permanent
Definition: MSRoute.cpp:98
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:251
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:103
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:91
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:277
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:200
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes....
Definition: MSRoute.cpp:307
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:239
std::map< std::string, std::pair< RandomDistributor< ConstMSRoutePtr > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:314
static bool dictionary(const std::string &id, ConstMSRoutePtr route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:109
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:397
static RandomDistributor< ConstMSRoutePtr > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:161
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:73
const bool myAmPermanent
whether the route may be deleted after the last vehicle abandoned it
Definition: MSRoute.h:280
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:187
MSRoute(const std::string &id, const ConstMSEdgeVector &edges, const bool isPermanent, const RGBColor *const c, const std::vector< SUMOVehicleParameter::Stop > &stops, SUMOTime replacedTime=-1, int replacedIndex=0)
Constructor.
Definition: MSRoute.cpp:49
static void clear()
Clears the dictionary (delete all known routes, too)
Definition: MSRoute.cpp:174
Base class for objects which have an id.
Definition: Named.h:54
const std::string & getID() const
Returns the id.
Definition: Named.h:74
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:199