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), myStops(stops) {}
59 
60 
62  delete myColor;
63 }
64 
65 
67 MSRoute::begin() const {
68  return myEdges.begin();
69 }
70 
71 
73 MSRoute::end() const {
74  return myEdges.end();
75 }
76 
77 
78 int
79 MSRoute::size() const {
80  return (int)myEdges.size();
81 }
82 
83 
84 const MSEdge*
86  assert(myEdges.size() > 0);
87  return myEdges[myEdges.size() - 1];
88 }
89 
90 
91 void
94 }
95 
96 
97 void
100  if (myReferenceCounter == 0) {
101 #ifdef HAVE_FOX
102  FXMutexLock f(myDictMutex);
103 #endif
104  myDict.erase(myID);
105  delete this;
106  }
107 }
108 
109 
110 bool
111 MSRoute::dictionary(const std::string& id, const MSRoute* route) {
112 #ifdef HAVE_FOX
113  FXMutexLock f(myDictMutex);
114 #endif
115  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
116  myDict[id] = route;
117  return true;
118  }
119  return false;
120 }
121 
122 
123 bool
124 MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* const routeDist, const bool permanent) {
125 #ifdef HAVE_FOX
126  FXMutexLock f(myDictMutex);
127 #endif
128  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
129  myDistDict[id] = std::make_pair(routeDist, permanent);
130  return true;
131  }
132  return false;
133 }
134 
135 
136 const MSRoute*
137 MSRoute::dictionary(const std::string& id, std::mt19937* rng) {
138 #ifdef HAVE_FOX
139  FXMutexLock f(myDictMutex);
140 #endif
141  RouteDict::iterator it = myDict.find(id);
142  if (it == myDict.end()) {
143  RouteDistDict::iterator it2 = myDistDict.find(id);
144  if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
145  return 0;
146  }
147  return it2->second.first->get(rng);
148  }
149  return it->second;
150 }
151 
152 
154 MSRoute::distDictionary(const std::string& id) {
155 #ifdef HAVE_FOX
156  FXMutexLock f(myDictMutex);
157 #endif
158  RouteDistDict::iterator it2 = myDistDict.find(id);
159  if (it2 == myDistDict.end()) {
160  return 0;
161  }
162  return it2->second.first;
163 }
164 
165 
166 void
168 #ifdef HAVE_FOX
169  FXMutexLock f(myDictMutex);
170 #endif
171  for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
172  delete i->second.first;
173  }
174  myDistDict.clear();
175  for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
176  delete i->second;
177  }
178  myDict.clear();
179 }
180 
181 
182 void
183 MSRoute::checkDist(const std::string& id) {
184 #ifdef HAVE_FOX
185  FXMutexLock f(myDictMutex);
186 #endif
187  RouteDistDict::iterator it = myDistDict.find(id);
188  if (it != myDistDict.end() && !it->second.second) {
189  const std::vector<const MSRoute*>& routes = it->second.first->getVals();
190  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
191  (*i)->release();
192  }
193  delete it->second.first;
194  myDistDict.erase(it);
195  }
196 }
197 
198 
199 void
200 MSRoute::insertIDs(std::vector<std::string>& into) {
201 #ifdef HAVE_FOX
202  FXMutexLock f(myDictMutex);
203 #endif
204  into.reserve(myDict.size() + myDistDict.size() + into.size());
205  for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
206  into.push_back((*i).first);
207  }
208  for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
209  into.push_back((*i).first);
210  }
211 }
212 
213 
214 int
215 MSRoute::writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo) const {
216  int numWritten = 0;
217  ConstMSEdgeVector::const_iterator i = myEdges.begin();
218  if (from != 0) {
219  i = std::find(myEdges.begin(), myEdges.end(), from);
220  }
221  for (; i != myEdges.end(); ++i) {
222  if ((*i) == upTo) {
223  return numWritten;
224  }
225  os << (*i)->getID();
226  numWritten++;
227  if (upTo || i != myEdges.end() - 1) {
228  os << ' ';
229  }
230  }
231  return numWritten;
232 }
233 
234 
235 bool
236 MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
237  MSEdgeVector::const_iterator i = edgelist.begin();
238  for (; i != edgelist.end(); ++i) {
239  if (contains(*i)) {
240  return true;
241  }
242  }
243  return false;
244 }
245 
246 
247 const MSEdge*
248 MSRoute::operator[](int index) const {
249  return myEdges[index];
250 }
251 
252 
253 void
255 #ifdef HAVE_FOX
256  FXMutexLock f(myDictMutex);
257 #endif
258  for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
259  out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_ID, (*it).second->getID());
260  out.writeAttr(SUMO_ATTR_STATE, (*it).second->myAmPermanent);
261  out.writeAttr(SUMO_ATTR_EDGES, (*it).second->myEdges).closeTag();
262  }
263  for (RouteDistDict::iterator it = myDistDict.begin(); it != myDistDict.end(); ++it) {
265  out.writeAttr(SUMO_ATTR_STATE, (*it).second.second);
266  out.writeAttr(SUMO_ATTR_ROUTES, (*it).second.first->getVals());
267  out.writeAttr(SUMO_ATTR_PROBS, (*it).second.first->getProbs());
268  out.closeTag();
269  }
270 }
271 
272 
273 double
274 MSRoute::getDistanceBetween(double fromPos, double toPos,
275  const MSEdge* fromEdge, const MSEdge* toEdge, bool includeInternal) const {
277  //std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << " includeInternal=" << includeInternal << "\n";
278  if (fromEdge->isInternal()) {
279  if (fromEdge == myEdges.front()) {
280  const MSEdge* succ = fromEdge->getSuccessors().front();
281  assert(succ != 0);
282  //std::cout << " recurse fromSucc=" << succ->getID() << "\n";
283  return (fromEdge->getLength() - fromPos) + getDistanceBetween(0, toPos, succ, toEdge, includeInternal);
284  } else {
285  const MSEdge* pred = fromEdge->getPredecessors().front();
286  assert(pred != 0);
287  //std::cout << " recurse fromPred=" << pred->getID() << "\n";
288  return getDistanceBetween(pred->getLength(), toPos, pred, toEdge, includeInternal) - fromPos;
289  }
290  }
291  if (toEdge->isInternal()) {
292  const MSEdge* pred = toEdge->getPredecessors().front();
293  assert(pred != 0);
294  //std::cout << " recurse toPred=" << pred->getID() << "\n";
295  return toPos + getDistanceBetween(fromPos, pred->getLength(), fromEdge, pred, includeInternal);
296  }
297  ConstMSEdgeVector::const_iterator it = std::find(myEdges.begin(), myEdges.end(), fromEdge);
298  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
299  // start or destination not contained in route
300  return std::numeric_limits<double>::max();
301  }
302  ConstMSEdgeVector::const_iterator it2 = std::find(it + 1, myEdges.end(), toEdge);
303 
304  if (fromEdge == toEdge) {
305  if (fromPos <= toPos) {
306  return toPos - fromPos;
307  } else if (it2 == myEdges.end()) {
308  // we don't visit the edge again
309  return std::numeric_limits<double>::max();
310  }
311  }
312  return getDistanceBetween(fromPos, toPos, it, it2, includeInternal);
313 }
314 
315 
316 double
317 MSRoute::getDistanceBetween(double fromPos, double toPos,
318  const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
319  bool isFirstIteration = true;
320  double distance = -fromPos;
321  MSRouteIterator it = fromEdge;
322  if (fromEdge == toEdge) {
323  // destination position is on start edge
324  if (fromPos <= toPos) {
325  return toPos - fromPos;
326  } else {
327  // we cannot go backwards. Something is wrong here
328  return std::numeric_limits<double>::max();
329  }
330  } else if (fromEdge > toEdge) {
331  // we don't visit the edge again
332  return std::numeric_limits<double>::max();
333  }
334  for (; it != end(); ++it) {
335  if (it == toEdge && !isFirstIteration) {
336  distance += toPos;
337  break;
338  } else {
339  distance += (*it)->getLength();
340  if (includeInternal && (it + 1) != end()) {
341  distance += (*it)->getInternalFollowingLengthTo(*(it + 1));
342  }
343  }
344  isFirstIteration = false;
345  }
346  return distance;
347 }
348 
349 
350 const RGBColor&
352  if (myColor == 0) {
354  }
355  return *myColor;
356 }
357 
358 
359 const std::vector<SUMOVehicleParameter::Stop>&
361  return myStops;
362 }
363 
364 
365 /****************************************************************************/
366 
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:246
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:98
Represents a generic random distribution.
distribution of a route
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:337
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:274
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:351
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:85
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:154
double getLength() const
return the length of the edge
Definition: MSEdge.h:563
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:79
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:254
The state of a link.
static void insertIDs(std::vector< std::string > &into)
Definition: MSRoute.cpp:200
A road/street connecting two junctions.
Definition: MSEdge.h:75
static void clear()
Clears the dictionary (delete all known routes, too)
Definition: MSRoute.cpp:167
the edges of a route
static RouteDistDict myDistDict
The dictionary container.
Definition: MSRoute.h:255
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:185
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:252
virtual ~MSRoute()
Destructor.
Definition: MSRoute.cpp:61
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:224
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:215
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition: MSRoute.h:242
Base class for objects which have an id.
Definition: Named.h:49
const MSEdge * operator[](int index) const
Definition: MSRoute.cpp:248
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:926
std::string myID
The name of the object.
Definition: Named.h:121
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:236
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition: MSRoute.h:227
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:92
int myReferenceCounter
Information by how many vehicles the route is used.
Definition: MSRoute.h:233
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:67
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:183
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:360
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:73
static RouteDict myDict
The dictionary container.
Definition: MSRoute.h:249
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:236
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:111