geocoder 1.6.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -0
- data/LICENSE +1 -1
- data/README.md +328 -231
- data/bin/console +6 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +7 -1
- data/lib/geocoder/cache.rb +16 -33
- data/lib/geocoder/cache_stores/base.rb +40 -0
- data/lib/geocoder/cache_stores/generic.rb +35 -0
- data/lib/geocoder/cache_stores/redis.rb +34 -0
- data/lib/geocoder/configuration.rb +11 -4
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/ip_address.rb +8 -1
- data/lib/geocoder/lookup.rb +16 -2
- data/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/lib/geocoder/lookups/amazon_location_service.rb +54 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +1 -1
- data/lib/geocoder/lookups/base.rb +8 -2
- data/lib/geocoder/lookups/bing.rb +1 -1
- data/lib/geocoder/lookups/esri.rb +6 -0
- data/lib/geocoder/lookups/geoapify.rb +72 -0
- data/lib/geocoder/lookups/geocodio.rb +1 -1
- data/lib/geocoder/lookups/geoip2.rb +4 -0
- data/lib/geocoder/lookups/google.rb +7 -2
- data/lib/geocoder/lookups/google_places_details.rb +8 -14
- data/lib/geocoder/lookups/google_places_search.rb +28 -2
- data/lib/geocoder/lookups/google_premier.rb +4 -0
- data/lib/geocoder/lookups/ip2location.rb +10 -6
- data/lib/geocoder/lookups/ipdata_co.rb +1 -1
- data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/lib/geocoder/lookups/latlon.rb +1 -2
- data/lib/geocoder/lookups/maxmind_local.rb +7 -1
- data/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/lib/geocoder/lookups/photon.rb +89 -0
- data/lib/geocoder/lookups/smarty_streets.rb +6 -1
- data/lib/geocoder/lookups/telize.rb +1 -1
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +1 -1
- data/lib/geocoder/lookups/yandex.rb +1 -2
- data/lib/geocoder/results/abstract_api.rb +146 -0
- data/lib/geocoder/results/amazon_location_service.rb +57 -0
- data/lib/geocoder/results/ban_data_gouv_fr.rb +26 -1
- data/lib/geocoder/results/db_ip_com.rb +1 -1
- data/lib/geocoder/results/esri.rb +5 -2
- data/lib/geocoder/results/geoapify.rb +179 -0
- data/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/lib/geocoder/results/ipregistry.rb +4 -8
- data/lib/geocoder/results/mapbox.rb +10 -4
- data/lib/geocoder/results/melissa_street.rb +46 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +1 -1
- data/lib/geocoder/results/nominatim.rb +27 -15
- data/lib/geocoder/results/photon.rb +119 -0
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- metadata +22 -10
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -30
- data/lib/hash_recursive_merge.rb +0 -73
| @@ -18,16 +18,42 @@ module Geocoder | |
| 18 18 |  | 
| 19 19 | 
             
                  private
         | 
| 20 20 |  | 
| 21 | 
            +
                  def result_root_attr
         | 
| 22 | 
            +
                    'candidates'
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
                  def base_query_url(query)
         | 
| 22 | 
            -
                    "#{protocol}://maps.googleapis.com/maps/api/place/ | 
| 26 | 
            +
                    "#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
         | 
| 23 27 | 
             
                  end
         | 
| 24 28 |  | 
| 25 29 | 
             
                  def query_url_google_params(query)
         | 
| 26 30 | 
             
                    {
         | 
| 27 | 
            -
                       | 
| 31 | 
            +
                      input: query.text,
         | 
| 32 | 
            +
                      inputtype: 'textquery',
         | 
| 33 | 
            +
                      fields: fields(query),
         | 
| 28 34 | 
             
                      language: query.language || configuration.language
         | 
| 29 35 | 
             
                    }
         | 
| 30 36 | 
             
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def fields(query)
         | 
| 39 | 
            +
                    query_fields = query.options[:fields]
         | 
| 40 | 
            +
                    return format_fields(query_fields) if query_fields
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    default_fields
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def default_fields
         | 
| 46 | 
            +
                    legacy = %w[id reference]
         | 
| 47 | 
            +
                    basic = %w[business_status formatted_address geometry icon name 
         | 
| 48 | 
            +
                      photos place_id plus_code types]
         | 
