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,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
|