geogov 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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