| 49 | 
            +
                    contact = %w[opening_hours]
         | 
| 50 | 
            +
                    atmosphere = %W[price_level rating user_ratings_total]
         | 
| 51 | 
            +
                    format_fields(legacy, basic, contact, atmosphere)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def format_fields(*fields)
         | 
| 55 | 
            +
                    fields.flatten.join(',')
         | 
| 56 | 
            +
                  end
         | 
| 31 57 | 
             
                end
         | 
| 32 58 | 
             
              end
         | 
| 33 59 | 
             
            end
         | 
| @@ -21,6 +21,10 @@ module Geocoder::Lookup | |
| 21 21 |  | 
| 22 22 | 
             
                private # ---------------------------------------------------------------
         | 
| 23 23 |  | 
| 24 | 
            +
                def result_root_attr
         | 
| 25 | 
            +
                  'results'
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 24 28 | 
             
                def cache_key(query)
         | 
| 25 29 | 
             
                  "#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
         | 
| 26 30 | 
             
                end
         | 
| @@ -8,6 +8,10 @@ module Geocoder::Lookup | |
| 8 8 | 
             
                  "IP2LocationApi"
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 | 
            +
                def required_api_key_parts
         | 
| 12 | 
            +
                  ['key']
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 11 15 | 
             
                def supported_protocols
         | 
| 12 16 | 
             
                  [:http, :https]
         | 
| 13 17 | 
             
                end
         | 
| @@ -15,15 +19,15 @@ module Geocoder::Lookup | |
| 15 19 | 
             
                private # ----------------------------------------------------------------
         | 
| 16 20 |  | 
| 17 21 | 
             
                def base_query_url(query)
         | 
| 18 | 
            -
                  "#{protocol}://api.ip2location.com/?"
         | 
| 22 | 
            +
                  "#{protocol}://api.ip2location.com/v2/?"
         | 
| 19 23 | 
             
                end
         | 
| 20 24 |  | 
| 21 25 | 
             
                def query_url_params(query)
         | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 24 | 
            -
                     | 
| 25 | 
            -
             | 
| 26 | 
            -
                   | 
| 26 | 
            +
                  super.merge(
         | 
| 27 | 
            +
                    key: configuration.api_key,
         | 
| 28 | 
            +
                    ip: query.sanitized_text,
         | 
| 29 | 
            +
                    package: configuration[:package],
         | 
| 30 | 
            +
                  )
         | 
| 27 31 | 
             
                end
         | 
| 28 32 |  | 
| 29 33 | 
             
                def results(query)
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'geocoder/lookups/base'
         | 
| 4 | 
            +
            require 'geocoder/results/ipqualityscore'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Geocoder::Lookup
         | 
| 7 | 
            +
              class Ipqualityscore < Base
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def name
         | 
| 10 | 
            +
                  "IPQualityScore"
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def required_api_key_parts
         | 
| 14 | 
            +
                  ['api_key']
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                private # ---------------------------------------------------------------
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def base_query_url(query)
         | 
| 20 | 
            +
                  "#{protocol}://ipqualityscore.com/api/json/ip/#{configuration.api_key}/#{query.sanitized_text}?"
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def valid_response?(response)
         | 
| 24 | 
            +
                  if (json = parse_json(response.body))
         | 
| 25 | 
            +
                    success = json['success']
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                  super && success == true
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def results(query, reverse = false)
         | 
| 31 | 
            +
                  return [] unless doc = fetch_data(query)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  return [doc] if doc['success']
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  case doc['message']
         | 
| 36 | 
            +
                  when /invalid (.*) key/i
         | 
| 37 | 
            +
                    raise_error Geocoder::InvalidApiKey ||
         | 
| 38 | 
            +
                                Geocoder.log(:warn, "#{name} API error: invalid api key.")
         | 
| 39 | 
            +
                  when /insufficient credits/, /exceeded your request quota/
         | 
| 40 | 
            +
                    raise_error Geocoder::OverQueryLimitError ||
         | 
| 41 | 
            +
                                Geocoder.log(:warn, "#{name} API error: query limit exceeded.")
         | 
| 42 | 
            +
                  when /invalid (.*) address/i
         | 
| 43 | 
            +
                    raise_error Geocoder::InvalidRequest ||
         | 
