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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // A vehicle route
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <cassert>
28 #include <algorithm>
29 #include <limits>
31 #include <utils/common/RGBColor.h>
34 #include "MSEdge.h"
35 #include "MSLane.h"
36 #include "MSRoute.h"
37 
38 
39 // ===========================================================================
40 // static member variables
41 // ===========================================================================
44 #ifdef HAVE_FOX
45 FXMutex MSRoute::myDictMutex(true);
46 #endif
47 
48 
49 // ===========================================================================
50 // member method definitions
51 // ===========================================================================
52 MSRoute::MSRoute(const std::string& id,
53  const ConstMSEdgeVector& edges,
54  const bool isPermanent, const RGBColor* const c,
55  const std::vector<SUMOVehicleParameter::Stop>& stops) :
56  Named(id), myEdges(edges), myAmPermanent(isPermanent),
57  myReferenceCounter(isPermanent ? 1 : 0),
58  myColor(c),
59  myCosts(-1),
60  mySavings(0),
61  myStops(stops) {}
62 
63 
65  delete myColor;
66 }
67 
68 
70 MSRoute::begin() const {
71  return myEdges.begin();
72 }
73 
74 
76 MSRoute::end() const {
77  return myEdges.end();
78 }
79 
80 
81 int
82 MSRoute::size() const {
83  return (int)myEdges.size();
84 }
85 
86 
87 const MSEdge*
89  assert(myEdges.size() > 0);
90  return myEdges[myEdges.size() - 1];
91 }
92 
93 
94 void
97 }
98 
99 
100 void
103  if (myReferenceCounter == 0) {
104 #ifdef HAVE_FOX
105  FXMutexLock f(myDictMutex);
106 #endif
107  myDict.erase(myID);
108  delete this;
109  }
110 }
111 
112 
113 bool
114 MSRoute::dictionary(const std::string& id, const MSRoute* route) {
115 #ifdef HAVE_FOX
116  FXMutexLock f(myDictMutex);
117 #endif
118  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
119  myDict[id] = route;
120  return true;
121  }
122  return false;
123 }
124 
125 
126 bool
127 MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* const routeDist, const bool permanent) {
128 #ifdef HAVE_FOX
129  FXMutexLock f(myDictMutex);
130 #endif
131  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
132  myDistDict[id] = std::make_pair(routeDist, permanent);
133  return true;
134  }
135  return false;
136 }
137 
138 
139 const MSRoute*
140 MSRoute::dictionary(const std::string& id, std::mt19937* rng) {
141 #ifdef HAVE_FOX
142  FXMutexLock f(myDictMutex);
143 #endif
144  RouteDict::iterator it = myDict.find(id);
145  if (it == myDict.end()) {
146  RouteDistDict::iterator it2 = myDistDict.find(id);
147  if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
148  return nullptr;
149  }
150  return it2->second.first->get(rng);
151  }
152  return it->second;
153 }
154 
155 
157 MSRoute::distDictionary(const std::string& id) {
158 #ifdef HAVE_FOX
159  FXMutexLock f(myDictMutex);
160 #endif
161  RouteDistDict::iterator it2 = myDistDict.find(id);
162  if (it2 == myDistDict.end()) {
163  return nullptr;
164  }
165  return it2->second.first;
166 }
167 
168 
169 void
171 #ifdef HAVE_FOX
172  FXMutexLock f(myDictMutex);
173 #endif
174  for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
175  delete i->second.first;
176  }
177  myDistDict.clear();
178  for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
179  delete i->second;
180  }
181  myDict.clear();
182 }
183 
184 
185 void
186 MSRoute::checkDist(const std::string& id) {
187 #ifdef HAVE_FOX
188  FXMutexLock f(myDictMutex);
189 #endif
190  RouteDistDict::iterator it = myDistDict.find(id);
191  if (it != myDistDict.end() && !it->second.second) {
192  const std::vector<const MSRoute*>& routes = it->second.first->getVals();
193  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
194  (*i)->release();
195  }
196  delete it->second.first;
197  myDistDict.erase(it);
198  }
199 }
200 
201 
202 void
203 MSRoute::insertIDs(std::vector<std::string>& into) {
204 #ifdef HAVE_FOX
205  FXMutexLock f(myDictMutex);
206 #endif
207  into.reserve(myDict.size() + myDistDict.size() + into.size());
208  for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
209  into.push_back((*i).first);
210  }
211  for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
212  into.push_back((*i).first);
213  }
214 }
215 
216 
217 int
218 MSRoute::writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo) const {
219  int numWritten = 0;
220  ConstMSEdgeVector::const_iterator i = myEdges.begin();
221  if (from != nullptr) {
222  i = std::find(myEdges.begin(), myEdges.end(), from);
223  }
224  for (; i != myEdges.end(); ++i) {
225  if ((*i) == upTo) {
226  return numWritten;
227  }
228  os << (*i)->getID();
229  numWritten++;
230  if (upTo || i != myEdges.end() - 1) {
231  os << ' ';
232  }
233  }
234  return numWritten;
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 (RouteDistDict::iterator it = myDistDict.begin(); it != myDistDict.end(); ++it) {
268  out.writeAttr(SUMO_ATTR_STATE, (*it).second.second);
269  out.writeAttr(SUMO_ATTR_ROUTES, (*it).second.first->getVals());
270  out.writeAttr(SUMO_ATTR_PROBS, (*it).second.first->getProbs());
271  out.closeTag();
272  }
273 }
274 
275 
276 double
277 MSRoute::getDistanceBetween(double fromPos, double toPos,
278  const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal, int routePosition) const {
279  if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
280  throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
281  }
283  //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
284  if (fromEdge->isInternal()) {
285  if (fromEdge == myEdges.front()) {
286  const MSEdge* succ = fromEdge->getSuccessors().front();
287  assert(succ != 0);
288  //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
289  return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
290  } else {
291  const MSEdge* pred = fromEdge->getPredecessors().front();
292  assert(pred != 0);
293  //std::cout << " recurse fromPred=" << pred->getID() << "\n";
294  return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
295  }
296  }
297  if (toEdge->isInternal()) {
298  const MSEdge* pred = toEdge->getPredecessors().front();
299  assert(pred != 0);
300  //std::cout << " recurse toPred=" << pred->getID() << "\n";
301  return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
302  }
303  ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
304  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
305  // start or destination not contained in route
306  return std::numeric_limits<double>::max();
307  }
308  ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
309 
310  if (fromEdge == toEdge) {
311  if (fromPos <= toPos) {
312  return toPos - fromPos;
313  } else if (it2 == myEdges.end()) {
314  // we don't visit the edge again
315  return std::numeric_limits<double>::max();
316  }
317  }
318  return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
319 }
320 
321 
322 double
323 MSRoute::getDistanceBetween(double fromPos, double toPos,
324  const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
325  bool isFirstIteration = true;
326  double distance = -fromPos;
327  MSRouteIterator it = fromEdge;
328  if (fromEdge == toEdge) {
329  // destination position is on start edge
330  if (fromPos <= toPos) {
331  return toPos - fromPos;
332  } else {
333  // we cannot go backwards. Something is wrong here
334  return std::numeric_limits<double>::max();
335  }
336  } else if (fromEdge > toEdge) {
337  // we don't visit the edge again
338  return std::numeric_limits<double>::max();
339  }
340  for (; it != end(); ++it) {
341  if (it == toEdge && !isFirstIteration) {
342  distance += toPos;
343  break;
344  } else {
345  distance += (*it)->getLength();
346  if (includeInternal && (it + 1) != end()) {
347  distance += (*it)->getInternalFollowingLengthTo(*(it + 1));
348  }
349  }
350  isFirstIteration = false;
351  }
352  return distance;
353 }
354 
355 
356 const RGBColor&
358  if (myColor == nullptr) {
360  }
361  return *myColor;
362 }
363 
364 
365 const std::vector<SUMOVehicleParameter::Stop>&
367  return myStops;
368 }
369 
370 
371 /****************************************************************************/
372 
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
std::map< std::string, const MSRoute * > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:265
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:101
Represents a generic random distribution.
distribution of a route
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:338
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:357
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:88
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:72
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:157
double getLength() const
return the length of the edge
Definition: MSEdge.h:568
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:82
begin/end of the description of a route
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition: MSRoute.cpp:257
The state of a link.
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:203
A road/street connecting two junctions.
Definition: MSEdge.h:75
static void clear()
Clears the dictionary (delete all known routes, too)
Definition: MSRoute.cpp:170
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:274
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:198
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:52
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:58
std::map< std::string, std::pair< RandomDistributor< const MSRoute * > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:271
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:64
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:225
int writeEdgeIDs(OutputDevice &os, const MSEdge *const from, const MSEdge *const upTo=0) const
Output the edge ids up to but not including the id of the given edge.
Definition: MSRoute.cpp:218
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:261
Base class for objects which have an id.
Definition: Named.h:58
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:251
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:981
std::string myID
The name of the object.
Definition: Named.h:130
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:239
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:243
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:95
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:249
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:71
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:186
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:366
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:76
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:268
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:103
const RGBColor *const myColor
The color.
Definition: MSRoute.h:252
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:114
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:277