Module: SmoWgs84ToBng::BngToWgs84
- Includes:
- Constants
- Defined in:
- lib/smo_wgs84_to_bng/bng_to_wgs84.rb
Constant Summary
Constants included from Constants
Constants::AIRY_A, Constants::AIRY_B, Constants::AIRY_E2, Constants::NG_E0, Constants::NG_F0, Constants::NG_LAT0, Constants::NG_LON0, Constants::NG_N0, Constants::RX, Constants::RY, Constants::RZ, Constants::S, Constants::TX, Constants::TY, Constants::TZ, Constants::WGS84_A, Constants::WGS84_B, Constants::WGS84_E2
Class Method Summary collapse
-
.convert(easting, northing) ⇒ Object
Convert BNG easting/northing (metres) to WGS84 lat/lon (degrees).
- .ng_to_latlon(easting, northing) ⇒ Object
Class Method Details
.convert(easting, northing) ⇒ Object
Convert BNG easting/northing (metres) to WGS84 lat/lon (degrees). Returns [lat, lon] rounded to 7 decimal places.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/smo_wgs84_to_bng/bng_to_wgs84.rb', line 9 def convert(easting, northing) # Step 1: National Grid -> OSGB36 lat/lon lat2, lon2 = ng_to_latlon(easting, northing) # Step 2: OSGB36 lat/lon -> OSGB36 cartesian x, y, z = Wgs84ToBng.latlon_to_cartesian(lat2, lon2, AIRY_A, AIRY_E2) # Step 3: Inverse Helmert OSGB36 -> WGS84 (negate all params) xw, yw, zw = Wgs84ToBng.helmert(x, y, z, -TX, -TY, -TZ, -RX, -RY, -RZ, -S) # Step 4: WGS84 cartesian -> WGS84 lat/lon lat, lon = Wgs84ToBng.cartesian_to_latlon(xw, yw, zw, WGS84_A, WGS84_B, WGS84_E2) lat_deg = (lat * 180.0 / Math::PI).round(7) lon_deg = (lon * 180.0 / Math::PI).round(7) [lat_deg, lon_deg] end |
.ng_to_latlon(easting, northing) ⇒ Object
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 79 |
# File 'lib/smo_wgs84_to_bng/bng_to_wgs84.rb', line 31 def ng_to_latlon(easting, northing) a = AIRY_A b = AIRY_B f0 = NG_F0 lat0 = NG_LAT0 lon0 = NG_LON0 e0 = NG_E0 n0 = NG_N0 e2 = AIRY_E2 n = (a - b) / (a + b) # Iterative solution for latitude from northing lat = lat0 m = 0.0 10.times do lat = (northing - n0 - m) / (a * f0) + lat m = Wgs84ToBng.meridional_arc(b, f0, n, lat0, lat) break if (northing - n0 - m).abs < 0.00001 end sin_lat = Math.sin(lat) cos_lat = Math.cos(lat) tan_lat = Math.tan(lat) nu = a * f0 / Math.sqrt(1 - e2 * sin_lat**2) rho = a * f0 * (1 - e2) / (1 - e2 * sin_lat**2)**1.5 eta2 = nu / rho - 1 tan2 = tan_lat**2 tan4 = tan_lat**4 sec_lat = 1.0 / cos_lat vii = tan_lat / (2 * rho * nu) viii = tan_lat / (24 * rho * nu**3) * (5 + 3 * tan2 + eta2 - 9 * tan2 * eta2) ix = tan_lat / (720 * rho * nu**5) * (61 + 90 * tan2 + 45 * tan4) x_c = sec_lat / nu xi = sec_lat / (6 * nu**3) * (nu / rho + 2 * tan2) xii = sec_lat / (120 * nu**5) * (5 + 28 * tan2 + 24 * tan4) xiia = sec_lat / (5040 * nu**7) * (61 + 662 * tan2 + 1320 * tan4 + 720 * tan_lat**6) de = easting - e0 lat_out = lat - vii * de**2 + viii * de**4 - ix * de**6 lon_out = lon0 + x_c * de - xi * de**3 + xii * de**5 - xiia * de**7 [lat_out, lon_out] end |