| 44 | 
            +
                                Geocoder.log(:warn, "#{name} API error: invalid request.")
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  [doc]
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -25,8 +25,7 @@ module Geocoder::Lookup | |
| 25 25 | 
             
                  # The API returned a 404 response, which indicates no results found
         | 
| 26 26 | 
             
                  elsif doc['error']['type'] == 'api_error'
         | 
| 27 27 | 
             
                    []
         | 
| 28 | 
            -
                  elsif
         | 
| 29 | 
            -
                    doc['error']['type'] == 'authentication_error'
         | 
| 28 | 
            +
                  elsif doc['error']['type'] == 'authentication_error'
         | 
| 30 29 | 
             
                    raise_error(Geocoder::InvalidApiKey) ||
         | 
| 31 30 | 
             
                      Geocoder.log(:warn, "LatLon.io service error: invalid API key.")
         | 
| 32 31 | 
             
                  else
         | 
| @@ -30,7 +30,13 @@ module Geocoder::Lookup | |
| 30 30 | 
             
                def results(query)
         | 
| 31 31 | 
             
                  if configuration[:file]
         | 
| 32 32 | 
             
                    geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP
         | 
| 33 | 
            -
                     | 
| 33 | 
            +
                    geoip_instance = geoip_class.new(configuration[:file])
         | 
| 34 | 
            +
                    result =
         | 
| 35 | 
            +
                      if configuration[:package] == :country
         | 
| 36 | 
            +
                        geoip_instance.country(query.to_s)
         | 
| 37 | 
            +
                      else
         | 
| 38 | 
            +
                        geoip_instance.city(query.to_s)
         | 
| 39 | 
            +
                      end
         | 
| 34 40 | 
             
                    result.nil? ? [] : [encode_hash(result.to_hash)]
         | 
| 35 41 | 
             
                  elsif configuration[:package] == :city
         | 
| 36 42 | 
             
                    addr = IPAddr.new(query.text).to_i
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'geocoder/lookups/base'
         | 
| 2 | 
            +
            require "geocoder/results/melissa_street"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Geocoder::Lookup
         | 
| 5 | 
            +
              class MelissaStreet < Base
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def name
         | 
| 8 | 
            +
                  "MelissaStreet"
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def results(query)
         | 
| 12 | 
            +
                  return [] unless doc = fetch_data(query)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  if doc["TransmissionResults"] == "GE05"
         | 
| 15 | 
            +
                    raise_error(Geocoder::InvalidApiKey) ||
         | 
| 16 | 
            +
                      Geocoder.log(:warn, "Melissa service error: invalid API key.")
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  return doc["Records"]
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                private # ---------------------------------------------------------------
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def base_query_url(query)
         | 
| 25 | 
            +
                  "#{protocol}://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress?"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def query_url_params(query)
         | 
| 29 | 
            +
                  params = {
         | 
| 30 | 
            +
                    id: configuration.api_key,
         | 
| 31 | 
            +
                    format: "JSON",
         | 
| 32 | 
            +
                    a1: query.sanitized_text,
         | 
| 33 | 
            +
                    loc: query.options[:city],
         | 
| 34 | 
            +
                    admarea: query.options[:state],
         | 
| 35 | 
            +
                    postal: query.options[:postal],
         | 
| 36 | 
            +
                    ctry: query.options[:country]
         | 
| 37 | 
            +
                  }
         | 
| 38 | 
            +
                  params.merge(super)
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,89 @@ | |
| 1 | 
            +
            require 'geocoder/lookups/base'
         | 
| 2 | 
            +
            require 'geocoder/results/photon'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Geocoder::Lookup
         | 
| 5 | 
            +
              class Photon < Base
         | 
| 6 | 
            +
                def name
         | 
| 7 | 
            +
                  'Photon'
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                private # ---------------------------------------------------------------
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def supported_protocols
         | 
| 13 | 
            +
                  [:https]
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def base_query_url(query)
         | 
| 17 | 
            +
                  host = configuration[:host] || 'photon.komoot.io'
         | 
| 18 | 
            +
                  method = query.reverse_geocode? ? 'reverse' : 'api'
         | 
| 19 | 
            +
                  "#{protocol}://#{host}/#{method}?"
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def results(query)
         | 
| 23 | 
            +
                  return [] unless (doc = fetch_data(query))
         | 
