$LOAD_PATH.unshift("#{File.dirname(__FILE__)}") require 'geo/postcode' require 'geo/sa1' require 'geo/sa2' require 'geo/sa3' require 'geo/sa4' require 'geo/state' require 'geo/suburb' require 'pr_geohash' class EnrichmentDb::Geo::Locator < EnrichmentDb::DatumModel attr_reader :id attr_reader :name attr_reader :state attr_reader :sa4 attr_reader :sa3 attr_reader :sa2 attr_reader :sa1 attr_reader :postcode attr_reader :suburb attr_reader :smallest_region def initialize(data) self.class.all_regions.each do |region| region_name = region.object_type region_data = data[region_name] region_instance = !!region_data ? region.new(region_data) : nil instance_variable_set("@#{region_name}", region_instance) if data['smallest_region'] == region_name @id = region_data['id'] @name = region_data['name'] @smallest_region = region_name end end end def self.geo_locate(geohash) formatted_geohash = format_geo(geohash) values = [formatted_geohash] data = {} all_regions.each do |region| region_name = region.object_type region_id = find_id(data, region_name) result = if !region_id.nil? region.by_id(region_id) else region.by_boundary(values) end data['smallest_region'] ||= region_name if !result.nil? data[region_name] = result end self.new(data) end def self.find_id(data, region_type) id = "#{region_type}_id" data.each do |k, v| return v[id] if v.is_a?(Hash) && v.keys.include?(id) end nil end def self.all_regions all_region_names.collect do |region| EnrichmentDb::Geo.const_get(region) end.sort_by do |region| region.scale end end def self.all_region_names EnrichmentDb::Geo.constants - [:Region, :Locator] end def self.format_geo(geo) return geo if geo.is_a?(String) fail EnrichmentDb::InvalidGeoPointFormat unless valid_geo_point?(geo) geo_format = geo.each_with_object({}) do |k, v, h| h[k.to_sym] = v end GeoHash.encode(geo_format[:lat], geo_format[:lon]) end def self.valid_geo_point?(geo_point) geo_point.is_a?(Hash) && geo_point.keys.sort.collect(&:to_sym) == [:lat, :lon] end private def self.object_type to_s.split(':').last.downcase.to_sym end def self.make_table_name(object_name) "#{object_name}s" end end