Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSRoute.cpp
Go to the documentation of this file.
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/****************************************************************************/
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 StopParVector& 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
97const MSEdge*
99 assert(myEdges.size() > 0);
100 return myEdges.front();
101}
102
103
104void
105MSRoute::checkRemoval(bool force) const {
106#ifdef HAVE_FOX
107 FXMutexLock f(myDictMutex);
108#endif
109 if (!myAmPermanent || force) {
110 myDict.erase(getID());
111 }
112}
113
114
115bool
116MSRoute::dictionary(const std::string& id, ConstMSRoutePtr route) {
117#ifdef HAVE_FOX
118 FXMutexLock f(myDictMutex);
119#endif
120 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
121 myDict[id] = route;
122 return true;
123 }
124 return false;
125}
126
127
128bool
129MSRoute::dictionary(const std::string& id, RandomDistributor<ConstMSRoutePtr>* const routeDist, const bool permanent) {
130#ifdef HAVE_FOX
131 FXMutexLock f(myDictMutex);
132#endif
133 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
134 myDistDict[id] = std::make_pair(routeDist, permanent);
135 return true;
136 }
137 return false;
138}
139
140
142MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
143#ifdef HAVE_FOX
144 FXMutexLock f(myDictMutex);
145#endif
146 RouteDict::iterator it = myDict.find(id);
147 if (it == myDict.end()) {
148 RouteDistDict::iterator it2 = myDistDict.find(id);
149 if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
150 return nullptr;
151 }
152 return it2->second.first->get(rng);
153 }
154 return it->second;
155}
156
157
158bool
159MSRoute::hasRoute(const std::string& id) {
160#ifdef HAVE_FOX
161 FXMutexLock f(myDictMutex);
162#endif
163 return myDict.find(id) != myDict.end();
164}
165
166
168MSRoute::distDictionary(const std::string& id) {
169#ifdef HAVE_FOX
170 FXMutexLock f(myDictMutex);
171#endif
172 RouteDistDict::iterator it2 = myDistDict.find(id);
173 if (it2 == myDistDict.end()) {
174 return nullptr;
175 }
176 return it2->second.first;
177}
178
179
180void
182#ifdef HAVE_FOX
183 FXMutexLock f(myDictMutex);
184#endif
185 for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
186 delete i->second.first;
187 }
188 myDistDict.clear();
189 myDict.clear();
190}
191
192
193void
194MSRoute::checkDist(const std::string& id) {
195#ifdef HAVE_FOX
196 FXMutexLock f(myDictMutex);
197#endif
198 RouteDistDict::iterator it = myDistDict.find(id);
199 if (it != myDistDict.end() && !it->second.second) {
200 for (ConstMSRoutePtr rp : it->second.first->getVals()) {
201 const MSRoute& r = *rp;
202 r.checkRemoval();
203 }
204 delete it->second.first;
205 myDistDict.erase(it);
206 }
207}
208
209
210void
211MSRoute::insertIDs(std::vector<std::string>& into) {
212#ifdef HAVE_FOX
213 FXMutexLock f(myDictMutex);
214#endif
215 into.reserve(myDict.size() + myDistDict.size() + into.size());
216 for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
217 into.push_back((*i).first);
218 }
219 for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
220 into.push_back((*i).first);
221 }
222}
223
224
225int
226MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex, bool withInternal, SUMOVehicleClass svc) const {
227 //std::cout << SIMTIME << " writeEdgeIDs " << getID() << " first=" << firstIndex << " lastIndex=" << lastIndex << " edges=" << toString(myEdges) << "\n";
228 if (lastIndex < 0) {
229 lastIndex = (int)myEdges.size();
230 }
231 int internal = 0;
232 for (int i = firstIndex; i < lastIndex; i++) {
233 os << myEdges[i]->getID() << ' ';
234 if (withInternal && i + 1 < lastIndex) {
235 const MSEdge* next = myEdges[i + 1];
236 const MSEdge* edge = myEdges[i]->getInternalFollowingEdge(next, svc);
237 // Take into account non-internal lengths until next non-internal edge
238 while (edge != nullptr && edge->isInternal()) {
239 os << edge->getID() << ' ';
240 internal++;
241 edge = edge->getInternalFollowingEdge(next, svc);
242 }
243 }
244 }
245 return internal + lastIndex - firstIndex;
246}
247
248
249bool
250MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
251 MSEdgeVector::const_iterator i = edgelist.begin();
252 for (; i != edgelist.end(); ++i) {
253 if (contains(*i)) {
254 return true;
255 }
256 }
257 return false;
258}
259
260
261const MSEdge*
262MSRoute::operator[](int index) const {
263 return myEdges[index];
264}
265
266
267void
269#ifdef HAVE_FOX
270 FXMutexLock f(myDictMutex);
271#endif
272 for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
273 ConstMSRoutePtr r = (*it).second;
275 out.writeAttr(SUMO_ATTR_ID, r->getID());
276 out.writeAttr(SUMO_ATTR_STATE, r->myAmPermanent);
277 out.writeAttr(SUMO_ATTR_EDGES, r->myEdges);
278 if (r->myColor != nullptr) {
279 out.writeAttr(SUMO_ATTR_COLOR, *r->myColor);
280 }
281 for (auto stop : r->getStops()) {
282 stop.write(out);
283 }
284 out.closeTag();
285 }
286 for (const auto& item : myDistDict) {
287 if (item.second.first->getVals().size() > 0) {
289 out.writeAttr(SUMO_ATTR_STATE, item.second.second);
290 std::ostringstream oss;
291 bool space = false;
292 for (const auto& route : item.second.first->getVals()) {
293 if (space) {
294 oss << " ";
295 }
296 oss << route->getID();
297 space = true;
298 }
299 out.writeAttr(SUMO_ATTR_ROUTES, oss.str());
300 out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
301 out.closeTag();
302 }
303 }
304}
305
306
307void
309#ifdef HAVE_FOX
310 FXMutexLock f(myDictMutex);
311#endif
312 myDistDict.clear();
313 myDict.clear();
314}
315
316
317double
318MSRoute::getDistanceBetween(double fromPos, double toPos,
319 const MSLane* fromLane, const MSLane* toLane, int routePosition) const {
320 // std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << "\n";
321 assert(fromPos >= 0. && fromPos <= fromLane->getLength());
322 assert(toPos >= 0. && toPos <= toLane->getLength());
323 assert(routePosition >= 0 && routePosition < (int)myEdges.size());
324 assert(routePosition == 0 || !myEdges.front()->isInternal());
325 const MSEdge* fromEdge = &fromLane->getEdge();
326 const MSEdge* toEdge = &toLane->getEdge();
327 if (fromEdge == toEdge && fromPos <= toPos) {
328 return toPos - fromPos;
329 }
330 // TODO If fromEdge and toEdge are identical or both are internal and directly connected,
331 // the code does not check whether they are in any relation to the route.
332 if (fromEdge->isInternal()) {
333 double minDist = std::numeric_limits<double>::max();
334 for (const auto& via : fromEdge->getViaSuccessors()) {
335 const MSEdge* const succ = via.second == nullptr ? via.first : via.second;
336 assert(succ != nullptr);
337 // std::cout << " recurse fromSucc=" << succ->getID() << "\n";
338 const double d = getDistanceBetween(0., toPos, succ->getLanes()[0], toLane, routePosition);
339 if (d != std::numeric_limits<double>::max() && fromLane->getLength() - fromPos + d < minDist) {
340 minDist = fromLane->getLength() - fromPos + d;
341 }
342 }
343 return minDist;
344 }
345 if (toEdge->isInternal()) {
346 const MSEdge* const pred = toEdge->getPredecessors().front();
347 assert(pred != nullptr);
348 // std::cout << " recurse toPred=" << pred->getID() << "\n";
349 const double d = getDistanceBetween(fromPos, pred->getLength(), fromLane, pred->getLanes()[0], routePosition);
350 return d == std::numeric_limits<double>::max() ? d : toPos + d;
351 }
352 ConstMSEdgeVector::const_iterator fromIt = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
353 if (fromIt == myEdges.end()) {
354 // start not contained in route
355 return std::numeric_limits<double>::max();
356 }
357 ConstMSEdgeVector::const_iterator toIt = std::find(fromIt + 1, myEdges.end(), toEdge);
358 if (toIt == myEdges.end()) {
359 // destination not contained in route
360 return std::numeric_limits<double>::max();
361 }
362 return getDistanceBetween(fromPos, toPos, fromIt, toIt, true);
363}
364
365
366double
367MSRoute::getDistanceBetween(double fromPos, double toPos,
368 const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
369 bool isFirstIteration = true;
370 double distance = -fromPos;
371 MSRouteIterator it = fromEdge;
372 if (fromEdge == toEdge) {
373 // destination position is on start edge
374 if (fromPos <= toPos) {
375 return toPos - fromPos;
376 } else {
377 // we cannot go backwards. Something is wrong here
378 return std::numeric_limits<double>::max();
379 }
380 } else if (fromEdge > toEdge) {
381 // we don't visit the edge again
382 return std::numeric_limits<double>::max();
383 }
384 for (; it != end(); ++it) {
385 if (it == toEdge && !isFirstIteration) {
386 distance += toPos;
387 break;
388 } else {
389 distance += (*it)->getLength();
390 if (includeInternal && (it + 1) != end()) {
391 // XXX the length may be wrong if there are parallel internal edges for different vClasses
392 distance += (*it)->getInternalFollowingLengthTo(*(it + 1), SVC_IGNORING);
393 }
394 }
395 isFirstIteration = false;
396 }
397 return distance;
398}
399
400
401const RGBColor&
403 if (myColor == nullptr) {
405 }
406 return *myColor;
407}
408
409
410const StopParVector&
412 return myStops;
413}
414
415
416/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSRoute.h:55
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:57
std::vector< MSEdge * > MSEdgeVector
Definition MSRoute.h:56
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition MSRoute.h:58
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
std::vector< SUMOVehicleParameter::Stop > StopParVector
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_ROUTE
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.
A road/street connecting two junctions.
Definition MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1298
double getLength() const
return the length of the edge
Definition MSEdge.h:693
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:268
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:417
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition MSEdge.cpp:910
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double getLength() const
Returns the lane's length.
Definition MSLane.h:611
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
static void dict_clearState()
Decrement all route references before quick-loading state.
Definition MSRoute.cpp:308
int size() const
Returns the number of edges to pass.
Definition MSRoute.cpp:85
static RouteDistDict myDistDict
The dictionary container.
Definition MSRoute.h:327
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition MSRoute.cpp:268
const RGBColor *const myColor
The color.
Definition MSRoute.h:293
StopParVector myStops
List of the stops on the parsed route.
Definition MSRoute.h:308
static RouteDict myDict
The dictionary container.
Definition MSRoute.h:321
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:226
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition MSRoute.cpp:159
void checkRemoval(bool force=false) const
removes the route from the internal dict if it is not marked as permanent
Definition MSRoute.cpp:105
std::map< std::string, ConstMSRoutePtr > RouteDict
Definition of the dictionary container.
Definition MSRoute.h:318
virtual ~MSRoute()
Destructor.
Definition MSRoute.cpp:67
const MSEdge * operator[](int index) const
Definition MSRoute.cpp:262
bool contains(const MSEdge *const edge) const
Definition MSRoute.h:107
const MSEdge * getLastEdge() const
returns the destination edge
Definition MSRoute.cpp:91
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition MSRoute.h:287
static void insertIDs(std::vector< std::string > &into)
Definition MSRoute.cpp:211
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition MSRoute.cpp:250
std::map< std::string, std::pair< RandomDistributor< ConstMSRoutePtr > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition MSRoute.h:324
static bool dictionary(const std::string &id, ConstMSRoutePtr route)
Adds a route to the dictionary.
Definition MSRoute.cpp:116
const RGBColor & getColor() const
Returns the color.
Definition MSRoute.cpp:402
MSRoute(const std::string &id, const ConstMSEdgeVector &edges, const bool isPermanent, const RGBColor *const c, const StopParVector &stops, SUMOTime replacedTime=-1, int replacedIndex=0)
Constructor.
Definition MSRoute.cpp:49
static RandomDistributor< ConstMSRoutePtr > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition MSRoute.cpp:168
const MSEdge * getFirstEdge() const
returns the origin edge
Definition MSRoute.cpp:98
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition MSRoute.cpp:73
double getDistanceBetween(double fromPos, double toPos, const MSLane *fromLane, const MSLane *toLane, int routePosition=0) const
Compute the distance between 2 given edges on this route, optionally including the length of internal...
Definition MSRoute.cpp:318
const bool myAmPermanent
whether the route may be deleted after the last vehicle abandoned it
Definition MSRoute.h:290
const StopParVector & getStops() const
Returns the stops.
Definition MSRoute.cpp:411
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition MSRoute.cpp:194
static void clear()
Clears the dictionary (delete all known routes, too)
Definition MSRoute.cpp:181
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.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
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:202
Represents a generic random distribution.