Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
57962f3a
Commit
57962f3a
authored
Nov 10, 2019
by
Matej Frančeškin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use GeographicLib UTM conversions
parent
1ee854e1
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
19 additions
and
616 deletions
+19
-616
qgroundcontrol.pro
qgroundcontrol.pro
+0
-2
QGCGeo.cc
src/Geo/QGCGeo.cc
+13
-11
UTM.cpp
src/Geo/UTM.cpp
+0
-434
UTM.h
src/Geo/UTM.h
+0
-163
SHPFileHelper.cc
src/SHPFileHelper.cc
+6
-6
No files found.
qgroundcontrol.pro
View file @
57962f3a
...
...
@@ -629,7 +629,6 @@ HEADERS += \
src
/
PositionManager
/
PositionManager
.
h
\
src
/
PositionManager
/
SimulatedPosition
.
h
\
src
/
Geo
/
QGCGeo
.
h
\
src
/
Geo
/
UTM
.
h
\
src
/
Geo
/
Constants
.
hpp
\
src
/
Geo
/
Math
.
hpp
\
src
/
Geo
/
Utility
.
hpp
\
...
...
@@ -866,7 +865,6 @@ SOURCES += \
src
/
PositionManager
/
PositionManager
.
cpp
\
src
/
PositionManager
/
SimulatedPosition
.
cc
\
src
/
Geo
/
QGCGeo
.
cc
\
src
/
Geo
/
UTM
.
cpp
\
src
/
Geo
/
Math
.
cpp
\
src
/
Geo
/
Utility
.
cpp
\
src
/
Geo
/
UTMUPS
.
cpp
\
...
...
src/Geo/QGCGeo.cc
View file @
57962f3a
...
...
@@ -13,7 +13,7 @@
#include <limits>
#include "QGCGeo.h"
#include "UTM
.h
"
#include "UTM
UPS.hpp
"
// These defines are private
#define M_DEG_TO_RAD (M_PI / 180.0)
...
...
@@ -26,7 +26,7 @@
#define CONSTANTS_ABSOLUTE_NULL_CELSIUS -273.15f
/* °C */
#define CONSTANTS_RADIUS_OF_EARTH 6371000
/* meters (m) */
static
const
float
epsilon
=
std
::
numeric_limits
<
double
>::
epsilon
();
static
const
double
epsilon
=
std
::
numeric_limits
<
double
>::
epsilon
();
void
convertGeoToNed
(
QGeoCoordinate
coord
,
QGeoCoordinate
origin
,
double
*
x
,
double
*
y
,
double
*
z
)
{
...
...
@@ -50,7 +50,7 @@ void convertGeoToNed(QGeoCoordinate coord, QGeoCoordinate origin, double* x, dou
double
ref_cos_lat
=
cos
(
ref_lat_rad
);
double
c
=
acos
(
ref_sin_lat
*
sin_lat
+
ref_cos_lat
*
cos_lat
*
cos_d_lon
);
double
k
=
(
f
abs
(
c
)
<
epsilon
)
?
1.0
:
(
c
/
sin
(
c
));
double
k
=
(
abs
(
c
)
<
epsilon
)
?
1.0
:
(
c
/
sin
(
c
));
*
x
=
k
*
(
ref_cos_lat
*
sin_lat
-
ref_sin_lat
*
cos_lat
*
cos_d_lon
)
*
CONSTANTS_RADIUS_OF_EARTH
;
*
y
=
k
*
cos_lat
*
sin
(
lon_rad
-
ref_lon_rad
)
*
CONSTANTS_RADIUS_OF_EARTH
;
...
...
@@ -61,7 +61,7 @@ void convertGeoToNed(QGeoCoordinate coord, QGeoCoordinate origin, double* x, dou
void
convertNedToGeo
(
double
x
,
double
y
,
double
z
,
QGeoCoordinate
origin
,
QGeoCoordinate
*
coord
)
{
double
x_rad
=
x
/
CONSTANTS_RADIUS_OF_EARTH
;
double
y_rad
=
y
/
CONSTANTS_RADIUS_OF_EARTH
;
double
c
=
sqrt
f
(
x_rad
*
x_rad
+
y_rad
*
y_rad
);
double
c
=
sqrt
(
x_rad
*
x_rad
+
y_rad
*
y_rad
);
double
sin_c
=
sin
(
c
);
double
cos_c
=
cos
(
c
);
...
...
@@ -74,7 +74,7 @@ void convertNedToGeo(double x, double y, double z, QGeoCoordinate origin, QGeoCo
double
lat_rad
;
double
lon_rad
;
if
(
f
abs
(
c
)
>
epsilon
)
{
if
(
abs
(
c
)
>
epsilon
)
{
lat_rad
=
asin
(
cos_c
*
ref_sin_lat
+
(
x_rad
*
sin_c
*
ref_cos_lat
)
/
c
);
lon_rad
=
(
ref_lon_rad
+
atan2
(
y_rad
*
sin_c
,
c
*
ref_cos_lat
*
cos_c
-
x_rad
*
ref_sin_lat
*
sin_c
));
...
...
@@ -91,14 +91,16 @@ void convertNedToGeo(double x, double y, double z, QGeoCoordinate origin, QGeoCo
int
convertGeoToUTM
(
const
QGeoCoordinate
&
coord
,
double
&
easting
,
double
&
northing
)
{
return
LatLonToUTMXY
(
coord
.
latitude
(),
coord
.
longitude
(),
-
1
/* zone */
,
easting
,
northing
);
int
zone
;
bool
northp
;
GeographicLib
::
UTMUPS
::
Forward
(
coord
.
latitude
(),
coord
.
longitude
(),
zone
,
northp
,
easting
,
northing
);
return
zone
;
}
void
convertUTMToGeo
(
double
easting
,
double
northing
,
int
zone
,
bool
southhemi
,
QGeoCoordinate
&
coord
)
{
double
latRadians
,
lonRadians
;
UTMXYToLatLon
(
easting
,
northing
,
zone
,
southhemi
,
latRadians
,
lonRadians
);
coord
.
setLatitude
(
RadToDeg
(
latRadians
));
coord
.
setLongitude
(
RadToDeg
(
lonRadians
));
double
lat
,
lon
;
GeographicLib
::
UTMUPS
::
Reverse
(
zone
,
!
southhemi
,
easting
,
northing
,
lat
,
lon
);
coord
.
setLatitude
(
lat
);
coord
.
setLongitude
(
lon
);
}
src/Geo/UTM.cpp
deleted
100644 → 0
View file @
1ee854e1
// UTM.c
// Original Javascript by Chuck Taylor
// Port to C++ by Alex Hajnal
//
// *** THIS CODE USES 32-BIT FLOATS BY DEFAULT ***
// *** For 64-bit double-precision edit UTM.h: undefine FLOAT_32 and define FLOAT_64
//
// This is a simple port of the code on the Geographic/UTM Coordinate Converter (1) page from Javascript to C++.
// Using this you can easily convert between UTM and WGS84 (latitude and longitude).
// Accuracy seems to be around 50cm (I suspect rounding errors are limiting precision).
// This code is provided as-is and has been minimally tested; enjoy but use at your own risk!
// The license for UTM.cpp and UTM.h is the same as the original Javascript:
// "The C++ source code in UTM.cpp and UTM.h may be copied and reused without restriction."
//
// 1) http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
// QGC Note: This file has been slightly modified to prevent possible conflicts with other parts of the system
#include "UTM.h"
#include <math.h>
#define pi 3.14159265358979
/* Ellipsoid model constants (actual values here are for WGS84) */
#define sm_a 6378137.0
#define sm_b 6356752.314
#define sm_EccSquared 6.69437999013e-03
#define UTMScaleFactor 0.9996
// DegToRad
// Converts degrees to radians.
double
DegToRad
(
double
deg
)
{
return
(
deg
/
180.0
*
pi
);
}
// RadToDeg
// Converts radians to degrees.
double
RadToDeg
(
double
rad
)
{
return
(
rad
/
pi
*
180.0
);
}
// ArcLengthOfMeridian
// Computes the ellipsoidal distance from the equator to a point at a
// given latitude.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// phi - Latitude of the point, in radians.
//
// Globals:
// sm_a - Ellipsoid model major axis.
// sm_b - Ellipsoid model minor axis.
//
// Returns:
// The ellipsoidal distance of the point from the equator, in meters.
double
ArcLengthOfMeridian
(
double
phi
)
{
double
alpha
,
beta
,
gamma
,
delta
,
epsilon
,
n
;
double
result
;
/* Precalculate n */
n
=
(
sm_a
-
sm_b
)
/
(
sm_a
+
sm_b
);
/* Precalculate alpha */
alpha
=
((
sm_a
+
sm_b
)
/
2.0
)
*
(
1.0
+
(
pow
(
n
,
2.0
)
/
4.0
)
+
(
pow
(
n
,
4.0
)
/
64.0
));
/* Precalculate beta */
beta
=
(
-
3.0
*
n
/
2.0
)
+
(
9.0
*
pow
(
n
,
3.0
)
/
16.0
)
+
(
-
3.0
*
pow
(
n
,
5.0
)
/
32.0
);
/* Precalculate gamma */
gamma
=
(
15.0
*
pow
(
n
,
2.0
)
/
16.0
)
+
(
-
15.0
*
pow
(
n
,
4.0
)
/
32.0
);
/* Precalculate delta */
delta
=
(
-
35.0
*
pow
(
n
,
3.0
)
/
48.0
)
+
(
105.0
*
pow
(
n
,
5.0
)
/
256.0
);
/* Precalculate epsilon */
epsilon
=
(
315.0
*
pow
(
n
,
4.0
)
/
512.0
);
/* Now calculate the sum of the series and return */
result
=
alpha
*
(
phi
+
(
beta
*
sin
(
2.0
*
phi
))
+
(
gamma
*
sin
(
4.0
*
phi
))
+
(
delta
*
sin
(
6.0
*
phi
))
+
(
epsilon
*
sin
(
8.0
*
phi
)));
return
result
;
}
// UTMCentralMeridian
// Determines the central meridian for the given UTM zone.
//
// Inputs:
// zone - An integer value designating the UTM zone, range [1,60].
//
// Returns:
// The central meridian for the given UTM zone, in radians
// Range of the central meridian is the radian equivalent of [-177,+177].
double
UTMCentralMeridian
(
int
zone
)
{
double
cmeridian
;
cmeridian
=
DegToRad
(
-
183.0
+
((
double
)
zone
*
6.0
));
return
cmeridian
;
}
// FootpointLatitude
//
// Computes the footpoint latitude for use in converting transverse
// Mercator coordinates to ellipsoidal coordinates.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// y - The UTM northing coordinate, in meters.
//
// Returns:
// The footpoint latitude, in radians.
double
FootpointLatitude
(
double
y
)
{
double
y_
,
alpha_
,
beta_
,
gamma_
,
delta_
,
epsilon_
,
n
;
double
result
;
/* Precalculate n (Eq. 10.18) */
n
=
(
sm_a
-
sm_b
)
/
(
sm_a
+
sm_b
);
/* Precalculate alpha_ (Eq. 10.22) */
/* (Same as alpha in Eq. 10.17) */
alpha_
=
((
sm_a
+
sm_b
)
/
2.0
)
*
(
1
+
(
pow
(
n
,
2.0
)
/
4
)
+
(
pow
(
n
,
4.0
)
/
64
));
/* Precalculate y_ (Eq. 10.23) */
y_
=
y
/
alpha_
;
/* Precalculate beta_ (Eq. 10.22) */
beta_
=
(
3.0
*
n
/
2.0
)
+
(
-
27.0
*
pow
(
n
,
3.0
)
/
32.0
)
+
(
269.0
*
pow
(
n
,
5.0
)
/
512.0
);
/* Precalculate gamma_ (Eq. 10.22) */
gamma_
=
(
21.0
*
pow
(
n
,
2.0
)
/
16.0
)
+
(
-
55.0
*
pow
(
n
,
4.0
)
/
32.0
);
/* Precalculate delta_ (Eq. 10.22) */
delta_
=
(
151.0
*
pow
(
n
,
3.0
)
/
96.0
)
+
(
-
417.0
*
pow
(
n
,
5.0
)
/
128.0
);
/* Precalculate epsilon_ (Eq. 10.22) */
epsilon_
=
(
1097.0
*
pow
(
n
,
4.0
)
/
512.0
);
/* Now calculate the sum of the series (Eq. 10.21) */
result
=
y_
+
(
beta_
*
sin
(
2.0
*
y_
))
+
(
gamma_
*
sin
(
4.0
*
y_
))
+
(
delta_
*
sin
(
6.0
*
y_
))
+
(
epsilon_
*
sin
(
8.0
*
y_
));
return
result
;
}
// MapLatLonToXY
// Converts a latitude/longitude pair to x and y coordinates in the
// Transverse Mercator projection. Note that Transverse Mercator is not
// the same as UTM; a scale factor is required to convert between them.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// phi - Latitude of the point, in radians.
// lambda - Longitude of the point, in radians.
// lambda0 - Longitude of the central meridian to be used, in radians.
//
// Outputs:
// x - The x coordinate of the computed point.
// y - The y coordinate of the computed point.
//
// Returns:
// The function does not return a value.
void
MapLatLonToXY
(
double
phi
,
double
lambda
,
double
lambda0
,
double
&
x
,
double
&
y
)
{
double
N
,
nu2
,
ep2
,
t
,
t2
,
l
;
double
l3coef
,
l4coef
,
l5coef
,
l6coef
,
l7coef
,
l8coef
;
//double tmp; // Unused
/* Precalculate ep2 */
ep2
=
(
pow
(
sm_a
,
2.0
)
-
pow
(
sm_b
,
2.0
))
/
pow
(
sm_b
,
2.0
);
/* Precalculate nu2 */
nu2
=
ep2
*
pow
(
cos
(
phi
),
2.0
);
/* Precalculate N */
N
=
pow
(
sm_a
,
2.0
)
/
(
sm_b
*
sqrt
(
1
+
nu2
));
/* Precalculate t */
t
=
tan
(
phi
);
t2
=
t
*
t
;
//tmp = (t2 * t2 * t2) - pow(t, 6.0); // Unused
/* Precalculate l */
l
=
lambda
-
lambda0
;
/* Precalculate coefficients for l**n in the equations below
so a normal human being can read the expressions for easting
and northing
-- l**1 and l**2 have coefficients of 1.0 */
l3coef
=
1.0
-
t2
+
nu2
;
l4coef
=
5.0
-
t2
+
9
*
nu2
+
4.0
*
(
nu2
*
nu2
);
l5coef
=
5.0
-
18.0
*
t2
+
(
t2
*
t2
)
+
14.0
*
nu2
-
58.0
*
t2
*
nu2
;
l6coef
=
61.0
-
58.0
*
t2
+
(
t2
*
t2
)
+
270.0
*
nu2
-
330.0
*
t2
*
nu2
;
l7coef
=
61.0
-
479.0
*
t2
+
179.0
*
(
t2
*
t2
)
-
(
t2
*
t2
*
t2
);
l8coef
=
1385.0
-
3111.0
*
t2
+
543.0
*
(
t2
*
t2
)
-
(
t2
*
t2
*
t2
);
/* Calculate easting (x) */
x
=
N
*
cos
(
phi
)
*
l
+
(
N
/
6.0
*
pow
(
cos
(
phi
),
3.0
)
*
l3coef
*
pow
(
l
,
3.0
))
+
(
N
/
120.0
*
pow
(
cos
(
phi
),
5.0
)
*
l5coef
*
pow
(
l
,
5.0
))
+
(
N
/
5040.0
*
pow
(
cos
(
phi
),
7.0
)
*
l7coef
*
pow
(
l
,
7.0
));
/* Calculate northing (y) */
y
=
ArcLengthOfMeridian
(
phi
)
+
(
t
/
2.0
*
N
*
pow
(
cos
(
phi
),
2.0
)
*
pow
(
l
,
2.0
))
+
(
t
/
24.0
*
N
*
pow
(
cos
(
phi
),
4.0
)
*
l4coef
*
pow
(
l
,
4.0
))
+
(
t
/
720.0
*
N
*
pow
(
cos
(
phi
),
6.0
)
*
l6coef
*
pow
(
l
,
6.0
))
+
(
t
/
40320.0
*
N
*
pow
(
cos
(
phi
),
8.0
)
*
l8coef
*
pow
(
l
,
8.0
));
return
;
}
// MapXYToLatLon
// Converts x and y coordinates in the Transverse Mercator projection to
// a latitude/longitude pair. Note that Transverse Mercator is not
// the same as UTM; a scale factor is required to convert between them.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// x - The easting of the point, in meters.
// y - The northing of the point, in meters.
// lambda0 - Longitude of the central meridian to be used, in radians.
//
// Outputs:
// phi - Latitude in radians.
// lambda - Longitude in radians.
//
// Returns:
// The function does not return a value.
//
// Remarks:
// The local variables Nf, nuf2, tf, and tf2 serve the same purpose as
// N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect
// to the footpoint latitude phif.
//
// x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and
// to optimize computations.
void
MapXYToLatLon
(
double
x
,
double
y
,
double
lambda0
,
double
&
phi
,
double
&
lambda
)
{
double
phif
,
Nf
,
Nfpow
,
nuf2
,
ep2
,
tf
,
tf2
,
tf4
,
cf
;
double
x1frac
,
x2frac
,
x3frac
,
x4frac
,
x5frac
,
x6frac
,
x7frac
,
x8frac
;
double
x2poly
,
x3poly
,
x4poly
,
x5poly
,
x6poly
,
x7poly
,
x8poly
;
/* Get the value of phif, the footpoint latitude. */
phif
=
FootpointLatitude
(
y
);
/* Precalculate ep2 */
ep2
=
(
pow
(
sm_a
,
2.0
)
-
pow
(
sm_b
,
2.0
))
/
pow
(
sm_b
,
2.0
);
/* Precalculate cos (phif) */
cf
=
cos
(
phif
);
/* Precalculate nuf2 */
nuf2
=
ep2
*
pow
(
cf
,
2.0
);
/* Precalculate Nf and initialize Nfpow */
Nf
=
pow
(
sm_a
,
2.0
)
/
(
sm_b
*
sqrt
(
1
+
nuf2
));
Nfpow
=
Nf
;
/* Precalculate tf */
tf
=
tan
(
phif
);
tf2
=
tf
*
tf
;
tf4
=
tf2
*
tf2
;
/* Precalculate fractional coefficients for x**n in the equations
below to simplify the expressions for latitude and longitude. */
x1frac
=
1.0
/
(
Nfpow
*
cf
);
Nfpow
*=
Nf
;
/* now equals Nf**2) */
x2frac
=
tf
/
(
2.0
*
Nfpow
);
Nfpow
*=
Nf
;
/* now equals Nf**3) */
x3frac
=
1.0
/
(
6.0
*
Nfpow
*
cf
);
Nfpow
*=
Nf
;
/* now equals Nf**4) */
x4frac
=
tf
/
(
24.0
*
Nfpow
);
Nfpow
*=
Nf
;
/* now equals Nf**5) */
x5frac
=
1.0
/
(
120.0
*
Nfpow
*
cf
);
Nfpow
*=
Nf
;
/* now equals Nf**6) */
x6frac
=
tf
/
(
720.0
*
Nfpow
);
Nfpow
*=
Nf
;
/* now equals Nf**7) */
x7frac
=
1.0
/
(
5040.0
*
Nfpow
*
cf
);
Nfpow
*=
Nf
;
/* now equals Nf**8) */
x8frac
=
tf
/
(
40320.0
*
Nfpow
);
/* Precalculate polynomial coefficients for x**n.
-- x**1 does not have a polynomial coefficient. */
x2poly
=
-
1.0
-
nuf2
;
x3poly
=
-
1.0
-
2
*
tf2
-
nuf2
;
x4poly
=
5.0
+
3.0
*
tf2
+
6.0
*
nuf2
-
6.0
*
tf2
*
nuf2
-
3.0
*
(
nuf2
*
nuf2
)
-
9.0
*
tf2
*
(
nuf2
*
nuf2
);
x5poly
=
5.0
+
28.0
*
tf2
+
24.0
*
tf4
+
6.0
*
nuf2
+
8.0
*
tf2
*
nuf2
;
x6poly
=
-
61.0
-
90.0
*
tf2
-
45.0
*
tf4
-
107.0
*
nuf2
+
162.0
*
tf2
*
nuf2
;
x7poly
=
-
61.0
-
662.0
*
tf2
-
1320.0
*
tf4
-
720.0
*
(
tf4
*
tf2
);
x8poly
=
1385.0
+
3633.0
*
tf2
+
4095.0
*
tf4
+
1575
*
(
tf4
*
tf2
);
/* Calculate latitude */
phi
=
phif
+
x2frac
*
x2poly
*
(
x
*
x
)
+
x4frac
*
x4poly
*
pow
(
x
,
4.0
)
+
x6frac
*
x6poly
*
pow
(
x
,
6.0
)
+
x8frac
*
x8poly
*
pow
(
x
,
8.0
);
/* Calculate longitude */
lambda
=
lambda0
+
x1frac
*
x
+
x3frac
*
x3poly
*
pow
(
x
,
3.0
)
+
x5frac
*
x5poly
*
pow
(
x
,
5.0
)
+
x7frac
*
x7poly
*
pow
(
x
,
7.0
);
return
;
}
// LatLonToUTMXY
// Converts a latitude/longitude pair to x and y coordinates in the
// Universal Transverse Mercator projection.
//
// Inputs:
// lat - Latitude of the point, in radians.
// lon - Longitude of the point, in radians.
// zone - UTM zone to be used for calculating values for x and y.
// If zone is less than 1 or greater than 60, the routine
// will determine the appropriate zone from the value of lon.
//
// Outputs:
// x - The x coordinate (easting) of the computed point. (in meters)
// y - The y coordinate (northing) of the computed point. (in meters)
//
// Returns:
// The UTM zone used for calculating the values of x and y.
int
LatLonToUTMXY
(
double
lat
,
double
lon
,
int
zone
,
double
&
x
,
double
&
y
)
{
if
(
(
zone
<
1
)
||
(
zone
>
60
)
)
zone
=
floor
((
lon
+
180.0
)
/
6
)
+
1
;
MapLatLonToXY
(
DegToRad
(
lat
),
DegToRad
(
lon
),
UTMCentralMeridian
(
zone
),
x
,
y
);
/* Adjust easting and northing for UTM system. */
x
=
x
*
UTMScaleFactor
+
500000.0
;
y
=
y
*
UTMScaleFactor
;
if
(
y
<
0.0
)
y
=
y
+
10000000.0
;
return
zone
;
}
// UTMXYToLatLon
//
// Converts x and y coordinates in the Universal Transverse Mercator
// projection to a latitude/longitude pair.
//
// Inputs:
// x - The easting of the point, in meters.
// y - The northing of the point, in meters.
// zone - The UTM zone in which the point lies.
// southhemi - True if the point is in the southern hemisphere;
// false otherwise.
//
// Outputs:
// lat - The latitude of the point, in radians.
// lon - The longitude of the point, in radians.
//
// Returns:
// The function does not return a value.
void
UTMXYToLatLon
(
double
x
,
double
y
,
int
zone
,
bool
southhemi
,
double
&
lat
,
double
&
lon
)
{
double
cmeridian
;
x
-=
500000.0
;
x
/=
UTMScaleFactor
;
/* If in southern hemisphere, adjust y accordingly. */
if
(
southhemi
)
y
-=
10000000.0
;
y
/=
UTMScaleFactor
;
cmeridian
=
UTMCentralMeridian
(
zone
);
MapXYToLatLon
(
x
,
y
,
cmeridian
,
lat
,
lon
);
return
;
}
src/Geo/UTM.h
deleted
100644 → 0
View file @
1ee854e1
// UTM.h
// Original Javascript by Chuck Taylor
// Port to C++ by Alex Hajnal
//
// This is a simple port of the code on the Geographic/UTM Coordinate Converter (1) page from Javascript to C++.
// Using this you can easily convert between UTM and WGS84 (latitude and longitude).
// Accuracy seems to be around 50cm (I suspect rounding errors are limiting precision).
// This code is provided as-is and has been minimally tested; enjoy but use at your own risk!
// The license for UTM.cpp and UTM.h is the same as the original Javascript:
// "The C++ source code in UTM.cpp and UTM.h may be copied and reused without restriction."
//
// 1) http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
// QGC Note: This file has been slightly modified to prevent possible conflicts with other parts of the system
#ifndef UTM_H
#define UTM_H
// DegToRad
// Converts degrees to radians.
double
DegToRad
(
double
deg
);
// RadToDeg
// Converts radians to degrees.
double
RadToDeg
(
double
rad
);
// ArcLengthOfMeridian
// Computes the ellipsoidal distance from the equator to a point at a
// given latitude.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// phi - Latitude of the point, in radians.
//
// Globals:
// sm_a - Ellipsoid model major axis.
// sm_b - Ellipsoid model minor axis.
//
// Returns:
// The ellipsoidal distance of the point from the equator, in meters.
double
ArcLengthOfMeridian
(
double
phi
);
// UTMCentralMeridian
// Determines the central meridian for the given UTM zone.
//
// Inputs:
// zone - An integer value designating the UTM zone, range [1,60].
//
// Returns:
// The central meridian for the given UTM zone, in radians
// Range of the central meridian is the radian equivalent of [-177,+177].
double
UTMCentralMeridian
(
int
zone
);
// FootpointLatitude
//
// Computes the footpoint latitude for use in converting transverse
// Mercator coordinates to ellipsoidal coordinates.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// y - The UTM northing coordinate, in meters.
//
// Returns:
// The footpoint latitude, in radians.
double
FootpointLatitude
(
double
y
);
// MapLatLonToXY
// Converts a latitude/longitude pair to x and y coordinates in the
// Transverse Mercator projection. Note that Transverse Mercator is not
// the same as UTM; a scale factor is required to convert between them.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// phi - Latitude of the point, in radians.
// lambda - Longitude of the point, in radians.
// lambda0 - Longitude of the central meridian to be used, in radians.
//
// Outputs:
// x - The x coordinate of the computed point.
// y - The y coordinate of the computed point.
//
// Returns:
// The function does not return a value.
void
MapLatLonToXY
(
double
phi
,
double
lambda
,
double
lambda0
,
double
&
x
,
double
&
y
);
// MapXYToLatLon
// Converts x and y coordinates in the Transverse Mercator projection to
// a latitude/longitude pair. Note that Transverse Mercator is not
// the same as UTM; a scale factor is required to convert between them.
//
// Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
// GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
//
// Inputs:
// x - The easting of the point, in meters.
// y - The northing of the point, in meters.
// lambda0 - Longitude of the central meridian to be used, in radians.
//
// Outputs:
// phi - Latitude in radians.
// lambda - Longitude in radians.
//
// Returns:
// The function does not return a value.
//
// Remarks:
// The local variables Nf, nuf2, tf, and tf2 serve the same purpose as
// N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect
// to the footpoint latitude phif.
//
// x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and
// to optimize computations.
void
MapXYToLatLon
(
double
x
,
double
y
,
double
lambda0
,
double
&
phi
,
double
&
lambda
);
// LatLonToUTMXY
// Converts a latitude/longitude pair to x and y coordinates in the
// Universal Transverse Mercator projection.
//
// Inputs:
// lat - Latitude of the point, in radians.
// lon - Longitude of the point, in radians.
// zone - UTM zone to be used for calculating values for x and y.
// If zone is less than 1 or greater than 60, the routine
// will determine the appropriate zone from the value of lon.
//
// Outputs:
// x - The x coordinate (easting) of the computed point. (in meters)
// y - The y coordinate (northing) of the computed point. (in meters)
//
// Returns:
// The UTM zone used for calculating the values of x and y.
int
LatLonToUTMXY
(
double
lat
,
double
lon
,
int
zone
,
double
&
x
,
double
&
y
);
// UTMXYToLatLon
//
// Converts x and y coordinates in the Universal Transverse Mercator// The UTM zone parameter should be in the range [1,60].
// projection to a latitude/longitude pair.
//
// Inputs:
// x - The easting of the point, in meters.
// y - The northing of the point, in meters.
// zone - The UTM zone in which the point lies.
// southhemi - True if the point is in the southern hemisphere;
// false otherwise.
//
// Outputs:
// lat - The latitude of the point, in radians.
// lon - The longitude of the point, in radians.
//
// Returns:
// The function does not return a value.
void
UTMXYToLatLon
(
double
x
,
double
y
,
int
zone
,
bool
southhemi
,
double
&
lat
,
double
&
lon
);
#endif
src/SHPFileHelper.cc
View file @
57962f3a
...
...
@@ -8,7 +8,7 @@
****************************************************************************/
#include "SHPFileHelper.h"
#include "
UTM
.h"
#include "
QGCGeo
.h"
#include <QFile>
#include <QVariant>
...
...
@@ -141,14 +141,14 @@ bool SHPFileHelper::loadPolygonFromFile(const QString& shpFile, QList<QGeoCoordi
}
for
(
int
i
=
0
;
i
<
shpObject
->
nVertices
;
i
++
)
{
double
lat
,
lon
;
QGeoCoordinate
coord
;
if
(
utmZone
)
{
UTMXYToLatLon
(
shpObject
->
padfX
[
i
],
shpObject
->
padfY
[
i
],
utmZone
,
utmSouthernHemisphere
,
lat
,
lon
);
convertUTMToGeo
(
shpObject
->
padfX
[
i
],
shpObject
->
padfY
[
i
],
utmZone
,
utmSouthernHemisphere
,
coord
);
}
else
{
lat
=
shpObject
->
padfY
[
i
]
;
lon
=
shpObject
->
padfX
[
i
]
;
coord
.
setLatitude
(
shpObject
->
padfY
[
i
])
;
coord
.
setLongitude
(
shpObject
->
padfX
[
i
])
;
}
vertices
.
append
(
QGeoCoordinate
(
lat
,
lon
)
);
vertices
.
append
(
coord
);
}
// Filter last vertex such that it differs from first
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment