geogov 0.0.3 → 0.0.4

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.
@@ -12,15 +12,18 @@ require 'geogov/providers/dracos_gazetteer'
12
12
 
13
13
  module Geogov
14
14
 
15
+ class UnrecognizedLocationError < RuntimeError
16
+ end
17
+
15
18
  def self.provider_for(method, instance)
16
19
  unless instance.respond_to?(method)
17
20
  raise ArgumentError.new("#{instance.class} doesn't respond to #{method}")
18
21
  end
19
-
22
+
20
23
  caching_instance = SimpleCache.new(instance)
21
24
  @@methods ||= {}
22
25
  @@methods[method] = caching_instance
23
-
26
+
24
27
  unless self.methods().include?(method)
25
28
  dispatcher = <<-EOS
26
29
  def #{method}(*args, &block)
@@ -28,30 +31,39 @@ module Geogov
28
31
  end
29
32
  EOS
30
33
  module_eval(dispatcher)
31
- end
34
+ end
32
35
  end
33
36
 
34
37
  def self.configure
35
38
  yield self
36
39
  end
37
40
 
38
- provider_for :nearest_place_name, DracosGazetteer.new()
39
-
40
- provider_for :lat_lon_to_country, Geonames.new()
41
- provider_for :centre_of_country, Geonames.new()
41
+ def lat_lon_from_postcode(postcode)
42
+ result = Mapit.new().lat_lon_from_postcode(postcode)
43
+
44
+ if result.nil?
45
+ raise UnrecognizedLocationError
46
+ end
47
+
48
+ result
49
+ end
50
+
51
+ provider_for :nearest_place_name, DracosGazetteer.new()
52
+
53
+ provider_for :lat_lon_to_country, Geonames.new()
54
+ provider_for :centre_of_country, Geonames.new()
42
55
 
43
- provider_for :centre_of_district, Mapit.new()
56
+ provider_for :centre_of_district, Mapit.new()
44
57
  provider_for :areas_for_stack_from_postcode, Mapit.new()
45
- provider_for :areas_for_stack_from_coords, Mapit.new()
46
- provider_for :lat_lon_from_postcode, Mapit.new()
58
+ provider_for :areas_for_stack_from_coords, Mapit.new()
47
59
 
48
- provider_for :remote_location, Hostip.new()
60
+ provider_for :remote_location, Hostip.new()
49
61
 
50
- provider_for :map_img, Google.new()
51
- provider_for :map_href, Google.new()
62
+ provider_for :map_img, Google.new()
63
+ provider_for :map_href, Google.new()
52
64
 
53
65
  extend self
54
-
66
+
55
67
  end
56
68
 
57
69
 
@@ -4,17 +4,17 @@ require 'uri'
4
4
  module Geogov
5
5
 
6
6
  class Mapit
7
-
7
+
8
8
  class Method
9
- def initialize(url,params = [])
9
+ def initialize(url, params = [])
10
10
  @url = url
11
11
  @params = params
12
12
  end
13
13
 
14
14
  def to_url(base_url)
15
15
  url = "/#{@url}" unless /^\//.match(@url)
