osgb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ 0.2.0 (November 4, 2011)
2
+
3
+ * extracted (and somewhat refactored) from radiant event_map extension
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Ryan Bates
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ = OSGB
2
+
3
+ Wiki[https://github.com/spanner/osgb/wiki] RDocs[http://rdoc.info/projects/spanner/osgb]
4
+
5
+ Osgb is a library that converts between British (and Irish) grid references and latitude and longitude co-ordinates. It is precise to about 5m, which is to say it's good enough for WGS84 and most GPS use but not local enough for surveying to ETRS89.
6
+
7
+ == Installation
8
+
9
+ In <b>Rails 3</b>, add this to your Gemfile and run +bundle install+.
10
+
11
+ gem "osgb"
12
+
13
+ In <b>Rails 2</b>, add this to your environment.rb file.
14
+
15
+ config.gem "osgb"
16
+
17
+ Alternatively, you can install it as a plugin.
18
+
19
+ rails plugin install git://github.com/spanner/osgb.git
20
+
21
+ == Usage
22
+
23
+ You don't need to make any explicit reference to the gem. It adds conversion methods to the String class:
24
+
25
+ "SD12341234".is_gridref? # -> true
26
+ "SD12341234".to_latlng # ->
27
+ "SD12341234".to_WGS84 # ->
28
+ "1.056789, 55.98978607".is_latlng? # -> true
29
+ "1.056789, 55.98978607".to_gridref # -> true
30
+
31
+ and provides some help for your ActiveRecord classes:
32
+
33
+ class Checkpoint < ActiveRecord::Base
34
+ has_gridref :lat => 'lat',
35
+ :lng => 'lng',
36
+ :gridref => 'gridref',
37
+ :validation => false,
38
+ :converstion => true
39
+
40
+ The :lat, :lng and :gridref keys should pass in the names of the relevant columns if they don't match these defaults.
41
+
42
+ == Questions or Problems?
43
+
44
+ If you have any issues with CanCan which you cannot find the solution to in the documentation[https://github.com/ryanb/cancan/wiki], please add an {issue on GitHub}[https://github.com/ryanb/cancan/issues] or fork the project and send a pull request.
45
+
46
+ To get the specs running you should call +bundle+ and then +rake+. See the {spec/README}[https://github.com/ryanb/cancan/blob/master/spec/README.rdoc] for more information.
47
+
48
+
49
+ == Special Thanks
50
+
51
+ CanCan was inspired by declarative_authorization[https://github.com/stffn/declarative_authorization/] and aegis[https://github.com/makandra/aegis]. Also many thanks to the CanCan contributors[https://github.com/ryanb/cancan/contributors]. See the CHANGELOG[https://github.com/ryanb/cancan/blob/master/CHANGELOG.rdoc] for the full list.
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :default => :spec
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'osgb'
@@ -0,0 +1,26 @@
1
+ require 'osgb/angle_conversions' # converts degrees to radians and back again
2
+ require 'osgb/ellipsoid' # standard approximations to the squashed-circle shape of the earth
3
+ require 'osgb/projection' # the geometrical distortions required by a map projection
4
+ require 'osgb/helmert' # 3d transformation algorithm for mapping between cartesian and ellipsoidal polar coordinates
5
+ require 'osgb/gridref' # parse grid references and returns lat/long pairs
6
+ require 'osgb/string_conversions' # add conversion methods to String
7
+ require 'osgb/railtie' if defined? Rails # add useful methods to ActiveRecord
8
+
9
+ # Define standard ellipsoids
10
+
11
+ Osgb::Ellipsoid.new :osgb36, 6377563.396, 6356256.910
12
+ Osgb::Ellipsoid.new :wgs84, 6378137.000, 6356752.3141
13
+ Osgb::Ellipsoid.new :ie65, 6377340.189, 6356034.447
14
+ Osgb::Ellipsoid.new :utm, 6378388.000, 6356911.946
15
+
16
+ # Define standard projections
17
+
18
+ Osgb::Projection.new :gb, :scale => 0.9996012717, :phi0 => 49, :lambda0 => -2, :e0 => 400000, :n0 => -100000, :ellipsoid => :osgb36
19
+ Osgb::Projection.new :ie, :scale => 1.000035, :phi0 => 53.5, :lambda0 => -8, :e0 => 250000, :n0 => 250000, :ellipsoid => :ie65
20
+ Osgb::Projection.new :utm29, :scale => 0.9996, :phi0 => 0, :lambda0 => -9, :e0 => 500000, :n0 => 0, :ellipsoid => :utm
21
+ Osgb::Projection.new :utm30, :scale => 0.9996, :phi0 => 0, :lambda0 => -3, :e0 => 500000, :n0 => 0, :ellipsoid => :utm
22
+ Osgb::Projection.new :utm31, :scale => 0.9996, :phi0 => 0, :lambda0 => 3, :e0 => 500000, :n0 => 0, :ellipsoid => :utm
23
+
24
+ # the Helmert matrix used to translate to wgs84.
25
+
26
+ Osgb::Helmert.new :wgs84, :tx => 446.448, :ty => -125.157, :tz => 542.060, :rx => 0.1502, :ry => 0.2470, :rz => 0.8421, :s => -20.4894
@@ -0,0 +1,9 @@
1
+ class Numeric
2
+ def to_radians # presumes self is a number of degrees
3
+ self * Math::PI / 180
4
+ end
5
+
6
+ def to_degrees # presumes self is a number of radians
7
+ self / (Math::PI / 180)
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ module Osgb
2
+ class Ellipsoid
3
+ attr_accessor :name, :a, :b
4
+ @@instances = {}
5
+
6
+ def initialize(name, a, b)
7
+ @name = name
8
+ @a = a
9
+ @b = b
10
+ @@instances[name] = self
11
+ end
12
+
13
+ def ecc
14
+ (a**2 - b**2) / (a**2)
15
+ end
16
+
17
+ def nu_for(phi)
18
+ a / (Math.sqrt(1 - ecc * Math.sin(phi)**2))
19
+ end
20
+
21
+ def precision
22
+ 4 / a
23
+ end
24
+
25
+ def polar_to_cartesian(phi, lambda)
26
+ h = 0
27
+ nu = nu_for(phi)
28
+ x1 = (nu + h) * Math.cos(phi) * Math.cos(lambda)
29
+ y1 = (nu + h) * Math.cos(phi) * Math.sin(lambda)
30
+ z1 = ((1 - ecc) * nu + h) * Math.sin(phi)
31
+ [x1, y1, z1]
32
+ end
33
+
34
+ def cartesian_to_polar(x,y,z)
35
+ p = Math.sqrt(x**2 + y**2)
36
+ phi = Math.atan2(z, p*(1-ecc));
37
+ phip = 2 * Math::PI
38
+
39
+ count = 0
40
+ while (phi-phip).abs > precision do
41
+ raise RuntimeError "Helmert transformation has not converged. Discrepancy after #{count} cycles is #{phi-phip}" if count >= Osgb::Gridref.iteration_ceiling
42
+ nu = a / Math.sqrt(1 - ecc * Math.sin(phi)**2)
43
+ phip = phi
44
+ phi = Math.atan2(z + ecc * nu * Math.sin(phi), p)
45
+ count += 1
46
+ end
47
+
48
+ lambda = Math.atan2(y, x)
49
+ [phi, lambda]
50
+ end
51
+
52
+ def self.[](name)
53
+ @@instances[name]
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,198 @@
1
+ module Osgb
2
+ # Implementation derived from the Ordnance Survey guide to coordinate systems in the UK
3
+ # http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/
4
+ # with help from CPAN module Geography::NationalGrid by and (c) P Kent
5
+
6
+ class Gridref
7
+ OsTiles = {
8
+ :a => [0,4], :b => [1,4], :c => [2,4], :d => [3,4], :e => [4,4],
9
+ :f => [0,3], :g => [1,3], :h => [2,3], :j => [3,3], :k => [4,3],
10
+ :l => [0,2], :m => [1,2], :n => [2,2], :o => [3,2], :p => [4,2],
11
+ :q => [0,1], :r => [1,1], :s => [2,1], :t => [3,1], :u => [4,1],
12
+ :v => [0,0], :w => [1,0], :x => [2,0], :y => [3,0], :z => [4,0],
13
+ }
14
+ FalseOrigin = {:e => 2, :n => 1}
15
+ SquareSize = [nil, 10000, 1000, 100, 10, 1] # shorter grid ref = larger square.
16
+
17
+ attr_accessor :gridref, :projection, :ellipsoid, :datum, :options, :precision
18
+
19
+ @@iteration_ceiling = 1000
20
+ @@defaults = {
21
+ :projection => :gb, # mercator projection of input gridref. Can be any projection name: usually :ie or :gb
22
+ :precision => 6 # decimal places in the output lat/long
23
+ }
24
+
25
+ class << self
26
+ def iteration_ceiling
27
+ @@iteration_ceiling
28
+ end
29
+ end
30
+
31
+ def initialize(string, options={})
32
+ raise ArgumentError, "invalid grid reference string '#{string}'." unless string.is_gridref?
33
+ options = @@defaults.merge(options)
34
+ @gridref = string.upcase
35
+ @projection = Osgb::Projection[options[:projection]]
36
+ @precision = options[:precision]
37
+ @ellipsoid = @projection.ellipsoid
38
+ @datum = options[:datum]
39
+ self
40
+ end
41
+
42
+ def tile
43
+ @tile ||= gridref[0,2]
44
+ end
45
+
46
+ def digits
47
+ @digits ||= gridref[2,10]
48
+ end
49
+
50
+ def resolution
51
+ digits.length / 2
52
+ end
53
+
54
+ def offsets
55
+ if tile
56
+ major = OsTiles[tile[0,1].downcase.to_sym ]
57
+ minor = OsTiles[tile[1,1].downcase.to_sym]
58
+ @offset ||= {
59
+ :e => (500000 * (major[0] - FalseOrigin[:e])) + (100000 * minor[0]),
60
+ :n => (500000 * (major[1] - FalseOrigin[:n])) + (100000 * minor[1])
61
+ }
62
+ else
63
+ { :e => 0, :n => 0 }
64
+ end
65
+ end
66
+
67
+ def easting
68
+ @east ||= offsets[:e] + digits[0, resolution].to_i * SquareSize[resolution]
69
+ end
70
+
71
+ def northing
72
+ @north ||= offsets[:n] + digits[resolution, resolution].to_i * SquareSize[resolution]
73
+ end
74
+
75
+ def lat
76
+ round(coordinates[:lat].to_degrees)
77
+ end
78
+
79
+ def lng
80
+ round(coordinates[:lng].to_degrees)
81
+ end
82
+
83
+ def round(value)
84
+ if value.method(:round).arity == 0
85
+ multiplier = 10**precision
86
+ (value * multiplier).round.to_f / multiplier
87
+ else
88
+ value.round(precision)
89
+ end
90
+ end
91
+
92
+ def to_s
93
+ gridref.to_s
94
+ end
95
+
96
+ def to_latlng
97
+ [lat, lng]
98
+ end
99
+
100
+ def coordinates
101
+ unless @coordinates
102
+ # variable names correspond roughly to symbols in the OS algorithm, lowercased:
103
+ # n0 = northing of true origin
104
+ # e0 = easting of true origin
105
+ # f0 = scale factor on central meridian
106
+ # phi0 = latitude of true origin
107
+ # lambda0 = longitude of true origin and central meridian.
108
+ # e2 = eccentricity squared
109
+ # a = length of polar axis of ellipsoid
110
+ # b = length of equatorial axis of ellipsoid
111
+ # ning & eing are the northings and eastings of the supplied gridref
112
+ # phi and lambda are the discovered latitude and longitude
113
+
114
+ ning = northing
115
+ eing = easting
116
+
117
+ n0 = projection.n0
118
+ e0 = projection.e0
119
+ phi0 = projection.phi0
120
+ l0 = projection.lambda0
121
+ f0 = projection.scale
122
+
123
+ a = ellipsoid.a
124
+ b = ellipsoid.b
125
+ e2 = ellipsoid.ecc
126
+
127
+ # the rest is juste a transliteration of the OS equations
128
+
129
+ n = (a - b) / (a + b)
130
+ m = 0
131
+ phi = phi0
132
+
133
+ # iterate to within acceptable distance of solution
134
+
135
+ count = 0
136
+ while ((ning - n0 - m) >= 0.001) do
137
+ raise RuntimeError "Demercatorising equation has not converged. Discrepancy after #{count} cycles is #{ning - n0 - m}" if count >= @@iteration_ceiling
138
+
139
+ phi = ((ning - n0 - m) / (a * f0)) + phi
140
+ ma = (1 + n + (1.25 * n**2) + (1.25 * n**3)) * (phi - phi0)
141
+ mb = ((3 * n) + (3 * n**2) + (2.625 * n**3)) * Math.sin(phi - phi0) * Math.cos(phi + phi0)
142
+ mc = ((1.875 * n**2) + (1.875 * n**3)) * Math.sin(2 * (phi - phi0)) * Math.cos(2 * (phi + phi0))
143
+ md = (35/24) * (n**3) * Math.sin(3 * (phi - phi0)) * Math.cos(3 * (phi + phi0))
144
+ m = b * f0 * (ma - mb + mc - md)
145
+ count += 1
146
+ end
147
+
148
+ # engage alphabet soup
149
+
150
+ nu = a * f0 * ((1-(e2) * ((Math.sin(phi)**2))) ** -0.5)
151
+ rho = a * f0 * (1-(e2)) * ((1-(e2)*((Math.sin(phi)**2))) ** -1.5)
152
+ eta2 = (nu/rho - 1)
153
+
154
+ # fire
155
+
156
+ vii = Math.tan(phi) / (2 * rho * nu)
157
+ viii = (Math.tan(phi) / (24 * rho * (nu ** 3))) * (5 + (3 * (Math.tan(phi) ** 2)) + eta2 - 9 * eta2 * (Math.tan(phi) ** 2) )
158
+ ix = (Math.tan(phi) / (720 * rho * (nu ** 5))) * (61 + (90 * (Math.tan(phi) ** 2)) + (45 * (Math.tan(phi) ** 4)) )
159
+ x = sec(phi) / nu
160
+ xi = (sec(phi) / (6 * nu ** 3)) * ((nu/rho) + 2 * (Math.tan(phi) ** 2))
161
+ xii = (sec(phi) / (120 * nu ** 5)) * (5 + (28 * (Math.tan(phi) ** 2)) + (24 * (Math.tan(phi) ** 4)))
162
+ xiia = (sec(phi) / (5040 * nu ** 7)) * (61 + (662 * (Math.tan(phi) ** 2)) + (1320 * (Math.tan(phi) ** 4)) + (720 * (Math.tan(phi) ** 6)))
163
+
164
+ d = eing-e0
165
+
166
+ # all of which was just to populate these last two equations:
167
+
168
+ phi = phi - vii*(d**2) + viii*(d**4) - ix*(d**6)
169
+ lambda = l0 + x*d - xi*(d**3) + xii*(d**5) - xiia*(d**7)
170
+
171
+ # phi and lambda are lat and long but note that here we are still in radians and osgb36
172
+ # if a different output datum is required, the helmert transformation remaps the coordinates onto a new globe
173
+
174
+ if datum && datum != :osgb36
175
+ target_ellipsoid = Osgb::Ellipsoid[datum]
176
+
177
+ if helmert = Osgb::Helmert[datum]
178
+ cartesian_coordinates = ellipsoid.polar_to_cartesian(phi, lambda)
179
+ transformed = helmert.transform(*cartesian_coordinates)
180
+ phi, lambda = target_ellipsoid.cartesian_to_polar(*transformed)
181
+ else
182
+ raise RuntimeError, "Missing ellipsoid or helmert transformation for #{datum}"
183
+ end
184
+ end
185
+
186
+ @coordinates = {:lat => phi, :lng => lambda}
187
+ end
188
+ @coordinates
189
+ end
190
+
191
+ private
192
+
193
+ def sec(radians)
194
+ 1 / Math.cos(radians)
195
+ end
196
+
197
+ end
198
+ end
@@ -0,0 +1,45 @@
1
+ module Osgb
2
+ module HasGridref
3
+ def self.included base #:nodoc:
4
+ base.class_eval {
5
+ cattr_accessor :osgb_options
6
+ @@osgb = {}
7
+ extend Osgb::ClassMethods
8
+ }
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def has_gridref name, options = {}
14
+ include Osgb::InstanceMethods
15
+ osgb_options = {
16
+ :lat => 'lat',
17
+ :lng => 'lng',
18
+ :gridref => 'gridref',
19
+ :validation => false,
20
+ :conversion => true
21
+ }.merge(options)
22
+ before_validation :convert_between_gridref_and_latlng if osgb_options[:conversion]
23
+ validates :must_have_location if osgb_options[:validation]
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ def must_have_location
29
+ send(cols[:gridref]).is_gridref? || (send("#{cols[:lat]}?") && send("#{cols[:lng]}?"))
30
+ end
31
+
32
+ def convert_between_gridref_and_latlng
33
+ cols = self.class.osgb_options
34
+ if columns.include?(cols[:lat], cols[:lng], cols[:gridref])
35
+ if send("#{cols[:gridref]}_changed?") || !send("#{cols[:lat]}?") || !send("#{cols[:lng]}?")
36
+ latlng = gridref.coordinates
37
+ send("#{cols[:lat]}=", latlng[0])
38
+ send("#{cols[:lng]}=", latlng[1])
39
+ elsif send("#{cols[:lat]}_changed?") || send("#{cols[:lng]}_changed?") || !send("#{cols[:gridref]}?")
40
+ send("#{cols[:gridref]}=", Osgb::Gridref.from(send(cols[:lat]), send(cols[:lng])))
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ module Osgb
2
+ class Helmert
3
+ attr_accessor :name, :tx, :ty, :tz, :rx, :ry, :rz, :s
4
+ @@instances = {}
5
+
6
+ def initialize(name, attributes)
7
+ @name = name
8
+ @tx = attributes[:tx]
9
+ @ty = attributes[:ty]
10
+ @tz = attributes[:tz]
11
+ @rx = (attributes[:rx]/3600).to_radians
12
+ @ry = (attributes[:ry]/3600).to_radians
13
+ @rz = (attributes[:rz]/3600).to_radians
14
+ @s = attributes[:s]
15
+ @@instances[name] = self
16
+ end
17
+
18
+ def s1
19
+ s/1e6 + 1
20
+ end
21
+
22
+ def transform(x,y,z)
23
+ xp = tx + x*s1 - y*rz + z*ry
24
+ yp = ty + x*rz + y*s1 - z*rx
25
+ zp = tz - x*ry + y*rx + z*s1
26
+ [xp, yp, zp]
27
+ end
28
+
29
+ def self.[](name)
30
+ @@instances[name]
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ module Osgb
2
+ class Projection
3
+ attr_accessor :name, :scale, :phi0, :lambda0, :e0, :n0, :ellipsoid
4
+ @@instances = {}
5
+
6
+ def initialize(name, attributes)
7
+ @name = name
8
+ @scale = attributes[:scale]
9
+ @phi0 = attributes[:phi0].to_radians
10
+ @lambda0 = attributes[:lambda0].to_radians
11
+ @e0 = attributes[:e0]
12
+ @n0 = attributes[:n0]
13
+ @ellipsoid = Osgb::Ellipsoid[attributes[:ellipsoid]]
14
+ @@instances[name] = self
15
+ end
16
+
17
+ def self.[](name)
18
+ @@instances[name]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'osgb'
2
+
3
+ module Osgb
4
+ if defined? Rails::Railtie
5
+ require 'rails'
6
+ class Railtie < Rails::Railtie
7
+ initializer 'osgb.insert_into_active_record' do
8
+ ActiveSupport.on_load :active_record do
9
+ Osgb::Railtie.insert
10
+ end
11
+ end
12
+ rake_tasks do
13
+ load "tasks/osgb.rake"
14
+ end
15
+ end
16
+ end
17
+
18
+ class Railtie
19
+ def self.insert
20
+ ActiveRecord::Base.send(:include, Osgb::HasGridref)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ class String
2
+ def is_gridref?
3
+ !!(self.upcase =~ /^(H(P|T|U|Y|Z)|N(A|B|C|D|F|G|H|J|K|L|M|N|O|R|S|T|U|W|X|Y|Z)|OV|S(C|D|E|G|H|J|K|M|N|O|P|R|S|T|U|W|X|Y|Z)|T(A|F|G|L|M|Q|R|V)){1}\d{4}(NE|NW|SE|SW)?$|((H(P|T|U|Y|Z)|N(A|B|C|D|F|G|H|J|K|L|M|N|O|R|S|T|U|W|X|Y|Z)|OV|S(C|D|E|G|H|J|K|M|N|O|P|R|S|T|U|W|X|Y|Z)|T(A|F|G|L|M|Q|R|V)){1}(\d{4}|\d{6}|\d{8}|\d{10}))$/)
4
+ end
5
+
6
+ def is_latlng?
7
+ !!coordinates
8
+ end
9
+
10
+ def coordinates
11
+ if matches = self.match(/(-?\d+\.\d+)[,\s]+(-?\d+\.\d+)/)
12
+ matches[1,2]
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ def to_latlng(options={})
19
+ if is_gridref?
20
+ Osgb::Gridref.new(self, options).to_latlng
21
+ else
22
+ self.coordinates
23
+ end
24
+ end
25
+
26
+ def to_wgs84(options={})
27
+ if is_gridref?
28
+ Osgb::Gridref.new(self, options.merge(:datum => :wgs84)).to_latlng
29
+ else
30
+ self.coordinates
31
+ end
32
+ end
33
+
34
+ def lat(options={})
35
+ to_latlng({:datum => :wgs84}.merge(options))[0]
36
+ end
37
+
38
+ def lng(options={})
39
+ to_latlng({:datum => :wgs84}.merge(options))[1]
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'osgb'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ it "should know whether or not it looks like a grid reference" do
5
+ "SD13241324".is_gridref?.should be_true
6
+ "catapult".is_gridref?.should be_false
7
+ "54.196915 -3.094684".is_gridref?.should be_false
8
+ end
9
+
10
+ it "should know whether or not it looks like a lat/lng pair" do
11
+ "SD13241324".is_latlng?.should be_false
12
+ "catapult".is_latlng?.should be_false
13
+ "54.196915 -3.094684".is_latlng?.should be_true
14
+ "54.196915, -3.094684".is_latlng?.should be_true
15
+ "54.196915|-3.094684".is_latlng?.should be_true
16
+ end
17
+
18
+ it "should turn be able to turn itself into an osgb lat/lng pair" do
19
+ "SD28687846".to_latlng(:precision => 6).should == [54.196763, -3.093320]
20
+ "SD28687846".to_latlng(:precision => 2).should == [54.2, -3.09]
21
+ end
22
+
23
+ it "should turn be able to turn itself into a wgs84 lat/lng pair for gps use" do
24
+ "SD28687846".to_wgs84(:precision => 6).should == [54.196915, -3.094684]
25
+ "SD28687846".to_wgs84(:precision => 2).should == [54.2, -3.09]
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: osgb
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - William Ross
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-24 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 23
29
+ segments:
30
+ - 2
31
+ - 6
32
+ - 0
33
+ version: 2.6.0
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rails
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 21
45
+ segments:
46
+ - 3
47
+ - 0
48
+ - 9
49
+ version: 3.0.9
50
+ type: :development
51
+ version_requirements: *id002
52
+ description: Supports the use of Ordnance Survey Grid References in place of lat/lng pairs. Includes activerecord plugin.
53
+ email: will@spanner.org
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - lib/osgb/angle_conversions.rb
62
+ - lib/osgb/ellipsoid.rb
63
+ - lib/osgb/gridref.rb
64
+ - lib/osgb/has_gridref.rb
65
+ - lib/osgb/helmert.rb
66
+ - lib/osgb/projection.rb
67
+ - lib/osgb/railtie.rb
68
+ - lib/osgb/string_conversions.rb
69
+ - lib/osgb.rb
70
+ - spec/spec_helper.rb
71
+ - spec/string_spec.rb
72
+ - CHANGELOG.rdoc
73
+ - Gemfile
74
+ - LICENSE
75
+ - Rakefile
76
+ - README.md
77
+ - init.rb
78
+ homepage: http://github.com/spanner/osgb
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 19
101
+ segments:
102
+ - 1
103
+ - 3
104
+ - 4
105
+ version: 1.3.4
106
+ requirements: []
107
+
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.10
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Grid reference translation to and from lat/long.
113
+ test_files: []
114
+