libosmscout  1.1.1
Navigation.h
Go to the documentation of this file.
1 #ifndef OSMSCOUT_NAVIGATION_NAVIGATION_H
2 #define OSMSCOUT_NAVIGATION_NAVIGATION_H
3 
4 /*
5  This source is part of the libosmscout library
6  Copyright (C) 2014 Tim Teulings, Vladimir Vyskocil
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 
23 #include <limits>
24 
25 #include <osmscout/GeoCoord.h>
27 
28 #include <osmscout/util/Geometry.h>
29 #include <osmscout/util/Time.h>
30 
31 namespace osmscout {
32 
33  template<class NodeDescriptionTmpl>
35  {
36  public:
37  virtual ~OutputDescription() = default;
38 
39  virtual void NextDescription(const Distance& /*distance*/,
40  std::list<RouteDescription::Node>::const_iterator& /*node*/,
41  std::list<RouteDescription::Node>::const_iterator /*end*/)
42  {};
43 
44  virtual NodeDescriptionTmpl GetDescription()
45  {return description;};
46 
47  virtual void Clear()
48  {};
49  protected:
50  NodeDescriptionTmpl description;
51  };
52 
53  template<class NodeDescriptionTmpl>
54  class Navigation
55  {
56  private:
63  bool SearchClosestSegment(const GeoCoord& location,
64  std::list<RouteDescription::Node>::const_iterator& foundNode,
65  double& foundAbscissa,
66  double& minDistance)
67  {
68  auto nextNode=locationOnRoute;
69  double abscissa=0.0;
70  bool found=false;
71  double qx,qy;
72  minDistance=std::numeric_limits<double>::max();
73  double snapDistanceInDegrees = GetDistanceInLonDegrees(snapDistanceInMeters,
74  location.GetLat());
75 
76  for (auto node=nextNode++; node!=route->Nodes().end(); node++) {
77  if (nextNode==route->Nodes().end()) {
78  break;
79  }
80  double d=DistanceToSegment(location.GetLon(),
81  location.GetLat(),
82  node->GetLocation().GetLon(),
83  node->GetLocation().GetLat(),
84  nextNode->GetLocation().GetLon(),
85  nextNode->GetLocation().GetLat(),
86  abscissa,
87  qx,
88  qy);
89  if (minDistance>=d) {
90  minDistance=d;
91  if (d<=snapDistanceInDegrees) {
92  foundNode =node;
93  foundAbscissa=abscissa;
94  found =true;
95  }
96  }
97  else if (found && d>minDistance*2) {
98  // Stop the search we have a good candidate
99  break;
100  }
101  nextNode++;
102  }
103  return found;
104  }
105 
106  public:
112  : route(nullptr),
113  outputDescription(outputDescr),
114  snapDistanceInMeters(Distance::Of<Meter>(25.0))
115  {
116  }
117 
118  void SetRoute(RouteDescription* newRoute)
119  {
120  assert(newRoute);
121  route =newRoute;
122  distanceFromStart =Distance::Of<Meter>(0.0);
123  durationFromStart =Duration(osmscout::Duration::zero());
124  locationOnRoute =route->Nodes().begin();
125  nextWaypoint =route->Nodes().begin();
126  outputDescription->Clear();
127  outputDescription->NextDescription(Distance::Of<Meter>(-1.0),
128  nextWaypoint,
129  route->Nodes().end());
130  std::list<RouteDescription::Node>::const_iterator lastWaypoint=--(route->Nodes().end());
131  duration=lastWaypoint->GetTime();
132  distance=lastWaypoint->GetDistance();
133  }
134 
135  void Clear()
136  {
137  route=nullptr;
138  }
139 
140  bool HasRoute()
141  {
142  return route!=nullptr;
143  }
144 
145  void SetSnapDistance(const Distance &distance)
146  {
147  snapDistanceInMeters=distance;
148  }
149 
151  {
152  return distanceFromStart;
153  }
154 
156  {
157  return durationFromStart;
158  }
159 
160  Distance GetDistance()
161  {
162  return distance;
163  }
164 
166  {
167  return duration;
168  }
169 
170  NodeDescriptionTmpl nextWaypointDescription()
171  {
172  return outputDescription->GetDescription();
173  }
174 
176  {
177  return *locationOnRoute;
178  }
179 
180  bool UpdateCurrentLocation(const GeoCoord& location,
181  double& minDistance)
182  {
183  auto foundNode =locationOnRoute;
184  double foundAbscissa=0.0;
185 
186  bool found=SearchClosestSegment(location,
187  foundNode,
188  foundAbscissa,
189  minDistance);
190  if (found) {
191  locationOnRoute=foundNode;
192 
193  auto nextNode=foundNode;
194 
195  nextNode++;
196  outputDescription->NextDescription(locationOnRoute->GetDistance(),
197  nextWaypoint,
198  route->Nodes().end());
199  if (foundAbscissa<0.0) {
200  foundAbscissa=0.0;
201  }
202  else if (foundAbscissa>1.0) {
203  foundAbscissa=1.0;
204  }
205  distanceFromStart =
206  nextNode->GetDistance()*foundAbscissa+locationOnRoute->GetDistance()*(1.0-foundAbscissa);
207  durationFromStart =
208  std::chrono::duration_cast<Duration>(
209  nextNode->GetTime()*foundAbscissa+locationOnRoute->GetTime()*(1.0-foundAbscissa));
210  return true;
211  }
212 
213  return false;
214  };
215 
216  bool ClosestPointOnRoute(const GeoCoord& location, GeoCoord& locOnRoute)
217  {
218  if(route == nullptr){
219  return false;
220  }
221  std::list<RouteDescription::Node>::const_iterator nextNode = route->Nodes().begin();
222  GeoCoord intersection, foundIntersection;
223  double abscissa;
224  double minDistance=std::numeric_limits<double>::max();
225  for (auto node=nextNode++; node!=route->Nodes().end(); node++) {
226  if (nextNode==route->Nodes().end()) {
227  break;
228  }
229  double d = DistanceToSegment(location,
230  node->GetLocation(),
231  nextNode->GetLocation(),
232  abscissa,
233  intersection);
234  if (minDistance > d) {
235  minDistance = d;
236  foundIntersection = intersection;
237  }
238  ++nextNode;
239  }
240  locOnRoute = foundIntersection;
241 
242  return true;
243  }
244 
245  private:
246  RouteDescription* route; // current route description
247  std::list<RouteDescription::Node>::const_iterator locationOnRoute; // last passed node on the route
248  std::list<RouteDescription::Node>::const_iterator nextWaypoint; // next node with routing instructions
249  OutputDescription<NodeDescriptionTmpl> * outputDescription; // next routing instructions
250  Distance distanceFromStart; // current length from the beginning of the route (in meters)
251  Duration durationFromStart; // current (estimated) duration from the beginning of the route
252  Distance distance; // whole lenght of the route
253  Duration duration; // whole estimated duration of the route
254  Distance snapDistanceInMeters; // max distance from the route path to consider being on route
255  };
256 }
257 
258 #endif
std::list< Node > & Nodes()
Definition: RouteDescription.h:803
Distance GetDistanceFromStart()
Definition: Navigation.h:150
OSMSCOUT_API double GetDistanceInLonDegrees(const Distance &d, double latitude=0)
Definition: RouteDescription.h:667
Definition: RouteDescription.h:53
virtual NodeDescriptionTmpl GetDescription()
Definition: Navigation.h:44
const RouteDescription::Node & GetCurrentNode()
Definition: Navigation.h:175
virtual ~OutputDescription()=default
bool HasRoute()
Definition: Navigation.h:140
virtual void Clear()
Definition: Navigation.h:47
Definition: Area.h:38
void SetRoute(RouteDescription *newRoute)
Definition: Navigation.h:118
void Clear()
Definition: Navigation.h:135
bool UpdateCurrentLocation(const GeoCoord &location, double &minDistance)
Definition: Navigation.h:180
OSMSCOUT_API double DistanceToSegment(double px, double py, double p1x, double p1y, double p2x, double p2y, double &r, double &qx, double &qy)
Duration GetDurationFromStart()
Definition: Navigation.h:155
NodeDescriptionTmpl description
Definition: Navigation.h:48
Definition: Navigation.h:34
Navigation(OutputDescription< NodeDescriptionTmpl > *outputDescr)
Definition: Navigation.h:111
Distance GetDistance()
Definition: Navigation.h:160
void SetSnapDistance(const Distance &distance)
Definition: Navigation.h:145
Definition: Distance.h:203
Timestamp::duration Duration
Definition: Time.h:29
virtual void NextDescription(const Distance &, std::list< RouteDescription::Node >::const_iterator &, std::list< RouteDescription::Node >::const_iterator)
Definition: Navigation.h:39
Duration GetDuration()
Definition: Navigation.h:165
NodeDescriptionTmpl nextWaypointDescription()
Definition: Navigation.h:170
bool ClosestPointOnRoute(const GeoCoord &location, GeoCoord &locOnRoute)
Definition: Navigation.h:216
Definition: Navigation.h:54