Class: DefraRuby::Address::HelmertTransformation

Inherits:
Object
  • Object
show all
Defined in:
lib/defra_ruby/address/helmert_transformation.rb

Overview

Shifts latitude/longitude between the OSGB36 and WGS84 datums using the 7-parameter Helmert transformation from the OS guide "A guide to coordinate systems in Great Britain". Accurate to around 5 metres.

The OSGB36 to WGS84 direction is ported from the breasal gem (https://github.com/theodi/breasal, MIT licence, copyright 2013 pezholio), corrected to the published OS guide parameters. The reverse direction just negates them.

Constant Summary collapse

AIRY_1830 =
{ a: 6_377_563.396, b: 6_356_256.909 }.freeze
WGS84 =
{ a: 6_378_137.0, b: 6_356_752.3141 }.freeze
ARC_SECOND_IN_RADIANS =
Math::PI / 648_000
PARAMETERS =

Translations (tx, ty, tz) in metres, scale change (s) in parts per unit and rotations (rx, ry, rz) in radians, for the OSGB36 to WGS84 direction; negated they transform in the opposite direction.

{
  tx: 446.448,
  ty: -125.157,
  tz: 542.060,
  s: -0.0000204894,
  rx: 0.1502 * ARC_SECOND_IN_RADIANS,
  ry: 0.2470 * ARC_SECOND_IN_RADIANS,
  rz: 0.8421 * ARC_SECOND_IN_RADIANS
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_ellipsoid, target_ellipsoid, direction) ⇒ HelmertTransformation

Returns a new instance of HelmertTransformation.



40
41
42
43
44
# File 'lib/defra_ruby/address/helmert_transformation.rb', line 40

def initialize(source_ellipsoid, target_ellipsoid, direction)
  @source_ellipsoid = source_ellipsoid
  @target_ellipsoid = target_ellipsoid
  @direction = direction
end

Class Method Details

.osgb36_to_wgs84(latitude, longitude) ⇒ Object



32
33
34
# File 'lib/defra_ruby/address/helmert_transformation.rb', line 32

def self.osgb36_to_wgs84(latitude, longitude)
  new(AIRY_1830, WGS84, 1).transform(latitude, longitude)
end

.wgs84_to_osgb36(latitude, longitude) ⇒ Object



36
37
38
# File 'lib/defra_ruby/address/helmert_transformation.rb', line 36

def self.wgs84_to_osgb36(latitude, longitude)
  new(WGS84, AIRY_1830, -1).transform(latitude, longitude)
end

Instance Method Details

#transform(latitude, longitude) ⇒ Object



46
47
48
# File 'lib/defra_ruby/address/helmert_transformation.rb', line 46

def transform(latitude, longitude)
  to_geodetic(apply_helmert(to_cartesian(latitude, longitude)))
end