dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
pureprojection.cpp
Go to the documentation of this file.
1 
13 /*
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, see <http://www.gnu.org/licenses/>
26 */
27 
28 #include "pureprojection.h"
29 #include "../../../../shared/api/physical_constants.h"
30 
31 
32 namespace internals {
33 
34 const double PureProjection::TWO_PI = 2*PI; // Use double PI in order to maintain high accuracy
35 const double PureProjection::EPSLoN= 1.0e-10;
36 const double PureProjection::MAX_VAL= 4;
37 const double PureProjection::MAXLONG= 2147483647;
38 const double PureProjection::DBLLONG= 4.61168601e18;
39 
40 Point PureProjection::FromLatLngToPixel(const PointLatLng &p,const int &zoom)
41  {
42  return FromLatLngToPixel(p.Lat(), p.Lng(), zoom);
43  }
44 
45 
46  PointLatLng PureProjection::FromPixelToLatLng(const Point &p,const int &zoom)
47  {
48  return FromPixelToLatLng(p.X(), p.Y(), zoom);
49  }
50 
51  Point PureProjection::FromPixelToTileXY(const Point &p)
52  {
53  return Point((int) (p.X() / TileSize().Width()), (int) (p.Y() / TileSize().Height()));
54  }
55 
56  Point PureProjection::FromTileXYToPixel(const Point &p)
57  {
58  return Point((p.X() * TileSize().Width()), (p.Y() * TileSize().Height()));
59  }
60 
62  {
63  Size sMin = GetTileMatrixMinXY(zoom);
64  Size sMax = GetTileMatrixMaxXY(zoom);
65 
66  return Size(sMax.Width() - sMin.Width() + 1, sMax.Height() - sMin.Height() + 1);
67  }
69  {
70  Size s = GetTileMatrixSizeXY(zoom);
71  return (s.Width() * s.Height());
72  }
74  {
75  Size s = GetTileMatrixSizeXY(zoom);
76  return Size(s.Width() * TileSize().Width(), s.Height() * TileSize().Height());
77  }
78  QList<Point> PureProjection::GetAreaTileList(const RectLatLng &rect,const int &zoom,const int &padding)
79  {
80  QList<Point> ret;
81 
82  Point topLeft = FromPixelToTileXY(FromLatLngToPixel(rect.LocationTopLeft(), zoom));
83  Point rightBottom = FromPixelToTileXY(FromLatLngToPixel(rect.Bottom(), rect.Right(), zoom));
84 
85  for(int x = (topLeft.X() - padding); x <= (rightBottom.X() + padding); x++)
86  {
87  for(int y = (topLeft.Y() - padding); y <= (rightBottom.Y() + padding); y++)
88  {
89  Point p = Point(x, y);
90  if(!ret.contains(p) && p.X() >= 0 && p.Y() >= 0)
91  {
92  ret.append(p);
93  }
94  }
95  }
96  //ret.TrimExcess();
97 
98  return ret;
99  }
100 
107  double PureProjection::GetGroundResolution(const int &zoom, const double &latitude_D)
108  {
109  return (cos(latitude_D * DEG2RAD) * TWO_PI * Axis()) / GetTileMatrixSizePixel(zoom).Width();
110  }
111 
112  double PureProjection::Sign(const double &x)
113  {
114  if(x < 0.0)
115  return (-1);
116  else
117  return (1);
118  }
119 
121  {
122  qlonglong count = 0;
123  while(true)
124  {
125  if(qAbs(x) <= PI)
126  break;
127  else
128  if(((qlonglong) qAbs(x / PI)) < 2)
129  x = x - (Sign(x) * TWO_PI);
130 
131  else
132  if(((qlonglong) qAbs(x / TWO_PI)) < MAXLONG)
133  {
134  x = x - (((qlonglong) (x / TWO_PI)) * TWO_PI);
135  }
136  else
137  if(((qlonglong) qAbs(x / (MAXLONG * TWO_PI))) < MAXLONG)
138  {
139  x = x - (((qlonglong) (x / (MAXLONG * TWO_PI))) * (TWO_PI * MAXLONG));
140  }
141  else
142  if(((qlonglong) qAbs(x / (DBLLONG * TWO_PI))) < MAXLONG)
143  {
144  x = x - (((qlonglong) (x / (DBLLONG * TWO_PI))) * (TWO_PI * DBLLONG));
145  }
146  else
147  x = x - (Sign(x) * TWO_PI);
148  count++;
149  if(count > MAX_VAL)
150  break;
151  }
152  return (x);
153  }
154 
155  void PureProjection::SinCos(const double &val, double &si, double &co)
156  {
157  si = sin(val);
158  co = cos(val);
159  }
160 
161  double PureProjection::e0fn(const double &x)
162  {
163  return (1.0 - 0.25 * x * (1.0 + x / 16.0 * (3.0 + 1.25 * x)));
164  }
165 
166  double PureProjection::e1fn(const double &x)
167  {
168  return (0.375 * x * (1.0 + 0.25 * x * (1.0 + 0.46875 * x)));
169  }
170 
171  double PureProjection::e2fn(const double &x)
172  {
173  return (0.05859375 * x * x * (1.0 + 0.75 * x));
174  }
175 
176  double PureProjection::e3fn(const double &x)
177  {
178  return (x * x * x * (35.0 / 3072.0));
179  }
180 
181  double PureProjection::mlfn(const double &e0,const double &e1,const double &e2,const double &e3,const double &phi)
182  {
183  return (e0 * phi - e1 * sin(2.0 * phi) + e2 * sin(4.0 * phi) - e3 * sin(6.0 * phi));
184  }
185 
186  qlonglong PureProjection::GetUTMzone(const double &lon)
187  {
188  return ((qlonglong) (((lon + 180.0) / 6.0) + 1.0));
189  }
190 
191 
201  void PureProjection::FromGeodeticToCartesian(double Lat_D, double Lng_D, double Height, double &X, double &Y, double &Z)
202  {
203  double Lat_R = Lat_D * DEG2RAD;
204  double Lng_R = Lng_D * DEG2RAD;
205 
206  double B = Axis() * (1.0 - Flattening());
207  double ee = 1.0 - (B / Axis()) * (B / Axis());
208  double N = (Axis() / sqrt(1.0 - ee * sin(Lat_R) * sin(Lat_R)));
209 
210  X = (N + Height) * cos(Lat_R) * cos(Lng_R);
211  Y = (N + Height) * cos(Lat_R) * sin(Lng_R);
212  Z = (N * (B / Axis()) * (B / Axis()) + Height) * sin(Lat_R);
213  }
214  void PureProjection::FromCartesianTGeodetic(const double &X, const double &Y, const double &Z, double &Lat_D, double &Lng_D)
215  {
216  double E = Flattening() * (2.0 - Flattening());
217  double Lng_R = atan2(Y, X);
218 
219  double P = sqrt(X * X + Y * Y);
220  double Theta = atan2(Z, (P * (1.0 - Flattening())));
221  double st = sin(Theta);
222  double ct = cos(Theta);
223  double Lat_R = atan2(Z + E / (1.0 - Flattening()) * Axis() * st * st * st, P - E * Axis() * ct * ct * ct);
224 
225  Lat_D = Lat_R * DEG2RAD;
226  Lng_D = Lng_R * DEG2RAD;
227  }
229  {
230 
231  double lon1_R = p1.Lng() * DEG2RAD;
232  double lat1_R = p1.Lat() * DEG2RAD;
233  double lon2_R = p2.Lng() * DEG2RAD;
234  double lat2_R = p2.Lat() * DEG2RAD;
235 
236  return TWO_PI - myfmod(atan2(sin(lon1_R - lon2_R) * cos(lat2_R),
237  cos(lat1_R) * sin(lat2_R) - sin(lat1_R) * cos(lat2_R) * cos(lon1_R - lon2_R)), TWO_PI);
238  }
239 
247  {
248  double R = WGS84_RADIUS_EARTH_KM;
249  double lat1_R = p1.Lat() * DEG2RAD;
250  double lat2_R = p2.Lat() * DEG2RAD;
251  double lon1_R = p1.Lng() * DEG2RAD;
252  double lon2_R = p2.Lng() * DEG2RAD;
253  double dLat_R = (lat2_R-lat1_R);
254  double dLon_R = (lon2_R-lon1_R);
255  double a = sin(dLat_R/2) * sin(dLat_R/2) + cos(lat1_R) * cos(lat2_R) * sin(dLon_R/2) * sin(dLon_R/2);
256  double c = 2 * atan2(sqrt(a), sqrt(1-a));
257  double d = R * c;
258  return d;
259  }
260 
269  double PureProjection::DistanceBetweenLatLngAlt(PointLatLng const& p1, double const& alt1, PointLatLng const& p2, double const& alt2)
270  {
271  return sqrt(pow(DistanceBetweenLatLng(p2, p1), 2) +
272  pow(alt2-alt1, 2));
273  }
274 
275  void PureProjection::offSetFromLatLngs(PointLatLng p1,PointLatLng p2,double &distance,double &bearing)
276  {
277  distance=DistanceBetweenLatLng(p1, p2);
278  bearing=courseBetweenLatLng(p1, p2);
279  }
280 
281  double PureProjection::myfmod(double x,double y)
282  {
283  return x - y*floor(x/y);
284  }
285 
286  PointLatLng PureProjection::translate(PointLatLng p1,double distance,double bearing)
287  {
288  PointLatLng ret;
289  double d=distance;
290  double tc=bearing;
291  double lat1_R = p1.Lat() * DEG2RAD;
292  double lon1_R = p1.Lng() * DEG2RAD;
293  double R=6378137;
294  double lat2_R = asin(sin(lat1_R) * cos(d/R) + cos(lat1_R) * sin(d/R) * cos(tc) );
295  double lon2_R = lon1_R + atan2(sin(tc) * sin(d/R) * cos(lat1_R),
296  cos(d/R) - sin(lat1_R) * sin(lat2_R));
297 
298  ret.SetLat(lat2_R * RAD2DEG);
299  ret.SetLng(lon2_R * RAD2DEG);
300  return ret;
301  }
302 
310  double PureProjection::bound(const double &val, const double &minValue, const double &maxValue) const
311  {
312  return qMin(qMax(val, minValue), maxValue);
313  }
314 }
static double AdjustLongitude(double x)
virtual Size TileSize() const =0
virtual core::Point FromLatLngToPixel(double lat, double lng, int const &zoom)=0
DEG2RAD
Definition: OPPlots.m:107
void SetLat(const double &value)
Definition: pointlatlng.h:69
double bound(double const &n, double const &minValue, double const &maxValue) const
PureProjection::bound Bounds the value at an upper and lower threshold.
static double e3fn(const double &x)
static const double TWO_PI
virtual Size GetTileMatrixSizeXY(const int &zoom)
virtual PointLatLng FromPixelToLatLng(const qint64 &x, const qint64 &y, const int &zoom)=0
const double PI
Definition: def.h:28
virtual core::Point FromPixelToTileXY(const core::Point &p)
QList< core::Point > GetAreaTileList(const RectLatLng &rect, const int &zoom, const int &padding)
static double mlfn(const double &e0, const double &e1, const double &e2, const double &e3, const double &phi)
static qlonglong GetUTMzone(const double &lon)
virtual double Flattening() const =0
void SetLng(const double &value)
Definition: pointlatlng.h:80
end a
Definition: OPPlots.m:98
static double e2fn(const double &x)
double Lng() const
Definition: pointlatlng.h:76
double Lat() const
Definition: pointlatlng.h:64
double Bottom() const
Definition: rectlatlng.h:154
virtual Size GetTileMatrixMinXY(const int &zoom)=0
static const double EPSLoN
double Right() const
Definition: rectlatlng.h:149
static double Sign(const double &x)
int GetTileMatrixItemCount(const int &zoom)
static const double MAX_VAL
virtual double Axis() const =0
static double DistanceBetweenLatLngAlt(PointLatLng const &p1, double const &alt1, PointLatLng const &p2, double const &alt2)
PureProjection::DistanceBetweenLatLngAlt Returns 3D distance between two geodetic points...
static void SinCos(const double &val, double &sin, double &cos)
static double e0fn(const double &x)
RAD2DEG
Definition: OPPlots.m:106
static double DistanceBetweenLatLng(PointLatLng const &p1, PointLatLng const &p2)
PureProjection::DistanceBetweenLatLng Returns 2D distance between two geodetic points.
PointLatLng translate(PointLatLng p1, double distance, double bearing)
void FromCartesianTGeodetic(const double &X, const double &Y, const double &Z, double &Lat, double &Lng)
virtual Size GetTileMatrixMaxXY(const int &zoom)=0
PointLatLng LocationTopLeft() const
Definition: rectlatlng.h:73
Definition: icore.h:39
static double e1fn(const double &x)
void FromGeodeticToCartesian(double Lat, double Lng, double Height, double &X, double &Y, double &Z)
PureProjection::FromGeodeticToCartesian.
static const double MAXLONG
x
Definition: OPPlots.m:100
virtual double GetGroundResolution(const int &zoom, const double &latitude)
PureProjection::GetGroundResolution Returns the conversion from pixels to meters. ...
N
Definition: OPPlots.m:112
virtual Size GetTileMatrixSizePixel(const int &zoom)
static const double DBLLONG
double courseBetweenLatLng(const PointLatLng &p1, const PointLatLng &p2)
void offSetFromLatLngs(PointLatLng p1, PointLatLng p2, double &dX, double &dY)
virtual core::Point FromTileXYToPixel(const core::Point &p)
y
Definition: OPPlots.m:101