| 24 | 
            +
                  return [] unless doc['type'] == 'FeatureCollection'
         | 
| 25 | 
            +
                  return [] unless doc['features'] || doc['features'].present?
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  doc['features']
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def query_url_params(query)
         | 
| 31 | 
            +
                  lang = query.language || configuration.language
         | 
| 32 | 
            +
                  params = { lang: lang, limit: query.options[:limit] }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  if query.reverse_geocode?
         | 
| 35 | 
            +
                    params.merge!(query_url_params_reverse(query))
         | 
| 36 | 
            +
                  else
         | 
| 37 | 
            +
                    params.merge!(query_url_params_coordinates(query))
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  params.merge!(super)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def query_url_params_coordinates(query)
         | 
| 44 | 
            +
                  params = { q: query.sanitized_text }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  if (bias = query.options[:bias])
         | 
| 47 | 
            +
                    params.merge!(lat: bias[:latitude], lon: bias[:longitude], location_bias_scale: bias[:scale])
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  if (filter = query_url_params_coordinates_filter(query))
         | 
| 51 | 
            +
                    params.merge!(filter)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  params
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def query_url_params_coordinates_filter(query)
         | 
| 58 | 
            +
                  filter = query.options[:filter]
         | 
| 59 | 
            +
                  return unless filter
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  bbox = filter[:bbox]
         | 
| 62 | 
            +
                  {
         | 
| 63 | 
            +
                    bbox: bbox.is_a?(Array) ? bbox.join(',') : bbox,
         | 
| 64 | 
            +
                    osm_tag: filter[:osm_tag]
         | 
| 65 | 
            +
                  }
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                def query_url_params_reverse(query)
         | 
| 69 | 
            +
                  params = { lat: query.coordinates[0], lon: query.coordinates[1], radius: query.options[:radius] }
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  if (dsort = query.options[:distance_sort])
         | 
| 72 | 
            +
                    params[:distance_sort] = dsort ? 'true' : 'false'
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  if (filter = query_url_params_reverse_filter(query))
         | 
| 76 | 
            +
                    params.merge!(filter)
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  params
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def query_url_params_reverse_filter(query)
         | 
| 83 | 
            +
                  filter = query.options[:filter]
         | 
| 84 | 
            +
                  return unless filter
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  { query_string_filter: filter[:string] }
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
            end
         | 
| @@ -57,7 +57,12 @@ module Geocoder::Lookup | |
| 57 57 | 
             
                end
         | 
| 58 58 |  | 
| 59 59 | 
             
                def results(query)
         | 
| 60 | 
            -
                  fetch_data(query) || []
         | 
| 60 | 
            +
                  doc = fetch_data(query) || []
         | 
| 61 | 
            +
                  if doc.is_a?(Hash) and doc.key?('status') # implies there's an error
         | 
| 62 | 
            +
                    return []
         | 
| 63 | 
            +
                  else
         | 
| 64 | 
            +
                    return doc
         | 
| 65 | 
            +
                  end
         | 
| 61 66 | 
             
                end
         | 
| 62 67 | 
             
              end
         | 
| 63 68 | 
             
            end
         | 
| @@ -16,7 +16,7 @@ module Geocoder::Lookup | |
| 16 16 | 
             
                  if configuration[:host]
         | 
| 17 17 | 
             
                    "#{protocol}://#{configuration[:host]}/location/#{query.sanitized_text}"
         | 
| 18 18 | 
             
                  else
         | 
| 19 | 
            -
                    "#{protocol}://telize-v1.p. | 
| 19 | 
            +
                    "#{protocol}://telize-v1.p.rapidapi.com/location/#{query.sanitized_text}?rapidapi-key=#{api_key}"
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| @@ -33,8 +33,7 @@ module Geocoder::Lookup | |
| 33 33 | 
             
                    return []
         | 
| 34 34 | 
             
                  end
         | 
| 35 35 | 
             
                  if doc = doc['response']['GeoObjectCollection']
         | 
| 36 | 
            -
                     | 
| 37 | 
            -
                    return meta['found'].to_i > 0 ? doc['featureMember'] : []
         | 
| 36 | 
            +
                    return doc['featureMember'].to_a
         | 
| 38 37 | 
             
                  else
         | 
| 39 38 | 
             
                    Geocoder.log(:warn, "Yandex Geocoding API error: unexpected response format.")
         | 
