Class: Address::NormalizedAddress
- Inherits:
-
Object
- Object
- Address::NormalizedAddress
- Defined in:
- app/services/address/normalized_address.rb
Overview
Constant Summary collapse
- ACCEPTABLE_TYPES =
Geocoder::Configuration.lookup = :google
Set.new(%w[street_address premise subpremise establishment])
- Attrs =
Attribute keys exposed by a normalized address (also used as the
attr_readerlist and the JSON shape returned to callers). %i[address_line1 address_line2 city state_province state_code postal_code country country_iso latitude longitude formatted_address].freeze
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.
16 17 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 |
# File 'app/services/address/normalized_address.rb', line 16 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 if value.blank? 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 @formatted_address = data["formatted_address"] || [ @address_line1, @address_line2, @city, @state_province, @postal_code ].select(&:present?).join(' ') # Latitude and longitude return unless data["geometry"] && data["geometry"]["location"] loc = data["geometry"]["location"] @latitude = BigDecimal(loc["lat"].to_s) @longitude = BigDecimal(loc["lng"].to_s) end |
Class Method Details
.from_string(raw_address_string) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'app/services/address/normalized_address.rb', line 88 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.present? # 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"]) normalized_address = new(data) if types.intersect?(ACCEPTABLE_TYPES) end normalized_address end |
Instance Method Details
#inspect ⇒ Object
84 85 86 |
# File 'app/services/address/normalized_address.rb', line 84 def inspect Attrs.index_with { |field| send(field) } end |
#to_s ⇒ Object
80 81 82 |
# File 'app/services/address/normalized_address.rb', line 80 def to_s @formatted_address end |