The simplest way to transform coordinates in Python is pyproj, i.e. the Python interface to PROJ.4 library. In fact:
from pyproj import Proj, transform
inProj = Proj(init='epsg:3857')
outProj = Proj(init='epsg:4326')
x1,y1 = -11705274.6374,4826473.6922
x2,y2 = transform(inProj,outProj,x1,y1)
print x2,y2
returns -105.150271116 39.7278572773
EDIT based on Marc's comment:
pyproj 2.4 gives a FutureWarning about deprecated Proj
initialization with the init=
syntax. The updated syntax is identical but without the init=
.
Like this:
inProj = Proj('epsg:3857')
outProj = Proj('epsg:4326')
Here is a test(seems both methods work with same precision):
import math
import pyproj
coords = [
(37.4001100556, -79.1539111111, 208.38),
(37.3996955278, -79.153841, 208.48),
(37.3992233889, -79.15425175, 208.18),
(37.3989114167, -79.1532775833, 208.48),
(37.3993285556, -79.1533773333, 208.28),
(37.3992801667, -79.1537883611, 208.38),
(37.3992441111, -79.1540981944, 208.48),
(37.3992616389, -79.1539428889, 208.58),
(37.3993530278, -79.1531711944, 208.28),
(37.4001223889, -79.1538085556, 208.38),
(37.3992922222, -79.15368575, 208.28),
(37.3998074167, -79.1529132222, 208.18),
(37.400068, -79.1542711389, 208.48),
(37.3997516389, -79.1533794444, 208.38),
(37.3988933333, -79.1534320556, 208.38),
(37.3996279444, -79.154401, 208.58),
]
def gps_to_ecef_pyproj(lat, lon, alt):
ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
x, y, z = pyproj.transform(lla, ecef, lon, lat, alt, radians=False)
return x, y, z
def gps_to_ecef_custom(lat, lon, alt):
rad_lat = lat * (math.pi / 180.0)
rad_lon = lon * (math.pi / 180.0)
a = 6378137.0
finv = 298.257223563
f = 1 / finv
e2 = 1 - (1 - f) * (1 - f)
v = a / math.sqrt(1 - e2 * math.sin(rad_lat) * math.sin(rad_lat))
x = (v + alt) * math.cos(rad_lat) * math.cos(rad_lon)
y = (v + alt) * math.cos(rad_lat) * math.sin(rad_lon)
z = (v * (1 - e2) + alt) * math.sin(rad_lat)
return x, y, z
def run_test():
for pt in coords:
print('pyproj', gps_to_ecef_pyproj(pt[0], pt[1], pt[2]))
print('custom', gps_to_ecef_custom(pt[0], pt[1], pt[2]))
run_test()
Best Answer
Probably because in
a
lat
of-113.2179781
is outside the valid bounds of -90 to 90.