geogov 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,9 +20,9 @@ module Geogov
20
20
  raise ArgumentError.new("#{instance.class} doesn't respond to #{method}")
21
21
  end
22
22
 
23
- caching_instance = SimpleCache.new(instance)
23
+ # caching_instance = SimpleCache.new(instance)
24
24
  @@methods ||= {}
25
- @@methods[method] = caching_instance
25
+ @@methods[method] = instance
26
26
 
27
27
  unless self.methods().include?(method)
28
28
  dispatcher = <<-EOS
@@ -43,6 +43,7 @@ module Geogov
43
43
  provider_for :lat_lon_to_country, Geonames.new()
44
44
  provider_for :centre_of_country, Geonames.new()
45
45
 
46
+ provider_for :lat_lon_from_postcode, Mapit.new()
46
47
  provider_for :centre_of_district, Mapit.new()
47
48
  provider_for :areas_for_stack_from_postcode, Mapit.new()
48
49
  provider_for :areas_for_stack_from_coords, Mapit.new()
@@ -1,8 +1,8 @@
1
1
  module Geogov
2
2
  class GeoStack
3
3
 
4
- attr_accessor :ward, :council, :nation, :country, :wmc, :lat, :lon, :friendly_name
5
- attr_reader :postcode, :fuzzy_point
4
+ attr_accessor :ward, :council, :nation, :country, :region, :lat, :lon, :authorities, :fuzzy_point
5
+ attr_reader :postcode
6
6
 
7
7
  def initialize(&block)
8
8
  if block_given?
@@ -58,13 +58,10 @@ module Geogov
58
58
  {
59
59
  :fuzzy_point => self.fuzzy_point.to_hash,
60
60
  :postcode => self.postcode,
61
- :ward => self.ward,
62
61
  :council => self.council,
63
- :nation => self.nation,
64
- :country => self.country,
65
- :wmc => self.wmc,
62
+ :ward => self.ward,
66
63
  :friendly_name => self.friendly_name
67
- }.select {|k,v| !(v.nil?) }
64
+ }#.select {|k,v| !(v.nil?) }
68
65
  end
69
66
 
70
67
  def update(hash)
@@ -79,6 +76,52 @@ module Geogov
79
76
  empty.fuzzy_point = empty.calculate_fuzzy_point
80
77
  end
81
78
  end
79
+
80
+ def friendly_name
81
+ @friendly_name ||= build_locality
82
+ end
83
+
84
+ def has_authority?( type )
85
+ get_authority(type) ? true : false
86
+ end
87
+
88
+ def get_authority( type )
89
+ return false if self.authorities[type.upcase.to_sym] == true
90
+ self.authorities.nil? or self.authorities[type.upcase.to_sym].nil? ? false : self.authorities[type.upcase.to_sym]
91
+ end
92
+
93
+ def formatted_authority_name( type )
94
+ return false unless has_authority?(type)
95
+ name = get_authority(type)['name'].dup
96
+
97
+ name.sub!(/ *((District Council|Borough Council|Community|County Council|City Council|Council) ?)+/,'')
98
+ name.sub!(/ (North|East|South|West|Central)$/,'')
99
+ name.sub!(/Mid /,'')
100
+
101
+ name
102
+ end
103
+
104
+ def build_locality
105
+ return false unless self.authorities
106
+
107
+ case
108
+ when has_authority?('DIS') && has_authority?('CTY')
109
+ locality = ['DIS','CTY']
110
+ when has_authority?('LBO')
111
+ locality = ['LBO','London']
112
+ when has_authority?('UTA') && has_authority?('CPC') # for cornwall civil parishes
113
+ locality = ['CPC','UTA']
114
+ when has_authority?('UTA') && has_authority?('UTE')
115
+ locality = ['UTE','UTA']
116
+ when has_authority?('UTA') && has_authority?('UTW')
117
+ locality = ['UTW','UTA']
118
+ when has_authority?('MTW') && has_authority?('MTD')
119
+ locality = ['MTW','MTD']
120
+ else
121
+ return false
122
+ end
123
+ locality.map {|t| formatted_authority_name(t) || t }.uniq.join(', ')
124
+ end
82
125
 
83
126
  def has_valid_lat_lon(hash)
84
127
  return (hash['lon'] and hash['lat'] and hash['lon'] != "" and hash['lat'] != "")
@@ -90,16 +133,12 @@ module Geogov
90
133
  fields = Geogov.areas_for_stack_from_postcode(postcode)
91
134
  if fields
92
135
  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
136
  set_fields(fields.select {|k,v| k != :point})
97
137
  end
98
138
  end
99
139
  end
100
140
 
101
141
  def fetch_missing_fields_for_coords(lat, lon)
