Source code for towerpy.georad.coordinate_transformation_tool

"""Towerpy: an open-source toolbox for processing polarimetric radar data."""

import math


[docs] class Coords_TT: """A class to work with the coordinate systems used in Great Britain.""" def __init__(self, ellipsoid, projection):
[docs] self.ellipsoid = ellipsoid
[docs] self.projection = projection
# Shape and size of biaxial ellipsoids used in the UK if ellipsoid == 'Airy_1830' or self.ellipsoid is None: ellipsoid_info = {'a [m]': 6377563.396, 'b [m]': 6356256.9091} if ellipsoid == 'Airy_1830_modified': ellipsoid_info = {'a [m]': 6377340.189, 'b [m]': 6356034.447} if ellipsoid == 'WGS84': ellipsoid_info = {'a [m]': 6378137, 'b [m]': 6356752.3141} # Transverse Mercator projections used in the UK if projection == 'OSGB' or projection is None: projection_info = {'N0': -100000, 'E0': 400000, 'F0': 0.9996012717, 'phi0': math.radians(49), 'lambda0': math.radians(-2)}
[docs] self.ellipsoid_info = ellipsoid_info
[docs] self.projection_info = projection_info
[docs] def param_M(self, phi, a, b): """ Return the parameter M for latitude phi using ellipsoid params a, b. Parameters ---------- phi : TYPE DESCRIPTION. a : TYPE DESCRIPTION. b : TYPE DESCRIPTION. Returns ------- M : TYPE DESCRIPTION. """ n = (a-b)/(a+b) n2 = n**2 n3 = n * n2 dphi = phi - self.projection_info['phi0'] sphi = phi + self.projection_info['phi0'] M = b * self.projection_info['F0'] * ( (1 + n + 5/4 * (n2+n3)) * dphi - (3*n + 3*n2 + 21/8 * n3) * math.sin(dphi) * math.cos(sphi) + (15/8 * (n2 + n3)) * math.sin(2*dphi) * math.cos(2*sphi) - (35/24 * n3 * math.sin(3*dphi) * math.cos(3*sphi)) ) return M
[docs] def aux_params(phi, a, F0, e2): """ Calculate and return the parameters rho, nu, and eta2. Parameters ---------- phi : TYPE DESCRIPTION. a : TYPE DESCRIPTION. F0 : TYPE DESCRIPTION. e2 : TYPE DESCRIPTION. Returns ------- rho : TYPE DESCRIPTION. nu : TYPE DESCRIPTION. eta2 : TYPE DESCRIPTION. """ rho = a * F0 * (1-e2) * (1-e2*math.sin(phi)**2)**-1.5 nu = a * F0 / math.sqrt(1-e2*math.sin(phi)**2) eta2 = nu/rho - 1 return rho, nu, eta2
[docs] def osgb2lalo(self, E, N): """ Convert from OS grid reference to latitude and longitude. Parameters ---------- E : TYPE DESCRIPTION. N : TYPE DESCRIPTION. Returns ------- None. """ a, b = self.ellipsoid_info['a [m]'], self.ellipsoid_info['b [m]'] e2 = (a**2 - b**2)/a**2 M, phip = 0, self.projection_info['phi0'] while abs(N-self.projection_info['N0']-M) >= 1.e-5: phip = (N - self.projection_info['N0'] - M)/(a*self.projection_info['F0']) + phip M = Coords_TT.param_M(self, phip, a, b) rho, nu, eta2 = Coords_TT.aux_params(phip, a, self.projection_info['F0'], e2) tan_phip = math.tan(phip) tan_phip2 = tan_phip**2 nu3, nu5 = nu**3, nu**5 sec_phip = 1./math.cos(phip) c1 = tan_phip/2/rho/nu c2 = tan_phip/24/rho/nu3 * (5 + 3*tan_phip2 + eta2 * (1 - 9*tan_phip2)) c3 = tan_phip / 720/rho/nu5 * (61 + tan_phip2*(90 + 45 * tan_phip2)) d1 = sec_phip / nu d2 = sec_phip / 6 / nu3 * (nu/rho + 2*tan_phip2) d3 = sec_phip / 120 / nu5 * (5 + tan_phip2*(28 + 24*tan_phip2)) d4 = sec_phip / 5040 / nu**7 * (61 + tan_phip2*(662 + tan_phip2 * (1320 + tan_phip2*720))) EmE0 = E - self.projection_info['E0'] EmE02 = EmE0**2 phi = phip + EmE0**2 * (-c1 + EmE02*(c2 - c3*EmE02)) lam = self.projection_info['lambda0'] + EmE0 * (d1 + EmE02*(-d2 + EmE02*(d3 - d4*EmE02))) self.latitude = math.degrees(phi) self.longitude = math.degrees(lam) self.easting = E self.northing = N
[docs] def lalo2osgb(self, lat, long): """ Convert from latitude and longitude to OS grid reference (E, N). Parameters ---------- phi : TYPE DESCRIPTION. lam : TYPE DESCRIPTION. Returns ------- None. """ phi = math.radians(lat) lam = math.radians(long) a, b = self.ellipsoid_info['a [m]'], self.ellipsoid_info['b [m]'] e2 = (a**2 - b**2)/a**2 rho, nu, eta2 = Coords_TT.aux_params(phi, a, self.projection_info['F0'], e2) M = Coords_TT.param_M(self, phi, a, b) sin_phi = math.sin(phi) cos_phi = math.cos(phi) cos_phi2 = cos_phi**2 cos_phi3 = cos_phi2 * cos_phi cos_phi5 = cos_phi3 * cos_phi2 tan_phi2 = math.tan(phi)**2 tan_phi4 = tan_phi2 * tan_phi2 a1 = M + self.projection_info['N0'] a2 = nu/2 * sin_phi * cos_phi a3 = nu/24 * sin_phi * cos_phi3 * (5 - tan_phi2 + 9*eta2) a4 = nu/720 * sin_phi * cos_phi5 * (61 - 58*tan_phi2 + tan_phi4) b1 = nu * cos_phi b2 = nu/6 * cos_phi3 * (nu/rho - tan_phi2) b3 = nu/120 * cos_phi5 * (5 - 18*tan_phi2 + tan_phi4 + eta2*(14 - 58*tan_phi2)) lml0 = lam - self.projection_info['lambda0'] lml02 = lml0**2 N = a1 + lml02 * (a2 + lml02*(a3 + a4*lml02)) E = self.projection_info['E0'] + lml0 * (b1 + lml02*(b2 + b3*lml02)) self.latitude = lat self.longitude = long self.easting = E self.northing = N