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 /****************************************************************************/
17 // A vehicle route
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <cassert>
27 #include <algorithm>
28 #include <limits>
30 #include <utils/common/RGBColor.h>
33 #include "MSEdge.h"
34 #include "MSLane.h"
35 #include "MSRoute.h"
36 
37 
38 // ===========================================================================
39 // static member variables
40 // ===========================================================================
43 #ifdef HAVE_FOX
44 FXMutex MSRoute::myDictMutex(true);
45 #endif
46 
47 
48 // ===========================================================================
49 // member method definitions
50 // ===========================================================================
51 MSRoute::MSRoute(const std::string& id,
52  const ConstMSEdgeVector& edges,
53  const bool isPermanent, const RGBColor* const c,
54  const std::vector<SUMOVehicleParameter::Stop>& stops) :
55  Named(id), myEdges(edges), myAmPermanent(isPermanent),
56  myReferenceCounter(isPermanent ? 1 : 0),
57  myColor(c),
58  myCosts(-1),
59  mySavings(0),
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[myEdges.size() - 1];
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, std::mt19937* 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 
156 MSRoute::distDictionary(const std::string& id) {
157 #ifdef HAVE_FOX
158  FXMutexLock f(myDictMutex);
159 #endif
160  RouteDistDict::iterator it2 = myDistDict.find(id);
161  if (it2 == myDistDict.end()) {
162  return nullptr;
163  }
164  return it2->second.first;
165 }
166 
167 
168 void
170 #ifdef HAVE_FOX
171  FXMutexLock f(myDictMutex);
172 #endif
173  for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
174  delete i->second.first;
175  }
176  myDistDict.clear();
177  for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
178  delete i->second;
179  }
180  myDict.clear();
181 }
182 
183 
184 void
185 MSRoute::checkDist(const std::string& id) {
186 #ifdef HAVE_FOX
187  FXMutexLock f(myDictMutex);
188 #endif
189  RouteDistDict::iterator it = myDistDict.find(id);
190  if (it != myDistDict.end() && !it->second.second) {
191  const std::vector<const MSRoute*>& routes = it->second.first->getVals();
192  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
193  (*i)->release();
194  }
195  delete it->second.first;
196  myDistDict.erase(it);
197  }
198 }
199 
200 
201 void
202 MSRoute::insertIDs(std::vector<std::string>& into) {
203 #ifdef HAVE_FOX
204  FXMutexLock f(myDictMutex);
205 #endif
206  into.reserve(myDict.size() + myDistDict.size() + into.size());
207  for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
208  into.push_back((*i).first);
209  }
210  for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
211  into.push_back((*i).first);
212  }
213 }
214 
215 
216 int
217 MSRoute::writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo) const {
218  int numWritten = 0;
219  ConstMSEdgeVector::const_iterator i = myEdges.begin();
220  if (from != nullptr) {
221  i = std::find(myEdges.begin(), myEdges.end(), from);
222  }
223  for (; i != myEdges.end(); ++i) {
224  if ((*i) == upTo) {
225  return numWritten;
226  }
227  os << (*i)->getID();
228  numWritten++;
229  if (upTo || i != myEdges.end() - 1) {
230  os << ' ';
231  }
232  }
233  return numWritten;
234 }
235 
236 
237 bool
238 MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
239  MSEdgeVector::const_iterator i = edgelist.begin();
240  for (; i != edgelist.end(); ++i) {
241  if (contains(*i)) {
242  return true;
243  }
244  }
245  return false;
246 }
247 
248 
249 const MSEdge*
250 MSRoute::operator[](int index) const {
251  return myEdges[index];
252 }
253 
254 
255 void
257 #ifdef HAVE_FOX
258  FXMutexLock f(myDictMutex);
259 #endif
260  for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
261  out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_ID, (*it).second->getID());
262  out.writeAttr(SUMO_ATTR_STATE, (*it).second->myAmPermanent);
263  out.writeAttr(SUMO_ATTR_EDGES, (*it).second->myEdges).closeTag();
264  }
265  for (const auto& item : myDistDict) {
266  if (item.second.first->getVals().size() > 0) {
268  out.writeAttr(SUMO_ATTR_STATE, item.second.second);
269  out.writeAttr(SUMO_ATTR_ROUTES, item.second.first->getVals());
270  out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
271  out.closeTag();
272  }
273  }
274 }
275 
276 
277 double
278 MSRoute::getDistanceBetween(double fromPos, double toPos,
279  const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal, int routePosition) const {
280  //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
281  if (routePosition < 0 || routePosition >= (int)myEdges.size()) {
282  throw ProcessError("Invalid routePosition " + toString(routePosition) + " for route with " + toString(myEdges.size()) + " edges");
283  }
284  if (fromEdge->isInternal() && toEdge->isInternal() && fromEdge->getToJunction() == toEdge->getToJunction()) {
285  // internal edges within the same junction
286  if (fromEdge == toEdge) {
287  if (fromPos <= toPos) {
288  return toPos - fromPos;
289  }
290  } else if (fromEdge->getSuccessors().front() == toEdge) {
291  return fromEdge->getLength() - fromPos + toPos;
292  }
293  }
294  if (fromEdge->isInternal()) {
295  if (fromEdge == myEdges.front()) {
296  const MSEdge* succ = fromEdge->getSuccessors().front();
297  assert(succ != 0);
298  //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
299  return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
300  } else {
301  const MSEdge* pred = fromEdge->getPredecessors().front();
302  assert(pred != 0);
303  //std::cout << " recurse fromPred=" << pred->getID() << "\n";
304  return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal, routePosition) - fromPos;
305  }
306  }
307  if (toEdge->isInternal()) {
308  const MSEdge* pred = toEdge->getPredecessors().front();
309  assert(pred != 0);
310  //std::cout << " recurse toPred=" << pred->getID() << "\n";
311  return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal, routePosition);
312  }
313  ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
314  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
315  // start or destination not contained in route
316  return std::numeric_limits<double>::max();
317  }
318  ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
319 
320  if (fromEdge == toEdge) {
321  if (fromPos <= toPos) {
322  return toPos - fromPos;
323  } else if (it2 == myEdges.end()) {
324  // we don't visit the edge again
325  return std::numeric_limits<double>::max();
326  }
327  }
328  return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
329 }
330 
331 
332 double
333 MSRoute::getDistanceBetween(double fromPos, double toPos,
334  const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
335  bool isFirstIteration = true;
336  double distance = -fromPos;
337  MSRouteIterator it = fromEdge;
338  if (fromEdge == toEdge) {
339  // destination position is on start edge
340  if (fromPos <= toPos) {
341  return toPos - fromPos;
342  } else {
343  // we cannot go backwards. Something is wrong here
344  return std::numeric_limits<double>::max();
345  }
346  } else if (fromEdge > toEdge) {
347  // we don't visit the edge again
348  return std::numeric_limits<double>::max();
349  }
350  for (; it != end(); ++it) {
351  if (it == toEdge && !isFirstIteration) {
352  distance += toPos;
353  break;
354  } else {
355  distance += (*it)->getLength();
356  if (includeInternal && (it + 1) != end()) {
357  distance += (*it)->getInternalFollowingLengthTo(*(it + 1));
358  }
359  }
360  isFirstIteration = false;
361  }
362  return distance;
363 }
364 
365 
366 const RGBColor&
368  if (myColor == nullptr) {
370  }
371  return *myColor;
372 }
373 
374 
375 const std::vector<SUMOVehicleParameter::Stop>&
377  return myStops;
378 }
379 
380 
381 /****************************************************************************/
382 
MSRoute::checkDist
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:185
MSRoute::myDict
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:267
RGBColor::DEFAULT_COLOR
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:203
MSRoute::myColor
const RGBColor *const myColor
The color.
Definition: MSRoute.h:251
MSRoute::release
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:100
MSEdge::getSuccessors
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:959
Named
Base class for objects which have an id.
Definition: Named.h:56
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:63
MSRoute::end
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
MSRouteIterator
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:57
SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
Definition: SUMOXMLDefinitions.h:214
MSRoute::RouteDict
std::map< std::string, const MSRoute * > RouteDict
Definition of the dictionary container.
Definition: MSRoute.h:264
FileHelpers.h
MSRoute::getLastEdge
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:87
ConstMSEdgeVector
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:75
SUMO_ATTR_ID
Definition: SUMOXMLDefinitions.h:378
MSEdge.h
MSRoute::getColor
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:367
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:589
MSRoute
Definition: MSRoute.h:66
MSRoute::insertIDs
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:202
RGBColor.h
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:253
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:51
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:235
BinaryInputDevice.h
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:255
MSRoute::size
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
RGBColor
Definition: RGBColor.h:39
MSRoute::distDictionary
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:156
MSRoute::myStops
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:260
MSRoute::~MSRoute
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:63
SUMO_ATTR_EDGES
the edges of a route
Definition: SUMOXMLDefinitions.h:427
MSRoute::clear
static void clear()
Clears the dictionary (delete all known routes, too)
Definition: MSRoute.cpp:169
OutputDevice.h
MSRoute::dict_saveState
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition: MSRoute.cpp:256
ProcessError
Definition: UtilExceptions.h:39
MSRoute::operator[]
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:250
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:78
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:363
SUMO_ATTR_PROBS
Definition: SUMOXMLDefinitions.h:630
RandomDistributor< const MSRoute * >
MSRoute::myDistDict
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:273
MSRoute::myReferenceCounter
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:248
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:239
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
SUMO_ATTR_STATE
The state of a link.
Definition: SUMOXMLDefinitions.h:708
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:217
MSRoute::RouteDistDict
std::map< std::string, std::pair< RandomDistributor< const MSRoute * > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition: MSRoute.h:270
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:74
MSRoute.h
SUMO_ATTR_ROUTES
Definition: SUMOXMLDefinitions.h:631
MSRoute::getStops
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:376
MSRoute::begin
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
SUMO_TAG_ROUTE
begin/end of the description of a route
Definition: SUMOXMLDefinitions.h:125
MSRoute::dictionary
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:113
config.h
MSRoute::addReference
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:94
MSLane.h
MSRoute::containsAnyOf
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:238
MSRoute::myEdges
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:242
MSRoute::contains
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:102
Named::myID
std::string myID
The name of the object.
Definition: Named.h:133
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:278
MSEdge::getPredecessors
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:354