class TelephoneNumber::GeoLocator

Attributes

locale[R]
location[R]
normalized_number[R]
phone_number[R]

Public Class Methods

new(phone_number, locale) click to toggle source

initialize with a phone_number object

# File lib/telephone_number/geo_locator.rb, line 6
def initialize(phone_number, locale)
  @phone_number = phone_number
  @normalized_number = build_normalized_number
  @locale = locale
end

Public Instance Methods

location_data() click to toggle source
# File lib/telephone_number/geo_locator.rb, line 16
def location_data
  @location_data ||= fetch_location_data
end

Private Instance Methods

build_normalized_number() click to toggle source

Google's geocoding data is odd in that it uses a non-standard format for lookups on countries that have a mobile token. In short, we need to remove it. See the link below for reference. github.com/googlei18n/libphonenumber/blob/master/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java#L121

# File lib/telephone_number/geo_locator.rb, line 52
def build_normalized_number
  return phone_number.e164_number(formatted: false) unless mobile_token = phone_number.country.mobile_token
  if phone_number.parser.normalized_number.start_with?(mobile_token)
    phone_number.e164_number(formatted: false).sub(mobile_token, '')
  else
    phone_number.e164_number(formatted: false)
  end
end
fetch_location_data() click to toggle source
# File lib/telephone_number/geo_locator.rb, line 29
def fetch_location_data
  return {} unless location_file = find_location_file
  Marshal.load(File.binread(location_file))
end
find_location() click to toggle source
# File lib/telephone_number/geo_locator.rb, line 22
def find_location
  number = normalized_number.dup
  location = nil
  (number.length - 2).times { break if location = location_data[number.chop!] }
  location
end
find_location_file() click to toggle source
# File lib/telephone_number/geo_locator.rb, line 34
def find_location_file
  locale_path = geocoding_path(locale)
  path = locale_path.empty? ? geocoding_path(:en) : locale_path

  path.sort { |a, b| b <=> a }.detect do |path|
    normalized_number.match?(/^#{File.basename(path, 'dat')}/)
  end
end
geocoding_path(locale) click to toggle source
# File lib/telephone_number/geo_locator.rb, line 43
def geocoding_path(locale)
  path = File.expand_path("../../../data/geocoding/#{locale}/*.dat", __FILE__)
  Dir.glob(path)
end