ordnance_survey_vs_the_world 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ module OrdnanceSurveyVsTheWorld
2
+ VERSION = '1.0.0'
3
+ end
4
+
5
+ require 'ordnance_survey_vs_the_world/os_grid_ref'
@@ -0,0 +1,4 @@
1
+ module OrdnanceSurveyVsTheWorld
2
+ class LatLon < Struct.new(:lat, :lon)
3
+ end
4
+ end
@@ -0,0 +1,102 @@
1
+ # Extracted from code by Chris Veness, who kindly published it under
2
+ # the CC-BY license (http://creativecommons.org/licenses/by/3.0/) with
3
+ # the request that the below copyright notice is retained.
4
+ #
5
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6
+ # ordnance survey grid reference functions (c) chris veness 2005-2012
7
+ # - www.movable-type.co.uk/scripts/gridref.js
8
+ # - www.movable-type.co.uk/scripts/latlon-gridref.html
9
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10
+
11
+ require 'ordnance_survey_vs_the_world/lat_lon'
12
+
13
+ module OrdnanceSurveyVsTheWorld
14
+ class OsGridRef
15
+ # Airy 1830 major & minor semi-axes
16
+ A = 6377563.396
17
+ B = 6356256.910
18
+
19
+ # eccentricity squared
20
+ E2 = 1 - (B*B)/(A*A)
21
+ N = (A-B)/(A+B)
22
+ N2 = N*N
23
+ N3 = N*N*N
24
+
25
+ # NatGrid scale factor on central meridian
26
+ F0 = 0.9996012717
27
+
28
+ # NatGrid true origin
29
+ LAT_0 = 49*Math::PI/180
30
+ LON_0 = -2*Math::PI/180
31
+
32
+ # Northing & easting of true origin, metres
33
+ N0 = -100000
34
+ E0 = 400000
35
+
36
+ def initialize(easting, northing)
37
+ @easting = easting
38
+ @northing = northing
39
+ end
40
+
41
+ def to_latlon
42
+ lat = airy1830_latitude
43
+
44
+ cosLat = Math.cos(lat)
45
+ sinLat = Math.sin(lat)
46
+ nu = A*F0/Math.sqrt(1-E2*sinLat*sinLat) # transverse radius of curvature
47
+ rho = A*F0*(1-E2)/((1-E2*sinLat*sinLat)**1.5) # meridional radius of curvature
48
+ eta2 = nu/rho-1
49
+
50
+ tanLat = Math.tan(lat)
51
+ tan2lat = tanLat*tanLat
52
+ tan4lat = tan2lat*tan2lat
53
+ tan6lat = tan4lat*tan2lat
54
+ secLat = 1/cosLat
55
+ nu3 = nu*nu*nu
56
+ nu5 = nu3*nu*nu
57
+ nu7 = nu5*nu*nu
58
+ vii = tanLat/(2*rho*nu)
59
+ viii = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2)
60
+ ix = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat)
61
+ x = secLat/nu
62
+ xi = secLat/(6*nu3)*(nu/rho+2*tan2lat)
63
+ xii = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat)
64
+ xiia = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat)
65
+
66
+ dE = (@easting-E0)
67
+ dE2 = dE*dE
68
+ dE3 = dE2*dE
69
+ dE4 = dE2*dE2
70
+ dE5 = dE3*dE2
71
+ dE6 = dE4*dE2
72
+ dE7 = dE5*dE2
73
+ lat = lat - vii*dE2 + viii*dE4 - ix*dE6;
74
+ lon = LON_0 + x*dE - xi*dE3 + xii*dE5 - xiia*dE7
75
+
76
+ LatLon.new(rad_to_deg(lat), rad_to_deg(lon));
77
+ end
78
+
79
+ def airy1830_latitude
80
+ lat = LAT_0
81
+ m=0
82
+ begin
83
+ lat = (@northing-N0-m)/(A*F0) + lat
84
+
85
+ ma = (1 + N + (5.to_f/4)*N2 + (5.to_f/4)*N3) * (lat-LAT_0)
86
+ mb = (3*N + 3*N*N + (21.to_f/8)*N3) * Math.sin(lat-LAT_0) * Math.cos(lat+LAT_0)
87
+ mc = ((15.to_f/8)*N2 + (15/8)*N3) * Math.sin(2*(lat-LAT_0)) * Math.cos(2*(lat+LAT_0))
88
+ md = (35.to_f/24)*N3 * Math.sin(3*(lat-LAT_0)) * Math.cos(3*(lat+LAT_0))
89
+ m = B * F0 * (ma - mb + mc - md) # meridional arc
90
+ end while (@northing-N0-m >= 0.00001) # until error is < 0.01mm
91
+
92
+ lat
93
+ end
94
+
95
+ private
96
+
97
+ def rad_to_deg(rad)
98
+ rad * 180 / Math::PI
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,42 @@
1
+ require 'test/unit'
2
+ require 'test/unit/assertions'
3
+ require 'ordnance_survey_vs_the_world'
4
+
5
+ module OrdnanceSurveyVsTheWorld
6
+ class OsGridRefTest < Test::Unit::TestCase
7
+
8
+ def airy_lat(easting, northing)
9
+ OsGridRef.new(easting, northing).airy1830_latitude
10
+ end
11
+
12
+ def test_airy1830_latitude
13
+ assert_in_delta(0.8709117584154843, airy_lat(0, 0), 0.00001)
14
+ assert_in_delta(0.8709117584154843, airy_lat(699999, 0), 0.00001)
15
+ assert_in_delta(1.0748183142194723, airy_lat(0,1299999), 0.00001)
16
+ assert_in_delta(1.0748183142194723, airy_lat(699999,1299999), 0.00001)
17
+ end
18
+
19
+
20
+ def latlon(easting, northing)
21
+ ll = OsGridRef.new(easting, northing).to_latlon
22
+ [ll.lat, ll.lon]
23
+ end
24
+
25
+ def test_to_latlon
26
+ assert_all_in_delta([49.76618579670919, -7.556448482562568], latlon(0, 0), 0.00001)
27
+ assert_all_in_delta([49.82444269457118, 2.171856193294114], latlon(699999, 0), 0.00001)
28
+ assert_all_in_delta([61.37589692662293, -9.49659523009406], latlon(0, 1299999), 0.00001)
29
+ assert_all_in_delta([61.46605926424626, 3.6348831054430324], latlon(699999, 1299999), 0.00001)
30
+
31
+ assert_all_in_delta([51.52485796242662, -0.10882875766639633], latlon(531182,182409), 0.00001)
32
+ end
33
+
34
+
35
+ def assert_all_in_delta(a1, a2, delta)
36
+ a1.each_with_index do |e, i|
37
+ assert_in_delta(e, a2[i], delta)
38
+ end
39
+ end
40
+
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ordnance_survey_vs_the_world
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Pablo Brasero
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-07-29 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Converts from the Bristish Ordnance Survey's own easting/northing OSGB-36 coordinates to WGS-84 latitude/longitude
17
+ email: pablobm@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/ordnance_survey_vs_the_world.rb
26
+ - lib/ordnance_survey_vs_the_world/lat_lon.rb
27
+ - lib/ordnance_survey_vs_the_world/os_grid_ref.rb
28
+ - test/ordnance_survey_vs_the_world/os_grid_ref_test.rb
29
+ homepage: https://github.com/pablobm/ordnance_survey_vs_the_world
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.15
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Convert from easting/northing to latitude/longitude
56
+ test_files:
57
+ - test/ordnance_survey_vs_the_world/os_grid_ref_test.rb