geogov 0.0.1 → 0.0.3

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.
@@ -13,9 +13,14 @@ require 'geogov/providers/dracos_gazetteer'
13
13
  module Geogov
14
14
 
15
15
  def self.provider_for(method, instance)
16
+ unless instance.respond_to?(method)
17
+ raise ArgumentError.new("#{instance.class} doesn't respond to #{method}")
18
+ end
19
+
16
20
  caching_instance = SimpleCache.new(instance)
17
21
  @@methods ||= {}
18
22
  @@methods[method] = caching_instance
23
+
19
24
  unless self.methods().include?(method)
20
25
  dispatcher = <<-EOS
21
26
  def #{method}(*args, &block)
@@ -1,140 +1,141 @@
1
1
  module Geogov
2
2
  class GeoStack
3
3
 
4
- attr_accessor :postcode,:ward,:council,:nation,:country,:wmc,:lat,:lon
5
- attr_accessor :fuzzy_point
6
- attr_accessor :friendly_name
7
-
8
- def initialize()
9
- yield self
10
- end
11
-
12
- def calculate_fuzzy_point
13
- if self.lat and self.lon
14
- return FuzzyPoint.new(self.lat, self.lon, :point)
15
- end
4
+ attr_accessor :ward, :council, :nation, :country, :wmc, :lat, :lon, :friendly_name
5
+ attr_reader :postcode, :fuzzy_point
6
+
7
+ def initialize(&block)
8
+ if block_given?
9
+ yield self
10
+ else
11
+ self.fuzzy_point = calculate_fuzzy_point
12
+ end
13
+ end
14
+
15
+ def calculate_fuzzy_point
16
+ if self.lat and self.lon
17
+ return FuzzyPoint.new(self.lat, self.lon, :point)
18
+ end
16
19
 
17
- if self.postcode
18
- district = postcode.split(" ")[0]
19
- district_centre = Geogov.centre_of_district(district)
20
- if district_centre
21
- return FuzzyPoint.new(district_centre["lat"],district_centre["lon"],:postcode_district)
22
- end
23
- end
24
-
25
- if self.country
26
- country_centre = Geogov.centre_of_country(self.country)
27
- if country_centre
28
- return FuzzyPoint.new(country_centre["lat"],country_centre["lon"],:country)
29
- end
30
- end
31
-
32
- FuzzyPoint.new(0,0,:planet)
33
- end
34
-
35
- def self.new_from_ip(ip_address)
36
- remote_location = Geogov.remote_location(ip_address)
37
- new() do |gs|
38
- if remote_location
39
- gs.country = remote_location['country']
40
- end
41
- gs.fuzzy_point = gs.calculate_fuzzy_point
42
- end
43
- end
44
-
45
- def self.new_from_hash(hash)
46
- new() do |gs|
47
- gs.set_fields(hash)
48
- unless hash['fuzzy_point']
49
- raise ArgumentError, "fuzzy point required"
50
- end
51
- end
52
- end
53
-
54
- def to_hash
55
- {
56
- :fuzzy_point => self.fuzzy_point.to_hash,
57
- :postcode => self.postcode,
58
- :ward => self.ward,
59
- :council => self.council,
60
- :nation => self.nation,
61
- :country => self.country,
62
- :wmc => self.wmc,
63
- :friendly_name => self.friendly_name
64
- }.select {|k,v| !(v.nil?) }
65
- end
66
-
67
- def update(hash)
68
- self.class.new() do |empty|
69
- full_postcode = hash['postcode']
70
- empty.set_fields(hash)
71
- if has_valid_lat_lon(hash)
72
- empty.fetch_missing_fields_for_coords(hash['lat'], hash['lon'])
73
- elsif full_postcode
74
- empty.fetch_missing_fields_for_postcode(full_postcode)
75
- end
76
- empty.fuzzy_point = empty.calculate_fuzzy_point
77
- end
78
- end
79
-
80
- def has_valid_lat_lon(hash)
20
+ if self.postcode
21
+ district = postcode.split(" ")[0]
22
+ district_centre = Geogov.centre_of_district(district)
23
+ if district_centre
24
+ return FuzzyPoint.new(district_centre["lat"],district_centre["lon"],:postcode_district)
25
+ end
26
+ end
27
+
28
+ if self.country
29
+ country_centre = Geogov.centre_of_country(self.country)
30
+ if country_centre
31
+ return FuzzyPoint.new(country_centre["lat"],country_centre["lon"],:country)
32
+ end
33
+ end
34
+
35
+ FuzzyPoint.new(0,0,:planet)
36
+ end
37
+
38
+ def self.new_from_ip(ip_address)
39
+ remote_location = Geogov.remote_location(ip_address)
40
+ new() do |gs|
41
+ if remote_location
42
+ gs.country = remote_location['country']
43
+ end
44
+ gs.fuzzy_point = gs.calculate_fuzzy_point
45
+ end
46
+ end
47
+
48
+ def self.new_from_hash(hash)
49
+ new() do |gs|
50
+ gs.set_fields(hash)
51
+ unless hash['fuzzy_point']
52
+ raise ArgumentError, "fuzzy point required"
53
+ end
54
+ end
55
+ end
56
+
57
+ def to_hash
58
+ {
59
+ :fuzzy_point => self.fuzzy_point.to_hash,
60
+ :postcode => self.postcode,
61
+ :ward => self.ward,
62
+ :council => self.council,
63
+ :nation => self.nation,
64
+ :country => self.country,
65
+ :wmc => self.wmc,
66
+ :friendly_name => self.friendly_name
67
+ }.select {|k,v| !(v.nil?) }
68
+ end
69
+
70
+ def update(hash)
71
+ self.class.new() do |empty|
72
+ full_postcode = hash['postcode']
73
+ empty.set_fields(hash)
74
+ if has_valid_lat_lon(hash)
75
+ empty.fetch_missing_fields_for_coords(hash['lat'], hash['lon'])
76
+ elsif full_postcode
77
+ empty.fetch_missing_fields_for_postcode(full_postcode)
78
+ end
79
+ empty.fuzzy_point = empty.calculate_fuzzy_point
80
+ end
81
+ end
82
+
83
+ def has_valid_lat_lon(hash)
81
84
  return (hash['lon'] and hash['lat'] and hash['lon'] != "" and hash['lat'] != "")
