Class: Address::NormalizedAddress
- Inherits:
-
Object
- Object
- Address::NormalizedAddress
- Defined in:
- app/services/address/normalized_address.rb
Overview
require 'geocoder'
require 'bigdecimal'
require 'set'
Constant Summary collapse
- ACCEPTABLE_TYPES =
Geocoder::Configuration.lookup = :google
Set.new(["street_address", "premise", "subpremise", "establishment"])
- Attrs =
[:address_line1, :address_line2, :city, :state_province, :state_code, :postal_code, :country, :country_iso, :latitude, :longitude, :formatted_address]
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(data) ⇒ NormalizedAddress
constructor
A new instance of NormalizedAddress.
- #inspect ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(data) ⇒ NormalizedAddress
Returns a new instance of NormalizedAddress.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/services/address/normalized_address.rb', line 18 def initialize(data) @address_line1 = nil @address_line2 = nil @city = nil @postal_code = nil @state_province = nil @country = nil @country_iso = nil @latitude = nil @longitude = nil @state_code = nil # The Google result consists of: # # - An array ("address_components") of hashes consisting of # {"long_name" => "...", "short_name" => "...", "types" => [...]} # - A "geometry" hash, with the latitude and longitude # - A "partial_match" indicator (which we're ignoring) # - A "types" array (which we're also ignoring) data["address_components"].each do |hash| types = hash["types"] value = hash["long_name"] next unless value.present? short_value = hash["short_name"] if types.include? "subpremise" @address_line2 = value @address_line2.insert(0, '#') unless @address_line2.starts_with?('#') elsif types.include? "street_number" @house_number = value elsif types.include? "sublocality" @city = value elsif types.include? "locality" @city = value if @city.nil? elsif types.include? "country" @country = value @country_iso = short_value elsif types.include? "postal_code" @postal_code = value elsif types.include? "route" @street = value elsif types.include? "administrative_area_level_1" @state_province = value @state_code = short_value elsif types.include? "establishment" @establishment = value end end @address_line1 = "#{@house_number} #{@street}".squish.presence || @establishment if data["formatted_address"] @formatted_address = data["formatted_address"] else @formatted_address = [ @address_line1, @address_line2, @city, @state_province, @postal_code ].select {|s| ! (s.nil? || s.empty?)}.join(' ') end # Latitude and longitude if data["geometry"] and data["geometry"]["location"] loc = data["geometry"]["location"] @latitude = BigDecimal(loc["lat"].to_s) @longitude = BigDecimal(loc["lng"].to_s) end end |
Class Method Details
.from_string(raw_address_string) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'app/services/address/normalized_address.rb', line 94 def self.from_string(raw_address_string) normalized_address = nil # Geocoder.search() returns an array of results. Take the first one. geocoded = Geocoder.search(raw_address_string) if geocoded && (geocoded.length > 0) # Geocoder returns data that may or may not be granular enough. For # instance, attempting to retrieve information about nonexistent # address '100 Main St, XYZ, PA, US' still returns a value, but the # value's type is "administrative_area_level_1", which means the data # is granular to a (U.S.) state. If it's a valid address, we should # get data that's more granular than that. Of the codes listed at # http://code.google.com/apis/maps/documentation/geocoding/#Types # we're interested in "street_address", "premise" and # "subpremise". data = geocoded[0].data types = Set.new(data["types"]) if !(types & ACCEPTABLE_TYPES).empty? normalized_address = new(data) end end normalized_address end |
Instance Method Details
#inspect ⇒ Object
89 90 91 |
# File 'app/services/address/normalized_address.rb', line 89 def inspect Hash[ Attrs.map {|field| [field, self.send(field)]} ] end |
#to_s ⇒ Object
85 86 87 |
# File 'app/services/address/normalized_address.rb', line 85 def to_s @formatted_address end |