16
- params = @params.map {|p|
17
- p = p.join(",") if p.is_a?(Array)
16
+ params = @params.map { |p|
17
+ p = p.join(",") if p.is_a?(Array)
18
18
  # Messy, but MapIt gets upset if you escape commas
19
19
  CGI::escape(p).gsub('%2C', ',')
20
20
  }
@@ -34,24 +34,26 @@ module Geogov
34
34
  end
35
35
 
36
36
  def valid_mapit_methods
37
- [:postcode,:areas,:area,:point,:generations]
37
+ [:postcode, :areas, :area, :point, :generations]
38
38
  end
39
39
 
40
40
  def respond_to?(sym)
41
41
  valid_mapit_methods.include?(sym) || super(sym)
42
42
  end
43
-
43
+
44
44
  def lat_lon_from_postcode(postcode)
45
45
  areas = areas_for_stack_from_postcode(postcode)
46
46
  areas[:point]
47
47
  end
48
-
48
+
49
49
  # Borrowed heavily from mapit's pylib/postcodes/views.py with some amendments based on
50
50
  # pylib/mapit/areas/models.py
51
51
  def translate_area_type_to_shortcut(area_type)
52
- if ['COP','LBW','LGE','MTW','UTE','UTW','DIW'].include?(area_type)
52
+ if ['COP', 'LBW', 'LGE', 'MTW', 'UTE', 'UTW', 'DIW'].include?(area_type)
53
53
  return 'ward'
54
54
  elsif ['CTY', 'CED'].include?(area_type)
55
+
56
+ git
55
57
  return 'council' # county
56
58
  elsif ['DIS', 'LBO'].include?(area_type)
57
59
  return 'council' # district
@@ -61,14 +63,14 @@ module Geogov
61
63
  end
62
64
 
63
65
  def areas_for_stack_from_coords(lat, lon)
64
- query = self.point("4326", [lon,lat])
66
+ query = self.point("4326", [lon, lat])
65
67
  results = {:point => {'lat' => lat, 'lon' => lon}}
66
- query.each do |id,area_info|
68
+ query.each do |id, area_info|
67
69
  level = translate_area_type_to_shortcut(area_info['type'])
68
70
  if level
69
71
  level = level.downcase.to_sym
70
72
  results[level] = [] unless results[level]
71
- level_info = area_info.select { |k,v| ["name","id","type"].include?(k) }
73
+ level_info = area_info.select { |k, v| ["name", "id", "type"].include?(k) }
72
74
  level_info['ons'] = area_info['codes']['ons'] if area_info['codes'] && area_info['codes']['ons']
73
75
  results[level] << level_info
74
76
  results[:nation] = area_info['country_name'] if results[:nation].nil?
@@ -80,40 +82,41 @@ module Geogov
80
82
  def areas_for_stack_from_postcode(postcode)
81
83
  query = self.postcode(postcode)
82
84
  results = {}
85
+
83
86
  if query && query['shortcuts'] && query['areas']
84
- query['shortcuts'].each do |typ,i|
87
+ query['shortcuts'].each do |typ, i|
85
88
  if i.is_a? Hash
86
89
  ids = i.values()
87
90
  else
88
91
  ids = [i]
89
92
  end
90
93
  ids.each do |id|
91
- area_info = query['areas'][id.to_s]
94
+ area_info = query['areas'][id.to_s]
92
95
  level = typ.downcase.to_sym
93
96
  results[level] = [] unless results[level]
94
- level_info = area_info.select { |k,v| ["name","id","type"].include?(k) }
97
+ level_info = area_info.select { |k, v| ["name", "id", "type"].include?(k) }
95
98
  level_info['ons'] = area_info['codes']['ons'] if area_info['codes'] && area_info['codes']['ons']
96
99
  results[level] << level_info
97
100
  results[:nation] = area_info['country_name'] if results[:nation].nil?
98
101
  end
99
102
  end
100
- lat,lon = query['wgs84_lat'],query['wgs84_lon']
103
+ lat, lon = query['wgs84_lat'], query['wgs84_lon']
101
104
  results[:point] = {'lat' => lat, 'lon' => lon}
102
105
  end
103
106
  return results
104
107
  end
105
-
108
+
106
109
  def centre_of_district(district_postcode)
107
- query = self.postcode("partial",district_postcode)
110
+ query = self.postcode("partial", district_postcode)
108
111
  if query
109
- lat,lon = query['wgs84_lat'],query['wgs84_lon']
112
+ lat, lon = query['wgs84_lat'], query['wgs84_lon']
110
113
  return {'lat' => lat, 'lon' => lon}
111
114
  end
112
115
  end
113
116
 
114
117
  def method_missing(method, *args, &block)
115
118
  if valid_mapit_methods.include?(method)
116
- Mapit::Method.new(method.to_s,args).call(@base)
119
+ Mapit::Method.new(method.to_s, args).call(@base)
117
120
  else
118
121
  super(method, *args, &block)
119
122
  end
@@ -1,72 +1,77 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class GovspeakTest < Test::Unit::TestCase
4
-
4
+
5
5
  test "IP-located stack should have country" do
6
6
 
7
7
  Geogov.configure do |g|
8
- g.provider_for :centre_of_country, stub(:centre_of_country => {"lat"=>37,"lon"=>-96})
9
- g.provider_for :remote_location, stub(:remote_location => {'country' => 'US'})
8
+ g.provider_for :centre_of_country, stub(:centre_of_country => {"lat"=>37, "lon"=>-96})
9
+ g.provider_for :remote_location, stub(:remote_location => {'country' => 'US'})
10
10
  end
11
11
 
12
12
  stack = Geogov::GeoStack.new_from_ip('173.203.129.90')
13
- assert_equal "US", stack.country
13
+ assert_equal "US", stack.country
14
14
  assert_in_delta stack.fuzzy_point.lon, -96, 0.5
15
15
  assert_in_delta stack.fuzzy_point.lat, 37, 0.5
16
- assert_equal :country, stack.fuzzy_point.accuracy
16
+ assert_equal :country, stack.fuzzy_point.accuracy
17
17
  end
18
-
19
- test "should be specific if no country available" do
20
-
21
- Geogov.configure do |g|
22
- g.provider_for :remote_location, stub(:remote_location => nil)
23
- end
24
-
25
- stack = Geogov::GeoStack.new_from_ip('127.0.0.1')
26
- assert_nil stack.country
27
- assert_equal 0, stack.fuzzy_point.lon
28
- assert_equal 0, stack.fuzzy_point.lat
29
- assert_equal :planet, stack.fuzzy_point.accuracy
18
+
19
+ test "should be specific if no country available" do
20
+ Geogov.configure do |g|
21
+ g.provider_for :remote_location, stub(:remote_location => nil)
30
22
  end
31
23
 
24
+ stack = Geogov::GeoStack.new_from_ip('127.0.0.1')
25
+ assert_nil stack.country
26
+ assert_equal 0, stack.fuzzy_point.lon
27
+ assert_equal 0, stack.fuzzy_point.lat
28
+ assert_equal :planet, stack.fuzzy_point.accuracy
29
+ end
30
+
32
31
  test "raises an exception if provider doesn't support required method" do
33
- assert_raises(ArgumentError) {
32
+ assert_raises(ArgumentError) {
34
33
  Geogov.configure do |g|
35
34
  g.provider_for :lat_lon_from_postcode, stub
36
- end
35
+ end
37
36
  }
38
37
  end
39
-
38
+
39
+ test "raises an error if the supplied postcode is invalid" do
40
+ assert_raises(Geogov::UnrecognizedLocationError) {
41
+ Geogov.lat_lon_from_postcode("nowhere")
42
+ }
43
+ end
44
+
40
45
  test "reconstructed stack rejects unknown params" do
41
- assert_raises(ArgumentError) {
42
- Geogov::GeoStack.new_from_hash("galaxy" => "Andromeda")
43
- }
46
+ assert_raises(ArgumentError) {
47
+ Geogov::GeoStack.new_from_hash("galaxy" => "Andromeda")
48
+ }
44
49
  end
45
50
 
46
51
  test "reconstructed stack should refuse creation if no fuzzy point" do
47
- assert_raises(ArgumentError) {
48
- Geogov::GeoStack.new_from_hash("country" => "US")
49
- }
52
+ assert_raises(ArgumentError) {
53
+ Geogov::GeoStack.new_from_hash("country" => "US")
54
+ }
50
55
  end
51
56
 
52
57
  test "reconstructed stack should always truncate postcode" do
53
- stack = Geogov::GeoStack.new_from_hash("postcode"=>"SE10 8UG","country" => "UK","fuzzy_point" => {"lat"=>"37","lon"=>"-96","accuracy"=>"postcode"})
54
- assert_equal "SE10 8", stack.postcode
58
+ stack = Geogov::GeoStack.new_from_hash("postcode"=>"SE10 8UG", "country" => "UK", "fuzzy_point" => {"lat"=>"37", "lon"=>"-96", "accuracy"=>"postcode"})
59
+ assert_equal "SE10 8", stack.postcode
55
60
  end
56
-
61
+
57
62
  test "stack should not consider a postcode with trailing whitespace invalid" do
58
- stack = Geogov::GeoStack.new_from_hash("postcode"=>"SE10 8UG ","country" => "UK","fuzzy_point" => {"lat"=>"37","lon"=>"-96","accuracy"=>"postcode"})
59
- assert_equal "SE10 8", stack.postcode
63
+ stack = Geogov::GeoStack.new_from_hash("postcode"=>"SE10 8UG ", "country" => "UK", "fuzzy_point" => {"lat"=>"37", "lon"=>"-96", "accuracy"=>"postcode"})
64
+ assert_equal "SE10 8", stack.postcode
60
65
  end
61
66
 
62
67
  test "stack should ignore invalid postcodes" do
63
- stack = Geogov::GeoStack.new_from_hash("postcode"=>"NOTAPOSTCODE","country" => "UK","fuzzy_point" => {"lat"=>"37","lon"=>"-96","accuracy"=>"postcode"})
64
- assert_nil stack.postcode
68
+ stack = Geogov::GeoStack.new_from_hash("postcode"=>"NOTAPOSTCODE", "country" => "UK", "fuzzy_point" => {"lat"=>"37", "lon"=>"-96", "accuracy"=>"postcode"})
69
+ assert_nil stack.postcode
65
70
  end
66
-
71
+
67
72
  test "stack with country should have country accuracy" do
68
- stack = Geogov::GeoStack.new_from_hash("country" => "US","fuzzy_point" => {"lat"=>"37","lon"=>"-96","accuracy"=>"country"})
73
+ stack = Geogov::GeoStack.new_from_hash("country" => "US", "fuzzy_point" => {"lat"=>"37", "lon"=>"-96", "accuracy"=>"country"})
69
74
  assert_equal :country, stack.fuzzy_point.accuracy
70
75
  end
71
-
76
+
72
77
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geogov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-12-08 00:00:00.000000000Z
13
+ date: 2011-12-20 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &70342818099700 !ruby/object:Gem::Requirement
17
+ requirement: &70306547782860 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.9.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70342818099700
25
+ version_requirements: *70306547782860
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: mocha
28
- requirement: &70342818099000 !ruby/object:Gem::Requirement
28
+ requirement: &70306547781900 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 0.9.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70342818099000
36
+ version_requirements: *70306547781900
37
37
  description: Geolocation and utilities for UK Government single domain
38
38
  email:
39
39
  - ben@alphagov.co.uk
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  version: '0'
77
77
  requirements: []
78
78
  rubyforge_project:
79
- rubygems_version: 1.8.10
79
+ rubygems_version: 1.8.12
80
80
  signing_key:
81
81
  specification_version: 3
82
82
  summary: Geolocation and utilities for UK Government single domain