82
- end
83
-
84
- def fetch_missing_fields_for_postcode(postcode)
85
- if matches = postcode.match(POSTCODE_REGEXP)
86
- self.country = "UK"
87
- fields = Geogov.areas_for_stack_from_postcode(postcode)
88
- if fields
89
- lat_lon = fields[:point]
90
- if lat_lon
91
- self.friendly_name = Geogov.nearest_place_name(lat_lon['lat'],lat_lon['lon'])
92
- end
93
- set_fields(fields.select {|k,v| k != :point})
94
- end
95
- end
96
- end
85
+ end
86
+
87
+ def fetch_missing_fields_for_postcode(postcode)
88
+ if matches = postcode.match(POSTCODE_REGEXP)
89
+ self.country = "UK"
90
+ fields = Geogov.areas_for_stack_from_postcode(postcode)
91
+ if fields
92
+ lat_lon = fields[:point]
93
+ if lat_lon
94
+ self.friendly_name = Geogov.nearest_place_name(lat_lon['lat'],lat_lon['lon'])
95
+ end
96
+ set_fields(fields.select {|k,v| k != :point})
97
+ end
98
+ end
99
+ end
97
100
 
98
- def fetch_missing_fields_for_coords(lat, lon)
99
- self.friendly_name = Geogov.nearest_place_name(lat, lon)
100
- fields = Geogov.areas_for_stack_from_coords(lat, lon)
101
- if ['England', 'Scotland', 'Northern Ireland', 'Wales'].include?(fields[:nation])
102
- self.country = 'UK'
103
- set_fields(fields.select {|k,v| k != :point})
104
- end
105
- end
106
-
107
- def set_fields(hash)
108
- hash.each do |geo, value|
109
- setter = (geo.to_s+"=").to_sym
110
- if self.respond_to?(setter)
111
- unless value == ""
112
- self.send(setter,value)
113
- end
114
- else
115
- raise ArgumentError, "geo type '#{geo}' is not a valid geo type"
116
- end
117
- end
118
- self
119
- end
120
-
121
- def fuzzy_point=(point)
122
- if point.is_a?(Hash)
123
- @fuzzy_point = FuzzyPoint.new(point["lat"],point["lon"],point["accuracy"])
124
- else
125
- @fuzzy_point = point
126
- end
127
- end
128
-
129
- POSTCODE_REGEXP = /^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])[ABD-HJLNP-UW-Z]{2}(:?\s+)?$/i
130
- SECTOR_POSTCODE_REGEXP = /^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])(:?\s+)?$/i
131
-
132
- def postcode=(postcode)
133
- if (matches = (postcode.match(POSTCODE_REGEXP) || postcode.match(SECTOR_POSTCODE_REGEXP)))
134
- @postcode = matches[1]+" "+matches[2]
135
- end
136
- end
137
-
138
-
139
- end
140
- end
101
+ def fetch_missing_fields_for_coords(lat, lon)
102
+ self.friendly_name = Geogov.nearest_place_name(lat, lon)
103
+ fields = Geogov.areas_for_stack_from_coords(lat, lon)
104
+ if ['England', 'Scotland', 'Northern Ireland', 'Wales'].include?(fields[:nation])
105
+ self.country = 'UK'
106
+ set_fields(fields.select {|k,v| k != :point})
107
+ end
108
+ end
109
+
110
+ def set_fields(hash)
111
+ hash.each do |geo, value|
112
+ setter = (geo.to_s+"=").to_sym
113
+ if self.respond_to?(setter)
114
+ unless value == ""
115
+ self.send(setter,value)
116
+ end
117
+ else
118
+ raise ArgumentError, "geo type '#{geo}' is not a valid geo type"
119
+ end
120
+ end
121
+ self
122
+ end
123
+
124
+ def fuzzy_point=(point)
125
+ if point.is_a?(Hash)
126
+ @fuzzy_point = FuzzyPoint.new(point["lat"],point["lon"],point["accuracy"])
127
+ else
128
+ @fuzzy_point = point
129
+ end
130
+ end
131
+
132
+ POSTCODE_REGEXP = /^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])[ABD-HJLNP-UW-Z]{2}(:?\s+)?$/i
133
+ SECTOR_POSTCODE_REGEXP = /^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])(:?\s+)?$/i
134
+
135
+ def postcode=(postcode)
136
+ if (matches = (postcode.match(POSTCODE_REGEXP) || postcode.match(SECTOR_POSTCODE_REGEXP)))
137
+ @postcode = matches[1]+" "+matches[2]
138
+ end
139
+ end
140
+ end
141
+ end
@@ -20,6 +20,7 @@ module Geogov
20
20
  }
