class Geocoder::EastingNorthing
def cos_pow_2(x)
def cos_pow_2(x) Math.cos(x) * Math.cos(x) end
def deg_to_rad(degrees)
def deg_to_rad(degrees) degrees / 180.0 * Math::PI end
def initialize(opts)
def initialize(opts) @easting = opts[:easting] @northing = opts[:northing] @lat_lng = to_WGS84(to_osgb_36) end
def rad_to_deg(r)
def rad_to_deg(r) (r / Math::PI) * 180 end
def sec(x)
def sec(x) 1.0 / Math.cos(x) end
def sin_pow_2(x)
def sin_pow_2(x) Math.sin(x) * Math.sin(x) end
def tan_pow_2(x)
def tan_pow_2(x) Math.tan(x) * Math.tan(x) end
def to_WGS84(latlng)
def to_WGS84(latlng) latitude = latlng[0] longitude = latlng[1] a = 6_377_563.396 b = 6_356_256.909 eSquared = ((a * a) - (b * b)) / (a * a) phi = deg_to_rad(latitude) lambda = deg_to_rad(longitude) v = a / Math.sqrt(1 - eSquared * sin_pow_2(phi)) h = 0 x = (v + h) * Math.cos(phi) * Math.cos(lambda) y = (v + h) * Math.cos(phi) * Math.sin(lambda) z = ((1 - eSquared) * v + h) * Math.sin(phi) tx = 446.448 ty = -124.157 tz = 542.060 s = -0.0000204894 rx = deg_to_rad(0.00004172222) ry = deg_to_rad(0.00006861111) rz = deg_to_rad(0.00023391666) xB = tx + (x * (1 + s)) + (-rx * y) + (ry * z) yB = ty + (rz * x) + (y * (1 + s)) + (-rx * z) zB = tz + (-ry * x) + (rx * y) + (z * (1 + s)) a = 6_378_137.000 b = 6_356_752.3141 eSquared = ((a * a) - (b * b)) / (a * a) lambdaB = rad_to_deg(Math.atan(yB / xB)) p = Math.sqrt((xB * xB) + (yB * yB)) phiN = Math.atan(zB / (p * (1 - eSquared))) (1..10).each do |_i| v = a / Math.sqrt(1 - eSquared * sin_pow_2(phiN)) phiN1 = Math.atan((zB + (eSquared * v * Math.sin(phiN))) / p) phiN = phiN1 end phiB = rad_to_deg(phiN) [phiB, lambdaB] end
def to_osgb_36
def to_osgb_36 osgb_fo = 0.9996012717 northing0 = -100_000.0 easting0 = 400_000.0 phi0 = deg_to_rad(49.0) lambda0 = deg_to_rad(-2.0) a = 6_377_563.396 b = 6_356_256.909 eSquared = ((a * a) - (b * b)) / (a * a) phi = 0.0 lambda = 0.0 n = (a - b) / (a + b) m = 0.0 phiPrime = ((northing - northing0) / (a * osgb_fo)) + phi0 while (northing - northing0 - m) >= 0.001 m = (b * osgb_fo)\ * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))\ * (phiPrime - phi0))\ - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))\ * Math.sin(phiPrime - phi0)\ * Math.cos(phiPrime + phi0))\ + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))\ * Math.sin(2.0 * (phiPrime - phi0))\ * Math.cos(2.0 * (phiPrime + phi0)))\ - (((35.0 / 24.0) * n * n * n)\ * Math.sin(3.0 * (phiPrime - phi0))\ * Math.cos(3.0 * (phiPrime + phi0)))) phiPrime += (northing - northing0 - m) / (a * osgb_fo) end v = a * osgb_fo * ((1.0 - eSquared * sin_pow_2(phiPrime))**-0.5) rho = a\ * osgb_fo\ * (1.0 - eSquared)\ * ((1.0 - eSquared * sin_pow_2(phiPrime))**-1.5) etaSquared = (v / rho) - 1.0 vii = Math.tan(phiPrime) / (2 * rho * v) viii = (Math.tan(phiPrime) / (24.0 * rho * (v**3.0)))\ * (5.0\ + (3.0 * tan_pow_2(phiPrime))\ + etaSquared\ - (9.0 * tan_pow_2(phiPrime) * etaSquared)) ix = (Math.tan(phiPrime) / (720.0 * rho * (v**5.0)))\ * (61.0\ + (90.0 * tan_pow_2(phiPrime))\ + (45.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime))) x = sec(phiPrime) / v xi = (sec(phiPrime) / (6.0 * v * v * v))\ * ((v / rho) + (2 * tan_pow_2(phiPrime))) xiii = (sec(phiPrime) / (120.0 * (v**5.0)))\ * (5.0\ + (28.0 * tan_pow_2(phiPrime))\ + (24.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime))) xiia = (sec(phiPrime) / (5040.0 * (v**7.0)))\ * (61.0\ + (662.0 * tan_pow_2(phiPrime))\ + (1320.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime))\ + (720.0\ * tan_pow_2(phiPrime)\ * tan_pow_2(phiPrime)\ * tan_pow_2(phiPrime))) phi = phiPrime\ - (vii * ((easting - easting0)**2.0))\ + (viii * ((easting - easting0)**4.0))\ - (ix * ((easting - easting0)**6.0)) lambda = lambda0\ + (x * (easting - easting0))\ - (xi * ((easting - easting0)**3.0))\ + (xiii * ((easting - easting0)**5.0))\ - (xiia * ((easting - easting0)**7.0)) [rad_to_deg(phi), rad_to_deg(lambda)] end