Class: Geogov::GeoStack

Inherits:
Object
  • Object
show all
Defined in:
lib/geogov/geo_stack.rb

Constant Summary collapse

POSTCODE_REGEXP =
/^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])[ABD-HJLNP-UW-Z]{2}(:?\s+)?$/i
SECTOR_POSTCODE_REGEXP =
/^([A-Z]{1,2}[0-9R][0-9A-Z]?)\s*([0-9])(:?\s+)?$/i

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ GeoStack

Returns a new instance of GeoStack.



7
8
9
10
11
12
13
# File 'lib/geogov/geo_stack.rb', line 7

def initialize(&block)
  if block_given?
    yield self
  else
    self.fuzzy_point = calculate_fuzzy_point
  end
end

Instance Attribute Details

#authoritiesObject

Returns the value of attribute authorities.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def authorities
  @authorities
end

#councilObject

Returns the value of attribute council.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def council
  @council
end

#countryObject

Returns the value of attribute country.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def country
  @country
end

#fuzzy_pointObject

Returns the value of attribute fuzzy_point.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def fuzzy_point
  @fuzzy_point
end

#latObject

Returns the value of attribute lat.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def lat
  @lat
end

#lonObject

Returns the value of attribute lon.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def lon
  @lon
end

#nationObject

Returns the value of attribute nation.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def nation
  @nation
end

#postcodeObject

Returns the value of attribute postcode.



5
6
7
# File 'lib/geogov/geo_stack.rb', line 5

def postcode
  @postcode
end

#regionObject

Returns the value of attribute region.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def region
  @region
end

#wardObject

Returns the value of attribute ward.



4
5
6
# File 'lib/geogov/geo_stack.rb', line 4

def ward
  @ward
end

Class Method Details

.new_from_hash(hash) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/geogov/geo_stack.rb', line 48

def self.new_from_hash(hash)
  new() do |gs|
    gs.set_fields(hash)
    unless hash['fuzzy_point']
      raise ArgumentError, "fuzzy point required"
    end
  end
end

.new_from_ip(ip_address) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/geogov/geo_stack.rb', line 38

def self.new_from_ip(ip_address)
  remote_location = Geogov.remote_location(ip_address)
  new() do |gs|
    if remote_location
      gs.country = remote_location['country']
    end
    gs.fuzzy_point = gs.calculate_fuzzy_point
  end
end

Instance Method Details

#build_localityObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/geogov/geo_stack.rb', line 104

def build_locality
  return false unless self.authorities

  case
    when has_authority?('DIS') && has_authority?('CTY')
      locality = ['DIS','CTY']
    when has_authority?('LBO')
      locality = ['LBO','London']
    when has_authority?('UTA') && has_authority?('CPC') # for cornwall civil parishes
      locality = ['CPC','UTA']
    when has_authority?('UTA') && has_authority?('UTE')
      locality = ['UTE','UTA']
    when has_authority?('UTA') && has_authority?('UTW')
      locality = ['UTW','UTA']       
    when has_authority?('MTW') && has_authority?('MTD')
      locality = ['MTW','MTD']
    else
      return false
  end
  locality.map {|t| formatted_authority_name(t) || t }.uniq.join(', ') 
end

#calculate_fuzzy_pointObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/geogov/geo_stack.rb', line 15

def calculate_fuzzy_point
  if self.lat and self.lon
    return FuzzyPoint.new(self.lat, self.lon, :point)
  end

  if self.postcode
    district = postcode.split(" ")[0]
    district_centre = Geogov.centre_of_district(district)
    if district_centre
      return FuzzyPoint.new(district_centre["lat"],district_centre["lon"],:postcode_district)
    end
  end

  if self.country
    country_centre = Geogov.centre_of_country(self.country)
    if country_centre
      return FuzzyPoint.new(country_centre["lat"],country_centre["lon"],:country)
    end
  end

  FuzzyPoint.new(0,0,:planet)
end

#fetch_missing_fields_for_coords(lat, lon) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/geogov/geo_stack.rb', line 141

def fetch_missing_fields_for_coords(lat, lon)
  fields = Geogov.areas_for_stack_from_coords(lat, lon)
  if ['England', 'Scotland', 'Northern Ireland', 'Wales'].include?(fields[:nation])
    self.country = 'UK'
    set_fields(fields.select {|k,v| k != :point})
  end
end

#fetch_missing_fields_for_postcode(postcode) ⇒ Object



130
131
132
133
134
135
136
137
138
139
# File 'lib/geogov/geo_stack.rb', line 130

def fetch_missing_fields_for_postcode(postcode)
  if matches = postcode.match(POSTCODE_REGEXP)
    self.country = "UK"
    fields = Geogov.areas_for_stack_from_postcode(postcode)
    if fields
      lat_lon = fields[:point]
      set_fields(fields.select {|k,v| k != :point})
    end
  end
end

#formatted_authority_name(type) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/geogov/geo_stack.rb', line 93

def formatted_authority_name( type ) 
  return false unless has_authority?(type)
  name = get_authority(type)['name'].dup

  name.sub!(/ *((District Council|Borough Council|Community|County Council|City Council|Council) ?)+/,'')
  name.sub!(/ (North|East|South|West|Central)$/,'')
  name.sub!(/Mid /,'')

  name
end

#friendly_nameObject



80
81
82
# File 'lib/geogov/geo_stack.rb', line 80

def friendly_name
  @friendly_name ||= build_locality
end

#get_authority(type) ⇒ Object



88
89
90
91
# File 'lib/geogov/geo_stack.rb', line 88

def get_authority( type )
  return false if self.authorities[type.upcase.to_sym] == true
  self.authorities.nil? or self.authorities[type.upcase.to_sym].nil? ? false : self.authorities[type.upcase.to_sym]
end

#has_authority?(type) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/geogov/geo_stack.rb', line 84

def has_authority?( type )
  get_authority(type) ? true : false
end

#has_valid_lat_lon(hash) ⇒ Object



126
127
128
# File 'lib/geogov/geo_stack.rb', line 126

def has_valid_lat_lon(hash)
  return (hash['lon'] and hash['lat'] and hash['lon'] != "" and hash['lat'] != "")
end

#set_fields(hash) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/geogov/geo_stack.rb', line 149

def set_fields(hash)
  hash.each do |geo, value|
    setter = (geo.to_s+"=").to_sym
    if self.respond_to?(setter)
      unless value == ""
        self.send(setter,value)
      end
    else
      self.authorities ||= { }
      self.authorities[geo] = value
      # raise ArgumentError, "geo type '#{geo}' is not a valid geo type"
    end
  end
  self
end

#to_hashObject



57
58
59
60
61
62
63
64
65
# File 'lib/geogov/geo_stack.rb', line 57

def to_hash
  {
    :fuzzy_point => self.fuzzy_point.to_hash,
    :postcode => self.postcode,
    :council => self.council,
    :ward => self.ward,
    :friendly_name => self.friendly_name
  }#.select {|k,v| !(v.nil?) }
end

#update(hash) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/geogov/geo_stack.rb', line 67

def update(hash)
  self.class.new() do |empty|
    full_postcode = hash['postcode']
    empty.set_fields(hash)
    if has_valid_lat_lon(hash)
      empty.fetch_missing_fields_for_coords(hash['lat'], hash['lon'])
    elsif full_postcode
      empty.fetch_missing_fields_for_postcode(full_postcode)
    end
    empty.fuzzy_point = empty.calculate_fuzzy_point
  end
end