102
- self.friendly_name = Geogov.nearest_place_name(lat, lon)
103
142
  fields = Geogov.areas_for_stack_from_coords(lat, lon)
104
143
  if ['England', 'Scotland', 'Northern Ireland', 'Wales'].include?(fields[:nation])
105
144
  self.country = 'UK'
@@ -115,7 +154,9 @@ module Geogov
115
154
  self.send(setter,value)
116
155
  end
117
156
  else
118
- raise ArgumentError, "geo type '#{geo}' is not a valid geo type"
157
+ self.authorities ||= { }
158
+ self.authorities[geo] = value
159
+ # raise ArgumentError, "geo type '#{geo}' is not a valid geo type"
119
160
  end
120
161
  end
121
162
  self
@@ -43,7 +43,7 @@ module Geogov
43
43
 
44
44
  def lat_lon_from_postcode(postcode)
45
45
  areas = areas_for_stack_from_postcode(postcode)
46
- areas[:point]
46
+ areas[:point] or raise UnrecognizedLocationError
47
47
  end
48
48
 
49
49
  # Borrowed heavily from mapit's pylib/postcodes/views.py with some amendments based on
@@ -51,12 +51,10 @@ module Geogov
51
51
  def translate_area_type_to_shortcut(area_type)
52
52
  if ['COP', 'LBW', 'LGE', 'MTW', 'UTE', 'UTW', 'DIW'].include?(area_type)
53
53
  return 'ward'
54
- elsif ['CTY', 'CED'].include?(area_type)
55
-
56
- git
57
- return 'council' # county
58
- elsif ['DIS', 'LBO'].include?(area_type)
59
- return 'council' # district
54
+ elsif ['CTY', 'CED', 'MTD', 'UTA', 'DIS', 'LBO', 'LGD'].include?(area_type)
55
+ return 'council'
56
+ elsif area_type == 'EUR'
57
+ return 'region'
60
58
  elsif area_type == 'WMC' # XXX Also maybe 'EUR', 'NIE', 'SPC', 'SPE', 'WAC', 'WAE', 'OLF', 'OLG', 'OMF', 'OMG')
61
59
  return 'WMC'
62
60
  end
@@ -65,8 +63,12 @@ module Geogov
65
63
  def areas_for_stack_from_coords(lat, lon)
66
64
  query = self.point("4326", [lon, lat])
67
65
  results = {:point => {'lat' => lat, 'lon' => lon}}
66
+ councils = { }
67
+
68
68
  query.each do |id, area_info|
69
+ type = area_info['type'].upcase.to_sym
69
70
  level = translate_area_type_to_shortcut(area_info['type'])
71
+
70
72
  if level
71
73
  level = level.downcase.to_sym
72
74
  results[level] = [] unless results[level]
@@ -75,15 +77,24 @@ module Geogov
75
77
  results[level] << level_info
76
78
  results[:nation] = area_info['country_name'] if results[:nation].nil?
77
79
  end
80
+
81
+ councils[type] = { 'name' => area_info['name'], 'type' => area_info['type'], 'id' => area_info['id'] }
78
82
  end
79
- return results
83
+
84
+ return councils.merge results
80
85
  end
81
86
 
82
87
  def areas_for_stack_from_postcode(postcode)
83
88
  query = self.postcode(postcode)
84
89
  results = {}
85
90
 
86
- if query && query['shortcuts'] && query['areas']
91
+ if query && query['areas']
92
+
93
+ query['areas'].each do |i, area|
94
+ type = area['type'].to_sym
95
+ results[type] = area
96
+ end
97
+
87
98
  query['shortcuts'].each do |typ, i|
88
99
  if i.is_a? Hash
89
100
  ids = i.values()
@@ -3,7 +3,6 @@ require 'test_helper'
3
3
  class GovspeakTest < Test::Unit::TestCase
4
4
 
5
5
  test "IP-located stack should have country" do
6
-
7
6
  Geogov.configure do |g|
8
7
  g.provider_for :centre_of_country, stub(:centre_of_country => {"lat"=>37, "lon"=>-96})
9
8
  g.provider_for :remote_location, stub(:remote_location => {'country' => 'US'})
@@ -74,4 +73,52 @@ class GovspeakTest < Test::Unit::TestCase
74
73
  assert_equal :country, stack.fuzzy_point.accuracy
75
74
  end
76
75
 
