osgb 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+