21
21
  url_path = "#{base_url}#{url}"
22
22
  url_path += "/#{params.join("/")}" if params.length > 0
23
+ url_path += ".json"
23
24
  return url_path
24
25
  end
25
26
 
@@ -39,6 +40,11 @@ module Geogov
39
40
  def respond_to?(sym)
40
41
  valid_mapit_methods.include?(sym) || super(sym)
41
42
  end
43
+
44
+ def lat_lon_from_postcode(postcode)
45
+ areas = areas_for_stack_from_postcode(postcode)
46
+ areas[:point]
47
+ end
42
48
 
43
49
  # Borrowed heavily from mapit's pylib/postcodes/views.py with some amendments based on
44
50
  # pylib/mapit/areas/models.py
@@ -62,7 +68,9 @@ module Geogov
62
68
  if level
63
69
  level = level.downcase.to_sym
64
70
  results[level] = [] unless results[level]
65
- results[level] << area_info.select {|k,v| ["name","id","type"].include?(k) }
71
+ level_info = area_info.select { |k,v| ["name","id","type"].include?(k) }
72
+ level_info['ons'] = area_info['codes']['ons'] if area_info['codes'] && area_info['codes']['ons']
73
+ results[level] << level_info
66
74
  results[:nation] = area_info['country_name'] if results[:nation].nil?
67
75
  end
68
76
  end
@@ -83,7 +91,9 @@ module Geogov
83
91
  area_info = query['areas'][id.to_s]
84
92
  level = typ.downcase.to_sym
85
93
  results[level] = [] unless results[level]
86
- results[level] << area_info.select {|k,v| ["name","id","type"].include?(k) }
94
+ level_info = area_info.select { |k,v| ["name","id","type"].include?(k) }
95
+ level_info['ons'] = area_info['codes']['ons'] if area_info['codes'] && area_info['codes']['ons']
96
+ results[level] << level_info
87
97
  results[:nation] = area_info['country_name'] if results[:nation].nil?
