libosmscout 1.1.1
Loading...
Searching...
No Matches
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
29#include <osmscout/util/Time.h>
30
31namespace 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>
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 : outputDescription(outputDescr),
113 snapDistanceInMeters(Distance::Of<Meter>(25.0))
114 {
115 }
116
118 {
119 assert(newRoute);
120 route =newRoute;
121 distanceFromStart =Distance::Of<Meter>(0.0);
122 durationFromStart =Duration(osmscout::Duration::zero());
123 locationOnRoute =route->Nodes().begin();
124 nextWaypoint =route->Nodes().begin();
125 outputDescription->Clear();
126 outputDescription->NextDescription(Distance::Of<Meter>(-1.0),
127 nextWaypoint,
128 route->Nodes().end());
129 std::list<RouteDescription::Node>::const_iterator lastWaypoint=--(route->Nodes().end());
130 duration=lastWaypoint->GetTime();
131 distance=lastWaypoint->GetDistance();
132 }
133
134 void Clear()
135 {
136 route=nullptr;
137 }
138
139 bool HasRoute() const
140 {
141 return route!=nullptr;
142 }
143
144 void SetSnapDistance(const Distance &distance)
145 {
146 snapDistanceInMeters=distance;
147 }
148
150 {
151 return distanceFromStart;
152 }
153
155 {
156 return durationFromStart;
157 }
158
159 Distance GetDistance()
160 {
161 return distance;
162 }
163
165 {
166 return duration;
167 }
168
169 NodeDescriptionTmpl nextWaypointDescription()
170 {
171 return outputDescription->GetDescription();
172 }
173
175 {
176 return *locationOnRoute;
177 }
178
179 bool UpdateCurrentLocation(const GeoCoord& location,
180 double& minDistance)
181 {
182 auto foundNode =locationOnRoute;
183 double foundAbscissa=0.0;
184
185 bool found=SearchClosestSegment(location,
186 foundNode,
187 foundAbscissa,
188 minDistance);
189 if (found) {
190 locationOnRoute=foundNode;
191
192 auto nextNode=foundNode;
193
194 nextNode++;
195 outputDescription->NextDescription(locationOnRoute->GetDistance(),
196 nextWaypoint,
197 route->Nodes().end());
198 if (foundAbscissa<0.0) {
199 foundAbscissa=0.0;
200 }
201 else if (foundAbscissa>1.0) {
202 foundAbscissa=1.0;
203 }
204 distanceFromStart =
205 nextNode->GetDistance()*foundAbscissa+locationOnRoute->GetDistance()*(1.0-foundAbscissa);
206 durationFromStart =
207 std::chrono::duration_cast<Duration>(
208 nextNode->GetTime()*foundAbscissa+locationOnRoute->GetTime()*(1.0-foundAbscissa));
209 return true;
210 }
211
212 return false;
213 };
214
215 bool ClosestPointOnRoute(const GeoCoord& location, GeoCoord& locOnRoute)
216 {
217 if(route == nullptr){
218 return false;
219 }
220 std::list<RouteDescription::Node>::const_iterator nextNode = route->Nodes().begin();
221 GeoCoord intersection, foundIntersection;
222 double abscissa;
223 double minDistance=std::numeric_limits<double>::max();
224 for (auto node=nextNode++; node!=route->Nodes().end(); node++) {
225 if (nextNode==route->Nodes().end()) {
226 break;
227 }
228 double d = DistanceToSegment(location,
229 node->GetLocation(),
230 nextNode->GetLocation(),
231 abscissa,
232 intersection);
233 if (minDistance > d) {
234 minDistance = d;
235 foundIntersection = intersection;
236 }
237 ++nextNode;
238 }
239 locOnRoute = foundIntersection;
240
241 return true;
242 }
243
244 private:
245 RouteDescription* route=nullptr; // current route description
246 std::list<RouteDescription::Node>::const_iterator locationOnRoute; // last passed node on the route
247 std::list<RouteDescription::Node>::const_iterator nextWaypoint; // next node with routing instructions
248 OutputDescription<NodeDescriptionTmpl> * outputDescription; // next routing instructions
249 Distance distanceFromStart; // current length from the beginning of the route (in meters)
250 Duration durationFromStart; // current (estimated) duration from the beginning of the route
251 Distance distance; // whole lenght of the route
252 Duration duration; // whole estimated duration of the route
253 Distance snapDistanceInMeters; // max distance from the route path to consider being on route
254 };
255}
256
257#endif
Definition Distance.h:204
bool HasRoute() const
Definition Navigation.h:139
void SetRoute(RouteDescription *newRoute)
Definition Navigation.h:117
Duration GetDurationFromStart() const
Definition Navigation.h:154
Duration GetDuration() const
Definition Navigation.h:164
void Clear()
Definition Navigation.h:134
const RouteDescription::Node & GetCurrentNode() const
Definition Navigation.h:174
bool UpdateCurrentLocation(const GeoCoord &location, double &minDistance)
Definition Navigation.h:179
bool ClosestPointOnRoute(const GeoCoord &location, GeoCoord &locOnRoute)
Definition Navigation.h:215
Distance GetDistanceFromStart()
Definition Navigation.h:149
void SetSnapDistance(const Distance &distance)
Definition Navigation.h:144
Navigation(OutputDescription< NodeDescriptionTmpl > *outputDescr)
Definition Navigation.h:111
Distance GetDistance()
Definition Navigation.h:159
NodeDescriptionTmpl nextWaypointDescription()
Definition Navigation.h:169
Definition Navigation.h:35
virtual void Clear()
Definition Navigation.h:47
virtual void NextDescription(const Distance &, std::list< RouteDescription::Node >::const_iterator &, std::list< RouteDescription::Node >::const_iterator)
Definition Navigation.h:39
NodeDescriptionTmpl description
Definition Navigation.h:50
virtual ~OutputDescription()=default
virtual NodeDescriptionTmpl GetDescription()
Definition Navigation.h:44
Definition RouteDescription.h:688
Definition RouteDescription.h:55
OSMSCOUT_API double DistanceToSegment(double px, double py, double p1x, double p1y, double p2x, double p2y, double &r, double &qx, double &qy)
OSMSCOUT_API double GetDistanceInLonDegrees(const Distance &d, double latitude=0)
Definition Area.h:39
Timestamp::duration Duration
Definition Time.h:29