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>
29 #include <utils/common/RGBColor.h>
31 #include "MSEdge.h"
32 #include "MSLane.h"
33 #include "MSRoute.h"
34 
35 
36 // ===========================================================================
37 // static member variables
38 // ===========================================================================
41 #ifdef HAVE_FOX
42 FXMutex MSRoute::myDictMutex(true);
43 #endif
44 
45 
46 // ===========================================================================
47 // member method definitions
48 // ===========================================================================
49 MSRoute::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  Named(id), myEdges(edges), myAmPermanent(isPermanent),
54  myReferenceCounter(isPermanent ? 1 : 0),
55  myColor(c),
56  myPeriod(0),
57  myCosts(-1),
58  mySavings(0),
59  myReroute(false),
60  myStops(stops) {}
61 
62 
64  delete myColor;
65 }
66 
67 
69 MSRoute::begin() const {
70  return myEdges.begin();
71 }
72 
73 
75 MSRoute::end() const {
76  return myEdges.end();
77 }
78 
79 
80 int
81 MSRoute::size() const {
82  return (int)myEdges.size();
83 }
84 
85 
86 const MSEdge*
88  assert(myEdges.size() > 0);
89  return myEdges.back();
90 }
91 
92 
93 void
96 }
97 
98 
99 void
102  if (myReferenceCounter == 0) {
103 #ifdef HAVE_FOX
104  FXMutexLock f(myDictMutex);
105 #endif
106  myDict.erase(myID);
107  delete this;
108  }
109 }
110 
111 
112 bool
113 MSRoute::dictionary(const std::string& id, const MSRoute* route) {
114 #ifdef HAVE_FOX
115  FXMutexLock f(myDictMutex);
116 #endif
117  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
118  myDict[id] = route;
119  return true;
120  }
121  return false;
122 }
123 
124 
125 bool
126 MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* const routeDist, const bool permanent) {
127 #ifdef HAVE_FOX
128  FXMutexLock f(myDictMutex);
129 #endif
130  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
131  myDistDict[id] = std::make_pair(routeDist, permanent);
132  return true;
133  }
134  return false;
135 }
136 
137 
138 const MSRoute*
139 MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
140 #ifdef HAVE_FOX
141  FXMutexLock f(myDictMutex);
142 #endif
143  RouteDict::iterator it = myDict.find(id);
144  if (it == myDict.end()) {
145  RouteDistDict::iterator it2 = myDistDict.find(id);
146  if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
147  return nullptr;
148  }
149  return it2->second.first->get(rng);
150  }
151  return it->second;
152 }
153 
154 
155 bool
156 MSRoute::hasRoute(const std::string& id) {
157 #ifdef HAVE_FOX
158  FXMutexLock f(myDictMutex);
159 #endif
160  return myDict.find(id) != myDict.end();
161 }
162 
163 
165 MSRoute::distDictionary(const std::string& id) {
166 #ifdef HAVE_FOX
167  FXMutexLock f(myDictMutex);
168 #endif
169  RouteDistDict::iterator it2 = myDistDict.find(id);
170  if (it2 == myDistDict.end()) {
171  return nullptr;
172  }
173  return it2->second.first;
174 }
175 
176 
177 void
179 #ifdef HAVE_FOX
180  FXMutexLock f(myDictMutex);
181 #endif
182  for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
183  delete i->second.first;
184  }
185  myDistDict.clear();
186  for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
187  delete i->second;
188  }
189  myDict.clear();
190 }
191 
192 
193 void
194 MSRoute::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  const std::vector<const MSRoute*>& routes = it->second.first->getVals();
201  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
202  (*i)->release();
203  }
204  delete it->second.first;
205  myDistDict.erase(it);
206  }
207 }
208 
209 
210 void
211 MSRoute::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 
225 int
226 MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex) 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  for (int i = firstIndex; i < lastIndex; i++) {
232  os << myEdges[i]->getID() << ' ';
233  }
234  return lastIndex - firstIndex;
235 }
236 
237 
238 bool
239 MSRoute::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 
250 const MSEdge*
251 MSRoute::operator[](int index) const {
252  return myEdges[index];
253 }
254 
255 
256 void
258 #ifdef HAVE_FOX
259  FXMutexLock f(myDictMutex);
260 #endif
261  for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
262  out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_ID, (*it).second->getID());
263  out.writeAttr(SUMO_ATTR_STATE, (*it).second->myAmPermanent);
264  out.writeAttr(SUMO_ATTR_EDGES, (*it).second->myEdges).closeTag();
265  }
266  for (const auto& item : myDistDict) {
267  if (item.second.first->getVals().size() > 0) {
269  out.writeAttr(SUMO_ATTR_STATE, item.second.second);
270  out.writeAttr(SUMO_ATTR_ROUTES, item.second.first->getVals());
271  out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
272  out.closeTag();
273  }
274  }
275 }
276 
277 void
279 #ifdef HAVE_FOX
280  FXMutexLock f(myDictMutex);
281 #endif
282  for (auto item : myDict) {
283  delete item.second;
284  }
285  myDistDict.clear();
286  myDict.clear();
287 }
288 
289 
290 double
291 MSRoute::getDistanceBetween(double fromPos, double toPos,
292  const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal, int routePosition) const {
293  //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
294  if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
295  throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
296  }
297  if (fromEdge->isInternal() && toEdge->isInternal() && fromEdge->getToJunction() == toEdge->getToJunction()) {
298  // internal edges within the same junction
299  if (fromEdge == toEdge) {
300  if (fromPos <= toPos) {
301  return toPos - fromPos;
302  }
303  } else if (fromEdge->getSuccessors().front() == toEdge) {
304  return fromEdge->getLength() - fromPos + toPos;
305  }
306  }
307  if (fromEdge->isInternal()) {
308  if (fromEdge == myEdges.front()) {
309  const MSEdge* succ = fromEdge->getSuccessors().front();
310  assert(succ != 0);
311  //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
312  return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
313  } else {
314  const MSEdge* pred = fromEdge->getPredecessors().front();
315  assert(pred != 0);
316  //std::cout << " recurse fromPred=" << pred->getID() << "\n";
317  return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
318  }
319  }
320  if (toEdge->isInternal()) {
321  const MSEdge* pred = toEdge->getPredecessors().front();
322  assert(pred != 0);
323  //std::cout << " recurse toPred=" << pred->getID() << "\n";
324  return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
325  }
326  ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
327  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
328  // start or destination not contained in route
329  return std::numeric_limits<double>::max();
330  }
331  ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
332 
333  if (fromEdge == toEdge) {
334  if (fromPos <= toPos) {
335  return toPos - fromPos;
336  } else if (it2 == myEdges.end()) {
337  // we don't visit the edge again
338  return std::numeric_limits<double>::max();
339  }
340  }
341  return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
342 }
343 
344 
345 double
346 MSRoute::getDistanceBetween(double fromPos, double toPos,
347  const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
348  bool isFirstIteration = true;
349  double distance = -fromPos;
350  MSRouteIterator it = fromEdge;
351  if (fromEdge == toEdge) {
352  // destination position is on start edge
353  if (fromPos <= toPos) {
354  return toPos - fromPos;
355  } else {
356  // we cannot go backwards. Something is wrong here
357  return std::numeric_limits<double>::max();
358  }
359  } else if (fromEdge > toEdge) {
360  // we don't visit the edge again
361  return std::numeric_limits<double>::max();
362  }
363  for (; it != end(); ++it) {
364  if (it == toEdge && !isFirstIteration) {
365  distance += toPos;
366  break;
367  } else {
368  distance += (*it)->getLength();
369  if (includeInternal && (it + 1) != end()) {
370  distance += (*it)->getInternalFollowingLengthTo(*(it + 1));
371  }
372  }
373  isFirstIteration = false;
374  }
375  return distance;
376 }
377 
378 
379 const RGBColor&
381  if (myColor == nullptr) {
383  }
384  return *myColor;
385 }
386 
387 
388 const std::vector<SUMOVehicleParameter::Stop>&
390  return myStops;
391 }
392 
393 
394 /****************************************************************************/
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
@ 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_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 MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:392
double getLength() const
return the length of the edge
Definition: MSEdge.h:641
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:262
const MSJunction * getToJunction() const
Definition: MSEdge.h:401
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1084
static void dict_clearState()
Decrement all route references before quick-loading state.
Definition: MSRoute.cpp:278
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:94
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:300
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:272
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:294
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:287
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:389
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:269
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:113
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition: MSRoute.cpp:156
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:63
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:251
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:99
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:100
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:87
MSRoute(const std::string &id, const ConstMSEdgeVector &edges, const bool isPermanent, const RGBColor *const c, const std::vector< SUMOVehicleParameter::Stop > &stops)
Constructor.
Definition: MSRoute.cpp:49
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:263
std::map< std::string, const MSRoute * > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:291
std::map< std::string, std::pair< RandomDistributor< const MSRoute * > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:297
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:165
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:211
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:291
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:239
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:380
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
int writeEdgeIDs(OutputDevice &os, int firstIndex=0, int lastIndex=-1) const
Output the edge ids up to but not including the id of the given edge.
Definition: MSRoute.cpp:226
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:178
Base class for objects which have an id.
Definition: Named.h:54
std::string myID
The name of the object.
Definition: Named.h:125
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
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