| 40 39 | 
             
                    return []
         | 
| @@ -0,0 +1,146 @@ | |
| 1 | 
            +
            require 'geocoder/results/base'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Geocoder
         | 
| 4 | 
            +
              module Result
         | 
| 5 | 
            +
                class AbstractApi < Base
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  ##
         | 
| 8 | 
            +
                  # Geolocation
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def state
         | 
| 11 | 
            +
                    @data['region']
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def state_code
         | 
| 15 | 
            +
                    @data['region_iso_code']
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def city
         | 
| 19 | 
            +
                    @data["city"]
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def city_geoname_id
         | 
| 23 | 
            +
                    @data["city_geoname_id"]
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def region_geoname_id
         | 
| 27 | 
            +
                    @data["region_geoname_id"]
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def postal_code
         | 
| 31 | 
            +
                    @data["postal_code"]
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def country
         | 
| 35 | 
            +
                    @data["country"]
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def country_code
         | 
| 39 | 
            +
                    @data["country_code"]
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def country_geoname_id
         | 
| 43 | 
            +
                    @data["country_geoname_id"]
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def country_is_eu
         | 
| 47 | 
            +
                    @data["country_is_eu"]
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def continent
         | 
| 51 | 
            +
                    @data["continent"]
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def continent_code
         | 
| 55 | 
            +
                    @data["continent_code"]
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def continent_geoname_id
         | 
| 59 | 
            +
                    @data["continent_geoname_id"]
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  ##
         | 
| 63 | 
            +
                  # Security
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def is_vpn?
         | 
| 66 | 
            +
                    @data.dig "security", "is_vpn"
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  ##
         | 
| 70 | 
            +
                  # Timezone
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def timezone_name
         | 
| 73 | 
            +
                    @data.dig "timezone", "name"
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  def timezone_abbreviation
         | 
| 77 | 
            +
                    @data.dig "timezone", "abbreviation"
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  def timezone_gmt_offset
         | 
| 81 | 
            +
                    @data.dig "timezone", "gmt_offset"
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  def timezone_current_time
         | 
| 85 | 
            +
                    @data.dig "timezone", "current_time"
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  def timezone_is_dst
         | 
| 89 | 
            +
                    @data.dig "timezone", "is_dst"
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  ##
         | 
| 93 | 
            +
                  # Flag
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  def flag_emoji
         | 
| 96 | 
            +
                    @data.dig "flag", "emoji"
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  def flag_unicode
         | 
| 100 | 
            +
                    @data.dig "flag", "unicode"
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  def flag_png
         | 
| 104 | 
            +
                    @data.dig "flag", "png"
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  def flag_svg
         | 
| 108 | 
            +
                    @data.dig "flag", "svg"
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  ##
         | 
| 112 | 
            +
                  # Currency
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  def currency_currency_name
         | 
| 115 | 
            +
                    @data.dig "currency", "currency_name"
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  def currency_currency_code
         | 
| 119 | 
            +
                    @data.dig "currency", "currency_code"
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  ##
         | 
| 123 | 
            +
                  # Connection
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  def connection_autonomous_system_number
         | 
| 126 | 
            +
                    @data.dig "connection", "autonomous_system_number"
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  def connection_autonomous_system_organization
         | 
| 130 | 
            +
                    @data.dig "connection", "autonomous_system_organization"
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                  def connection_connection_type
         | 
| 134 | 
            +
                    @data.dig "connection", "connection_type"
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  def connection_isp_name
         | 
| 138 | 
            +
                    @data.dig "connection", "isp_name"
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  def connection_organization_name
         | 
| 142 | 
            +
                    @data.dig "connection", "organization_name"
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            require 'geocoder/results/base'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Geocoder::Result
         | 
| 4 | 
            +
              class AmazonLocationService < Base
         | 
| 5 | 
            +
                def initialize(result)
         | 
| 6 | 
            +
                  @place = result
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def coordinates
         | 
| 10 | 
            +
                  [@place.geometry.point[1], @place.geometry.point[0]]
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def address
         | 
| 14 | 
            +
                  @place.label
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def neighborhood
         | 
| 18 | 
            +
                  @place.neighborhood
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def route
         | 
| 22 | 
            +
                  @place.street
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def city
         | 
