class Zipcoder::Cacher::Base

Constants

KEY_BASE
KEY_CITY
KEY_COUNTY
KEY_STATES
KEY_STATE_CITIES
KEY_STATE_COUNTIES
KEY_ZIP

Attributes

loaded[RW]

Public Class Methods

new(**kwargs) click to toggle source

endregion

# File lib/zipcoder/cacher/base.rb, line 94
def initialize(**kwargs)
  self._init_cache **kwargs
  self.loaded = false
end

Public Instance Methods

_empty_cache() click to toggle source
# File lib/zipcoder/cacher/base.rb, line 76
def _empty_cache
  # Override ME
end
_init_cache(**kwargs) click to toggle source

region Override These

# File lib/zipcoder/cacher/base.rb, line 72
def _init_cache(**kwargs)
  # Override ME
end
_iterate_keys(**kwargs, &block) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 88
def _iterate_keys(**kwargs, &block)
  # Override ME
end
_read_cache(key) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 84
def _read_cache(key)
  # Override ME
end
_write_cache(key, value) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 80
def _write_cache(key, value)
  # Override ME
end
iterate_cities(&block) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 205
def iterate_cities(&block)
  return if block == nil
  _iterate_keys(start_with: "zipcoder:city") do |key|
    info = _read_cache(key)
    block.call(info) if block != nil
  end
end
iterate_zips(&block) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 197
def iterate_zips(&block)
  return if block == nil
  _iterate_keys(start_with: "zipcoder:zip") do |key|
    info = _read_cache(key)
    block.call(info) if block != nil
  end
end
load(data: nil) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 99
def load(data: nil)
  return if self.loaded

  start_time = Time.now

  # Load zip cache from file
  if data != nil
    zip_data = File.open(data)
  else
    this_dir = File.expand_path(File.dirname(__FILE__))
    zip_data = File.join(this_dir, '..', '..', 'data', 'data.yml' )
  end
  zip_codes = YAML.load(File.open(zip_data))

  # Initialize
  _empty_cache
  city_states = {}
  state_cities_lookup = {}
  state_counties_lookup = {}

  # Add the zip codes to the cache
  zip_codes.each do |zip, cities|
    cities.each do |info|
      city = info[:city]
      state = info[:state]

      # For the zip codes, only store the primary
      if info[:primary]
        _write_cache _zip_cache(zip), info
      end

      # Create the city lookups
      city_state = "#{city.upcase},#{state.upcase}"
      infos = city_states[city_state] || []
      infos << info
      city_states[city_state] = infos
    end
  end

  # Normalize each city and populate the state cache
  city_states.each do |city_state, infos|
    city = infos[0][:city]
    state = infos[0][:state]

    # Populate the City Cache
    normalized = _normalize_city(infos)
    _write_cache _city_cache(city_state), normalized

    # Populate the State City Cache
    cities = state_cities_lookup[state] || []
    cities << city
    state_cities_lookup[state] = cities

    # Populate the State Counties Cache
    counties = state_counties_lookup[state] || []
    counties += normalized[:county].split(",")
    state_counties_lookup[state] = counties
  end

  # Set the cities cache
  state_cities_lookup.each do |state, cities|
    _write_cache _state_cities_cache(state), cities.sort
  end

  # Set the cities cache
  state_counties_lookup.each do |state, counties|
    _write_cache _state_counties_cache(state), counties.sort.uniq
  end

  # Set the states cache
  self._write_cache _states, state_cities_lookup.keys.sort

  # Print the alpsed time
  puts "ZipCoder initialization time: #{Time.now-start_time}"

  self.loaded = true
end
read_city_cache(city_state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 181
def read_city_cache(city_state)
  _read_cache _city_cache(city_state)
end
read_state_cities_cache(state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 185
def read_state_cities_cache(state)
  _read_cache _state_cities_cache(state)
end
read_state_counties_cache(state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 189
def read_state_counties_cache(state)
  _read_cache _state_counties_cache(state)
end
read_states() click to toggle source
# File lib/zipcoder/cacher/base.rb, line 193
def read_states
  _read_cache _states
end
read_zip_cache(zip) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 177
def read_zip_cache(zip)
  _read_cache _zip_cache(zip)
end

Private Instance Methods

_city_cache(city_state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 219
def _city_cache(city_state)
  "#{KEY_CITY}:#{city_state}"
end
_normalize_city(infos) click to toggle source

Normalizes the values

# File lib/zipcoder/cacher/base.rb, line 236
def _normalize_city(infos)
  # Values
  zips = []
  counties = []
  lat_min = 200
  lat_max = -200
  long_min = 200
  long_max = -200

  # Iterate through the info and get min/max of zip/lat/long
  infos.each do |info|
    if info[:primary]
      lat_min = info[:lat] if info[:lat] < lat_min
      lat_max = info[:lat] if info[:lat] > lat_max
      long_min = info[:long] if info[:long] < long_min
      long_max = info[:long] if info[:long] > long_max
    end
    zips << info[:zip]
    counties += info[:county].split(",")
  end

  # Create the normalized value
  if infos.count == 0
    normalized = nil
  elsif infos.count == 1
    normalized = {
        city: infos[0][:city],
        county: infos[0][:county],
        state: infos[0][:state],
        zip: infos[0][:zip],
        lat: infos[0][:lat],
        long: infos[0][:long],
    }
  else
    normalized = {
        city: infos[0][:city],
        county: counties.uniq.join(","),
        state: infos[0][:state],
        zip: zips.combine_zips,
        lat: ((lat_min+lat_max)/2).round(4),
        long: ((long_min+long_max)/2).round(4)
    }
  end

  normalized
end
_state_cities_cache(state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 223
def _state_cities_cache(state)
  "#{KEY_STATE_CITIES}:#{state}"
end
_state_counties_cache(state) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 227
def _state_counties_cache(state)
  "#{KEY_STATE_COUNTIES}:#{state}"
end
_states() click to toggle source
# File lib/zipcoder/cacher/base.rb, line 231
def _states
  KEY_STATES
end
_zip_cache(zip) click to toggle source
# File lib/zipcoder/cacher/base.rb, line 215
def _zip_cache(zip)
  "#{KEY_ZIP}:#{zip}"
end