module Geocoder::Store::Base

def bearing_from(point, options = {})


ways of specifying the point.
See Geocoder::Calculations.distance_between for
Calculate the bearing from another point to the object.
#
def bearing_from(point, options = {})
  return nil unless geocoded?
  Geocoder::Calculations.bearing_between(
    point, to_coordinates, options)
end

def bearing_to(point, options = {})


ways of specifying the point.
See Geocoder::Calculations.distance_between for
Calculate the bearing from the object to another point.
#
def bearing_to(point, options = {})
  return nil unless geocoded?
  Geocoder::Calculations.bearing_between(
    to_coordinates, point, options)
end

def distance_to(point, units = :mi)


(:mi or :km; default is :mi).
the point. Also takes a symbol specifying the units
See Geocoder::Calculations.distance_between for ways of specifying
Calculate the distance from the object to an arbitrary point.
#
def distance_to(point, units = :mi)
  return nil unless geocoded?
  Geocoder::Calculations.distance_between(
    to_coordinates, point, :units => units)
end

def do_lookup(reverse = false)


Geocoder::Result objects).
given two-arguments: the object being geocoded and an array of
block (given to geocoded_by or reverse_geocoded_by). The block is
geocoded_by or reverse_geocoded_by) and handle the results with the
Look up geographic data based on object attributes (configured in
#
def do_lookup(reverse = false)
  options = self.class.geocoder_options
  if reverse and options[:reverse_geocode]
    query = to_coordinates
  elsif !reverse and options[:geocode]
    query = send(options[:user_address])
  else
    return
  end
  if (results = Geocoder.search(query)).size > 0
    # execute custom block, if specified in configuration
    block_key = reverse ? :reverse_block : :geocode_block
    if custom_block = options[block_key]
      custom_block.call(self, results)
    # else execute block passed directly to this method,
    # which generally performs the "auto-assigns"
    elsif block_given?
      yield(self, results)
    end
  end
end

def geocode


(or other as specified in +geocoded_by+). Returns coordinates (array).
Look up coordinates and assign to +latitude+ and +longitude+ attributes
#
def geocode
  fail
end

def geocoded?


Is this object geocoded? (Does it have latitude and longitude?)
#
def geocoded?
  to_coordinates.compact.size > 0
end

def nearbys(radius = 20, options = {})


Takes the same options hash as the near class method (scope).
Get nearby geocoded objects.
#
def nearbys(radius = 20, options = {})
  return [] unless geocoded?
  options.merge!(:exclude => self)
  self.class.near(self, radius, options)
end

def reverse_geocode


in +reverse_geocoded_by+). Returns address (string).
Look up address and assign to +address+ attribute (or other as specified
#
def reverse_geocode
  fail
end

def to_coordinates


Coordinates [lat,lon] of the object.
#
def to_coordinates
  [:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] }
end