geogov 0.0.3 → 0.0.4

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