88
98
  end
89
99
  end
@@ -28,6 +28,14 @@ class GovspeakTest < Test::Unit::TestCase
28
28
  assert_equal 0, stack.fuzzy_point.lat
29
29
  assert_equal :planet, stack.fuzzy_point.accuracy
30
30
  end
31
+
32
+ test "raises an exception if provider doesn't support required method" do
33
+ assert_raises(ArgumentError) {
34
+ Geogov.configure do |g|
35
+ g.provider_for :lat_lon_from_postcode, stub
36
+ end
37
+ }
38
+ end
31
39
 
32
40
  test "reconstructed stack rejects unknown params" do
33
41
  assert_raises(ArgumentError) {
@@ -1,9 +1,8 @@
1
1
  $:.unshift(File.expand_path("../lib")) unless $:.include?(File.expand_path("../lib"))
2
2
 
3
- require 'bundler'
4
- Bundler.setup :default, :development, :test
5
-
6
3
  require 'test/unit'
4
+ require 'mocha'
5
+ require 'geogov'
7
6
 
8
7
  class Test::Unit::TestCase
9
8
  class << self
@@ -16,6 +15,3 @@ class Test::Unit::TestCase
16
15
  end
17
16
  end
18
17
  end
19
-
20
- require 'mocha'
21
- require 'geogov'
metadata CHANGED
@@ -1,81 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: geogov
3
- version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Ben Griffiths
9
+ - James Stewart
14
10
  autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2011-08-08 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2011-12-08 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: rake
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &70342818099700 !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
19
+ requirements:
27
20
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 63
30
- segments:
31
- - 0
32
- - 8
33
- - 0
34
- version: 0.8.0
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.0
35
23
  type: :development
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: mocha
39
24
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *70342818099700
26
+ - !ruby/object:Gem::Dependency
27
+ name: mocha
28
+ requirement: &70342818099000 !ruby/object:Gem::Requirement
41
29
  none: false
42
- requirements:
30
+ requirements:
43
31
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 59
46
- segments:
47
- - 0
48
- - 9
49
- - 0
32
+ - !ruby/object:Gem::Version
50
33
  version: 0.9.0
51
34
  type: :development
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: rspec
55
35
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- hash: 27
62
- segments:
63
- - 2
64
- - 5
65
- - 0
66
- version: 2.5.0
67
- type: :development
68
- version_requirements: *id003
69
- description: Geolocation and utilities for single domain
70
- email:
36
+ version_requirements: *70342818099000
37
+ description: Geolocation and utilities for UK Government single domain
38
+ email:
71
39
  - ben@alphagov.co.uk
40
+ - jystewart@gmail.com
72
41
  executables: []
73
-
74
42
  extensions: []
75
-
76
43
  extra_rdoc_files: []
77
-
78
- files:
44
+ files:
79
45
  - lib/geogov/fuzzy_point.rb
80
46
  - lib/geogov/geo_stack.rb
81
47
  - lib/geogov/providers/dracos_gazetteer.rb
@@ -90,40 +56,30 @@ files:
90
56
  - Rakefile
91
57
  - test/geogov_test.rb
92
58
  - test/test_helper.rb
93
- has_rdoc: true
94
59
  homepage: http://github.com/alphagov/geogov
95
60
  licenses: []
96
-
97
61
  post_install_message:
98
62
  rdoc_options: []
99
-
100
- require_paths:
63
+ require_paths:
101
64
  - lib
102
- required_ruby_version: !ruby/object:Gem::Requirement
65
+ required_ruby_version: !ruby/object:Gem::Requirement
103
66
  none: false
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- hash: 3
108
- segments:
109
- - 0
110
- version: "0"
111
- required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
72
  none: false
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- hash: 3
117
- segments:
118
- - 0
119
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
120
77
  requirements: []
121
-
122
78
  rubyforge_project:
123
- rubygems_version: 1.3.7
79
+ rubygems_version: 1.8.10
124
80
  signing_key:
125
81
  specification_version: 3
126
- summary: Geolocation and utilities for single domain
127
- test_files:
82
+ summary: Geolocation and utilities for UK Government single domain
83
+ test_files:
128
84
  - test/geogov_test.rb
129
85
  - test/test_helper.rb