76
+ test "stack with postcode returns correct locality" do
77
+ stack = Geogov::GeoStack.new
78
+ stack = stack.update( 'postcode' => "SW1A 1AA" )
79
+
80
+ assert_equal "Westminster, London", stack.friendly_name
81
+ end
82
+
83
+ test "stack with coordinates returns correct locality" do
84
+ stack = Geogov::GeoStack.new
85
+ stack = stack.update( 'lat' => "51.501009", "lon" => "-0.1415870" )
86
+
87
+ assert_equal "Westminster, London", stack.friendly_name
88
+ end
89
+
90
+ test "stack with postcode returns authorities" do
91
+ stack = Geogov::GeoStack.new
92
+ stack = stack.update( 'postcode' => "SW1A 1AA" )
93
+
94
+ assert stack.authorities.any?
95
+ end
96
+
97
+ test "stack with coordinates returns authorities" do
98
+ stack = Geogov::GeoStack.new
99
+ stack = stack.update( 'lat' => "51.501009", "lon" => "-0.1415870" )
100
+
101
+ assert stack.authorities.any?
102
+ end
103
+
104
+ test "stack with postcode returns correct locality, ward and council" do
105
+ stack = Geogov::GeoStack.new
106
+ stack = stack.update( 'postcode' => "SW1A 1AA" )
107
+
108
+ assert_equal "Westminster, London", stack.friendly_name
109
+ assert stack.ward and stack.ward.any?
110
+ assert stack.council and stack.council.any?
111
+ assert_equal "Westminster City Council", stack.council.first['name']
112
+ end
113
+
114
+ test "stack with coordinates returns correct locality, ward and council" do
115
+ stack = Geogov::GeoStack.new
116
+ stack = stack.update( 'lat' => "51.501009", "lon" => "-0.1415870" )
117
+
118
+ assert_equal "Westminster, London", stack.friendly_name
119
+ assert stack.ward and stack.ward.any?
120
+ assert stack.council and stack.council.any?
121
+ assert_equal "Westminster City Council", stack.council.first['name']
122
+ end
123
+
77
124
  end
metadata CHANGED
@@ -1,47 +1,51 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: geogov
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.8
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.0.9
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Ben Griffiths
9
9
  - James Stewart
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-01-30 00:00:00.000000000Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
13
+
14
+ date: 2012-01-30 00:00:00 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
16
17
  name: rake
17
- requirement: &70356750291540 !ruby/object:Gem::Requirement
18
+ requirement: &id001 !ruby/object:Gem::Requirement
18
19
  none: false
19
- requirements:
20
+ requirements:
20
21
  - - ~>
21
- - !ruby/object:Gem::Version
22
+ - !ruby/object:Gem::Version
22
23
  version: 0.9.0
23
24
  type: :development
24
25
  prerelease: false
25
- version_requirements: *70356750291540
26
- - !ruby/object:Gem::Dependency
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
27
28
  name: mocha
28
- requirement: &70356750291060 !ruby/object:Gem::Requirement
29
+ requirement: &id002 !ruby/object:Gem::Requirement
29
30
  none: false
30
- requirements:
31
+ requirements:
31
32
  - - ~>
32
- - !ruby/object:Gem::Version
33
+ - !ruby/object:Gem::Version
33
34
  version: 0.9.0
34
35
  type: :development
35
36
  prerelease: false
36
- version_requirements: *70356750291060
37
+ version_requirements: *id002
37
38
  description: Geolocation and utilities for UK Government single domain
38
- email:
39
+ email:
39
40
  - ben@alphagov.co.uk
40
41
  - jystewart@gmail.com
41
42
  executables: []
43
+
42
44
  extensions: []
45
+
43
46
  extra_rdoc_files: []
44
- files:
47
+
48
+ files:
45
49
  - lib/geogov/fuzzy_point.rb
46
50
  - lib/geogov/geo_stack.rb
47
51
  - lib/geogov/providers/dracos_gazetteer.rb
@@ -58,28 +62,37 @@ files:
58
62
  - test/test_helper.rb
59
63
  homepage: http://github.com/alphagov/geogov
60
64
  licenses: []
65
+
61
66
  post_install_message:
62
67
  rdoc_options: []
63
- require_paths:
68
+
69
+ require_paths:
64
70
  - lib
65
- required_ruby_version: !ruby/object:Gem::Requirement
71
+ required_ruby_version: !ruby/object:Gem::Requirement
66
72
  none: false
67
- requirements:
68
- - - ! '>='
69
- - !ruby/object:Gem::Version
70
- version: '0'
71
- required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 2911658137343146548
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
81
  none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
76
- version: '0'
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 2911658137343146548
86
+ segments:
87
+ - 0
88
+ version: "0"
77
89
  requirements: []
90
+
78
91
  rubyforge_project:
79
- rubygems_version: 1.8.10
92
+ rubygems_version: 1.8.13
80
93
  signing_key:
81
94
  specification_version: 3
82
95
  summary: Geolocation and utilities for UK Government single domain
83
- test_files:
96
+ test_files:
84
97
  - test/geogov_test.rb
85
98
  - test/test_helper.rb