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-2022 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 myReferenceCounter(isPermanent ? 1 : 0),
57 myColor(c),
58 myPeriod(0),
59 myCosts(-1),
60 mySavings(0),
61 myReroute(false),
62 myStops(stops),
63 myReplacedTime(replacedTime),
64 myReplacedIndex(replacedIndex)
65{}
66
67
69 delete myColor;
70}
71
72
75 return myEdges.begin();
76}
77
78
80MSRoute::end() const {
81 return myEdges.end();
82}
83
84
85int
87 return (int)myEdges.size();
88}
89
90
91const MSEdge*
93 assert(myEdges.size() > 0);
94 return myEdges.back();
95}
96
97
98void
101}
102
103
104void
107 if (myReferenceCounter == 0) {
108#ifdef HAVE_FOX
109 FXMutexLock f(myDictMutex);
110#endif
111 myDict.erase(myID);
112 delete this;
113 }
114}
115
116
117bool
118MSRoute::dictionary(const std::string& id, const MSRoute* route) {
119#ifdef HAVE_FOX
120 FXMutexLock f(myDictMutex);
121#endif
122 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
123 myDict[id] = route;
124 return true;
125 }
126 return false;
127}
128
129
130bool
131MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* const routeDist, const bool permanent) {
132#ifdef HAVE_FOX
133 FXMutexLock f(myDictMutex);
134#endif
135 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
136 myDistDict[id] = std::make_pair(routeDist, permanent);
137 return true;
138 }
139 return false;
140}
141
142
143const MSRoute*
144MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
145#ifdef HAVE_FOX
146 FXMutexLock f(myDictMutex);
147#endif
148 RouteDict::iterator it = myDict.find(id);
149 if (it == myDict.end()) {
150 RouteDistDict::iterator it2 = myDistDict.find(id);
151 if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
152 return nullptr;
153 }
154 return it2->second.first->get(rng);
155 }
156 return it->second;
157}
158
159
160bool
161MSRoute::hasRoute(const std::string& id) {
162#ifdef HAVE_FOX
163 FXMutexLock f(myDictMutex);
164#endif
165 return myDict.find(id) != myDict.end();
166}
167
168
170MSRoute::distDictionary(const std::string& id) {
171#ifdef HAVE_FOX
172 FXMutexLock f(myDictMutex);
173#endif
174 RouteDistDict::iterator it2 = myDistDict.find(id);
175 if (it2 == myDistDict.end()) {
176 return nullptr;
177 }
178 return it2->second.first;
179}
180
181
182void
184#ifdef HAVE_FOX
185 FXMutexLock f(myDictMutex);
186#endif
187 for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
188 delete i->second.first;
189 }
190 myDistDict.clear();
191 for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
192 delete i->second;
193 }
194 myDict.clear();
195}
196
197
198void
199MSRoute::checkDist(const std::string& id) {
200#ifdef HAVE_FOX
201 FXMutexLock f(myDictMutex);
202#endif
203 RouteDistDict::iterator it = myDistDict.find(id);
204 if (it != myDistDict.end() && !it->second.second) {
205 const std::vector<const MSRoute*>& routes = it->second.first->getVals();
206 for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
207 (*i)->release();
208 }
209 delete it->second.first;
210 myDistDict.erase(it);
211 }
212}
213
214
215void
216MSRoute::insertIDs(std::vector<std::string>& into) {
217#ifdef HAVE_FOX
218 FXMutexLock f(myDictMutex);
219#endif
220 into.reserve(myDict.size() + myDistDict.size() + into.size());
221 for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
222 into.push_back((*i).first);
223 }
224 for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
225 into.push_back((*i).first);
226 }
227}
228
229
230int
231MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex, bool withInternal, SUMOVehicleClass svc) const {
232 //std::cout << SIMTIME << " writeEdgeIDs " << getID() << " first=" << firstIndex << " lastIndex=" << lastIndex << " edges=" << toString(myEdges) << "\n";
233 if (lastIndex < 0) {
234 lastIndex = (int)myEdges.size();
235 }
236 int internal = 0;
237 for (int i = firstIndex; i < lastIndex; i++) {
238 os << myEdges[i]->getID() << ' ';
239 if (withInternal && i + 1 < lastIndex) {
240 const MSEdge* next = myEdges[i + 1];
241 const MSEdge* edge = myEdges[i]->getInternalFollowingEdge(next, svc);
242 // Take into account non-internal lengths until next non-internal edge
243 while (edge != nullptr && edge->isInternal()) {
244 os << edge->getID() << ' ';
245 internal++;
246 edge = edge->getInternalFollowingEdge(next, svc);
247 }
248 }
249 }
250 return internal + lastIndex - firstIndex;
251}
252
253
254bool
255MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
256 MSEdgeVector::const_iterator i = edgelist.begin();
257 for (; i != edgelist.end(); ++i) {
258 if (contains(*i)) {
259 return true;
260 }
261 }
262 return false;
263}
264
265
266const MSEdge*
267MSRoute::operator[](int index) const {
268 return myEdges[index];
269}
270
271
272void
274#ifdef HAVE_FOX
275 FXMutexLock f(myDictMutex);
276#endif
277 for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
278 const MSRoute* r = (*it).second;
280 out.writeAttr(SUMO_ATTR_ID, r->getID());
283 if (r->myColor != nullptr) {
285 }
286 for (auto stop : r->getStops()) {
287 stop.write(out);
288 }
289 out.closeTag();
290 }
291 for (const auto& item : myDistDict) {
292 if (item.second.first->getVals().size() > 0) {
294 out.writeAttr(SUMO_ATTR_STATE, item.second.second);
295 out.writeAttr(SUMO_ATTR_ROUTES, item.second.first->getVals());
296 out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
297 out.closeTag();
298 }
299 }
300}
301
302void
304#ifdef HAVE_FOX
305 FXMutexLock f(myDictMutex);
306#endif
307 for (auto item : myDict) {
308 delete item.second;
309 }
310 myDistDict.clear();
311 myDict.clear();
312}
313
314
315double
316MSRoute::getDistanceBetween(double fromPos, double toPos,
317 const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal, int routePosition) const {
318 //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
319 if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
320 throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
321 }
322 if (fromEdge->isInternal() && toEdge->isInternal() && fromEdge->getToJunction() == toEdge->getToJunction()) {
323 // internal edges within the same junction
324 if (fromEdge == toEdge) {
325 if (fromPos <= toPos) {
326 return toPos - fromPos;
327 }
328 } else if (fromEdge->getSuccessors().front() == toEdge) {
329 return fromEdge->getLength() - fromPos + toPos;
330 }
331 }
332 if (fromEdge->isInternal()) {
333 if (fromEdge == myEdges.front()) {
334 const MSEdge* succ = fromEdge->getSuccessors().front();
335 assert(succ != 0);
336 //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
337 return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
338 } else {
339 const MSEdge* pred = fromEdge->getPredecessors().front();
340 assert(pred != 0);
341 //std::cout << " recurse fromPred=" << pred->getID() << "\n";
342 return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
343 }
344 }
345 if (toEdge->isInternal()) {
346 const MSEdge* pred = toEdge->getPredecessors().front();
347 assert(pred != 0);
348 //std::cout << " recurse toPred=" << pred->getID() << "\n";
349 return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
350 }
351 ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
352 if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
353 // start or destination not contained in route
354 return std::numeric_limits<double>::max();
355 }
356 ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
357
358 if (fromEdge == toEdge) {
359 if (fromPos <= toPos) {
360 return toPos - fromPos;
361 } else if (it2 == myEdges.end()) {
362 // we don't visit the edge again
363 return std::numeric_limits<double>::max();
364 }
365 }
366 return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
367}
368
369
370double
371MSRoute::getDistanceBetween(double fromPos, double toPos,
372 const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
373 bool isFirstIteration = true;
374 double distance = -fromPos;
375 MSRouteIterator it = fromEdge;
376 if (fromEdge == toEdge) {
377 // destination position is on start edge
378 if (fromPos <= toPos) {
379 return toPos - fromPos;
380 } else {
381 // we cannot go backwards. Something is wrong here
382 return std::numeric_limits<double>::max();
383 }
384 } else if (fromEdge > toEdge) {
385 // we don't visit the edge again
386 return std::numeric_limits<double>::max();
387 }
388 for (; it != end(); ++it) {
389 if (it == toEdge && !isFirstIteration) {
390 distance += toPos;
391 break;
392 } else {
393 distance += (*it)->getLength();
394 if (includeInternal && (it + 1) != end()) {
395 // XXX the length may be wrong if there are parallel internal edges for different vClasses
396 distance += (*it)->getInternalFollowingLengthTo(*(it + 1), SVC_IGNORING);
397 }
398 }
399 isFirstIteration = false;
400 }
401 return distance;
402}
403
404
405const RGBColor&
407 if (myColor == nullptr) {
409 }
410 return *myColor;
411}
412
413
414const std::vector<SUMOVehicleParameter::Stop>&
416 return myStops;
417}
418
419
420/****************************************************************************/
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:54
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:1155
static void dict_clearState()
Decrement all route references before quick-loading state.
Definition: MSRoute.cpp:303
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:99
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:86
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:320
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition: MSRoute.cpp:273
const RGBColor *const myColor
The color.
Definition: MSRoute.h:286
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:314
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:301
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:415
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:80
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:231
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:283
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:118
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition: MSRoute.cpp:161
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:68
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:267
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:103
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:105
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:92
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:277
std::map< std::string, const MSRoute * > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:311
std::map< std::string, std::pair< RandomDistributor< const MSRoute * > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:317
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:170
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:216
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:316
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:255
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:406
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
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:199
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:183
Base class for objects which have an id.
Definition: Named.h:54
std::string myID
The name of the object.
Definition: Named.h:125
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:251
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