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-2019 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  //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
280  if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
281  throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
282  }
283  if (fromEdge->isInternal() && toEdge->isInternal() && fromEdge->getToJunction() == toEdge->getToJunction()) {
284  // internal edges within the same junction
285  if (fromEdge == toEdge) {
286  if (fromPos <= toPos) {
287  return toPos - fromPos;
288  }
289  } else if (fromEdge->getSuccessors().front() == toEdge) {
290  return fromEdge->getLength() - fromPos + toPos;
291  }
292  }
293  if (fromEdge->isInternal()) {
294  if (fromEdge == myEdges.front()) {
295  const MSEdge* succ = fromEdge->getSuccessors().front();
296  assert(succ != 0);
297  //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
298  return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
299  } else {
300  const MSEdge* pred = fromEdge->getPredecessors().front();
301  assert(pred != 0);
302  //std::cout << " recurse fromPred=" << pred->getID() << "\n";
303  return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
304  }
305  }
306  if (toEdge->isInternal()) {
307  const MSEdge* pred = toEdge->getPredecessors().front();
308  assert(pred != 0);
309  //std::cout << " recurse toPred=" << pred->getID() << "\n";
310  return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
311  }
312  ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
313  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
314  // start or destination not contained in route
315  return std::numeric_limits<double>::max();
316  }
317  ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
318 
319  if (fromEdge == toEdge) {
320  if (fromPos <= toPos) {
321  return toPos - fromPos;
322  } else if (it2 == myEdges.end()) {
323  // we don't visit the edge again
324  return std::numeric_limits<double>::max();
325  }
326  }
327  return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
328 }
329 
330 
331 double
332 MSRoute::getDistanceBetween(double fromPos, double toPos,
333  const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
334  bool isFirstIteration = true;
335  double distance = -fromPos;
336  MSRouteIterator it = fromEdge;
337  if (fromEdge == toEdge) {
338  // destination position is on start edge
339  if (fromPos <= toPos) {
340  return toPos - fromPos;
341  } else {
342  // we cannot go backwards. Something is wrong here
343  return std::numeric_limits<double>::max();
344  }
345  } else if (fromEdge > toEdge) {
346  // we don't visit the edge again
347  return std::numeric_limits<double>::max();
348  }
349  for (; it != end(); ++it) {
350  if (it == toEdge && !isFirstIteration) {
351  distance += toPos;
352  break;
353  } else {
354  distance += (*it)->getLength();
355  if (includeInternal && (it + 1) != end()) {
356  distance += (*it)->getInternalFollowingLengthTo(*(it + 1));
357  }
358  }
359  isFirstIteration = false;
360  }
361  return distance;
362 }
363 
364 
365 const RGBColor&
367  if (myColor == nullptr) {
369  }
370  return *myColor;
371 }
372 
373 
374 const std::vector<SUMOVehicleParameter::Stop>&
376  return myStops;
377 }
378 
379 
380 /****************************************************************************/
381 
MSRoute::checkDist
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:186
MSRoute::myDict
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:268
RGBColor::DEFAULT_COLOR
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:204
MSRoute::myColor
const RGBColor *const myColor
The color.
Definition: MSRoute.h:252
MSRoute::release
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:101
MSEdge::getSuccessors
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:998
Named
Base class for objects which have an id.
Definition: Named.h:57
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
MSRoute::end
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:76
MSRouteIterator
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:58
SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
Definition: SUMOXMLDefinitions.h:215
MSRoute::RouteDict
std::map< std::string, const MSRoute * > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:265
FileHelpers.h
MSRoute::getLastEdge
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:88
ConstMSEdgeVector
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:73
SUMO_ATTR_ID
Definition: SUMOXMLDefinitions.h:379
MSEdge.h
MSRoute::getColor
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:366
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
MSRoute
Definition: MSRoute.h:67
MSRoute::insertIDs
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:203
RGBColor.h
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:254
MSRoute::MSRoute
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
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:233
BinaryInputDevice.h
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
MSRoute::size
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:82
RGBColor
Definition: RGBColor.h:40
MSRoute::distDictionary
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:157
MSRoute::myStops
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:261
MSRoute::~MSRoute
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:64
SUMO_ATTR_EDGES
the edges of a route
Definition: SUMOXMLDefinitions.h:428
MSRoute::clear
static void clear()
Clears the dictionary (delete all known routes, too)
Definition: MSRoute.cpp:170
OutputDevice.h
MSRoute::dict_saveState
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition: MSRoute.cpp:257
ProcessError
Definition: UtilExceptions.h:40
MSRoute::operator[]
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:251
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:76
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:361
SUMO_ATTR_PROBS
Definition: SUMOXMLDefinitions.h:628
RandomDistributor< const MSRoute * >
MSRoute::myDistDict
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:274
MSRoute::myReferenceCounter
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:249
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:240
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
SUMO_ATTR_STATE
The state of a link.
Definition: SUMOXMLDefinitions.h:705
MSRoute::writeEdgeIDs
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
MSRoute::RouteDistDict
std::map< std::string, std::pair< RandomDistributor< const MSRoute * > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:271
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:72
MSRoute.h
SUMO_ATTR_ROUTES
Definition: SUMOXMLDefinitions.h:629
MSRoute::getStops
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:375
MSRoute::begin
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
SUMO_TAG_ROUTE
begin/end of the description of a route
Definition: SUMOXMLDefinitions.h:126
MSRoute::dictionary
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:114
config.h
MSRoute::addReference
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:95
MSLane.h
MSRoute::containsAnyOf
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:239
MSRoute::myEdges
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:243
MSRoute::contains
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:103
Named::myID
std::string myID
The name of the object.
Definition: Named.h:134
MSRoute::getDistanceBetween
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
MSEdge::getPredecessors
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:352