| 26 | 
            +
                  @place.municipality || @place.sub_region
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def state
         | 
| 30 | 
            +
                  @place.region
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def state_code
         | 
| 34 | 
            +
                  @place.region
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def province
         | 
| 38 | 
            +
                  @place.region
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def province_code
         | 
| 42 | 
            +
                  @place.region
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def postal_code
         | 
| 46 | 
            +
                  @place.postal_code
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def country
         | 
| 50 | 
            +
                  @place.country
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def country_code
         | 
| 54 | 
            +
                  @place.country
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| @@ -4,6 +4,27 @@ require 'geocoder/results/base' | |
| 4 4 | 
             
            module Geocoder::Result
         | 
| 5 5 | 
             
              class BanDataGouvFr < Base
         | 
| 6 6 |  | 
| 7 | 
            +
                STATE_CODE_MAPPINGS = {
         | 
| 8 | 
            +
                  "Guadeloupe" => "01",
         | 
| 9 | 
            +
                  "Martinique" => "02",
         | 
| 10 | 
            +
                  "Guyane" => "03",
         | 
| 11 | 
            +
                  "La Réunion" => "04",
         | 
| 12 | 
            +
                  "Mayotte" => "06",
         | 
| 13 | 
            +
                  "Île-de-France" => "11",
         | 
| 14 | 
            +
                  "Centre-Val de Loire" => "24",
         | 
| 15 | 
            +
                  "Bourgogne-Franche-Comté" => "27",
         | 
| 16 | 
            +
                  "Normandie" => "28",
         | 
| 17 | 
            +
                  "Hauts-de-France" => "32",
         | 
| 18 | 
            +
                  "Grand Est" => "44",
         | 
| 19 | 
            +
                  "Pays de la Loire" => "52",
         | 
| 20 | 
            +
                  "Bretagne" => "53",
         | 
| 21 | 
            +
                  "Nouvelle-Aquitaine" => "75",
         | 
| 22 | 
            +
                  "Occitanie" => "76",
         | 
| 23 | 
            +
                  "Auvergne-Rhône-Alpes" => "84",
         | 
| 24 | 
            +
                  "Provence-Alpes-Côte d'Azur" => "93",
         | 
| 25 | 
            +
                  "Corse" => "94"
         | 
| 26 | 
            +
                }.freeze
         | 
| 27 | 
            +
             | 
| 7 28 | 
             
                #### BASE METHODS ####
         | 
| 8 29 |  | 
| 9 30 | 
             
                def self.response_attributes
         | 
| @@ -209,6 +230,10 @@ module Geocoder::Result | |
| 209 230 | 
             
                  end
         | 
| 210 231 | 
             
                end
         | 
| 211 232 |  | 
| 233 | 
            +
                def region_code
         | 
| 234 | 
            +
                  STATE_CODE_MAPPINGS[region_name]
         | 
| 235 | 
            +
                end
         | 
| 236 | 
            +
             | 
| 212 237 | 
             
                def country
         | 
| 213 238 | 
             
                  "France"
         | 
| 214 239 | 
             
                end
         | 
| @@ -235,7 +260,7 @@ module Geocoder::Result | |
| 235 260 | 
             
                alias_method :street, :street_name
         | 
| 236 261 | 
             
                alias_method :city, :city_name
         | 
| 237 262 | 
             
                alias_method :state, :region_name
         | 
| 238 | 
            -
                alias_method :state_code, : | 
| 263 | 
            +
                alias_method :state_code, :region_code
         | 
| 239 264 |  | 
| 240 265 | 
             
                #### CITIES' METHODS ####
         | 
| 241 266 |  | 
| @@ -16,11 +16,14 @@ module Geocoder::Result | |
| 16 16 | 
             
                  end
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 | 
            -
                def  | 
| 19 | 
            +
                def state
         | 
| 20 20 | 
             
                  attributes['Region']
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 | 
            -
                 | 
| 23 | 
            +
                def state_code
         | 
| 24 | 
            +
                  abbr = attributes['RegionAbbr']
         | 
| 25 | 
            +
                  abbr.to_s == "" ? state : abbr
         | 
| 26 | 
            +
                end
         | 
| 24 27 |  | 
| 25 28 | 
             
                def country
         | 
| 26 29 | 
             
                  country_key = reverse_geocode? ? "CountryCode" : "Country"
         |