forked from kartverket/kivyMaps
-
Notifications
You must be signed in to change notification settings - Fork 4
/
projections.py
78 lines (61 loc) · 2.59 KB
/
projections.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
try:
from pyproj import Proj, transform
### utility methods for projection - pyproj support ########################################
pLatlon = Proj(init='epsg:4326')
p32633 = Proj(init='epsg:32633')
pGoogle = Proj(init='epsg:3857')
def project_to_unit(proj, x, y):
'''Projects any coordinate system to a bent mercator unit square.'''
lon, lat = transform(proj, pLatlon, x, y)
return latlon_to_unit(lat, lon)
def unit_to_project(proj, x, y):
'''Unprojects unit square to any coordinate system.'''
lat, lon = unit_to_latlon(x,y)
return transform(pLatlon, proj, lon, lat)
#############################################################################################
except ImportError:
pass
from math import pi, sin, cos, atan2, sqrt, radians, log, atan, exp, tan
### utility methods for projection ############################################################
def latlon_to_unit(lat, lon):
'''Projects the given lat/lon to bent mercator image
coordinates [-1,1] x [-1,1]. (as defined by Google)
'''
return (lon / 180.0, log(tan(pi / 4.0 + (lat * pi / 180.0) / 2.0)) / pi) #exact calculation
def unit_to_latlon(x, y):
'''Unprojects the given bent mercator image coordinates [-1,1] x [-1,1] to
the lat/lon space.
'''
return ((2 * atan(exp(y * pi)) - pi / 2) * 180.0 / pi, x * 180)
def p4326_to_unit(lon, lat):
return lon / 180.0, lat / 90.0
def unit_to_p4326(x, y):
return x * 180.0, y * 90.0
GCONST = 20037508.342789244
def latlon_to_google(lat, lon):
x,y = latlon_to_unit(lat, lon)
return x*GCONST, y*GCONST
def google_to_latlon(x, y):
return unit_to_latlon(x / GCONST, y / GCONST)
def unit_to_custom(x, y, bounds):
ulx, uly, orx, ory = bounds
dx, dy = orx-ulx, ory-uly
return ulx + (x + 1.0) / 2.0 * dx , uly + (y + 1.0) / 2.0 * dy
def custom_to_unit(x, y, bounds):
ulx, uly, orx, ory = bounds
dx, dy = orx-ulx, ory-uly
return (x - ulx) * 2.0 / dx - 1.0, (y-uly) * 2.0 / dy - 1.0
# !NOTE! These method map the given local bounds to a global lat/lon system. This is not a proper reprojection.
# While the overlays operate within the bounds, the map itself believes to operate in WGS84.
def latlon_to_custom(lat, lon, bounds):
ux, uy = latlon_to_unit(lat, lon)
x, y = unit_to_custom(ux, uy, bounds)
return x,y
def custom_to_latlon(x, y, bounds):
u, v = custom_to_unit(x, y, bounds)
l, m = unit_to_latlon(u, v)
return l, m
###############################################################################################
def fix180(x):
'''wrap all coordinates into [-180;180]'''
return ((x + 180) % 360) - 180