Module: Geocoder::Store::ActiveRecord

Includes:
Base
Defined in:
lib/geocoder/stores/active_record.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Base

#bearing_from, #bearing_to, #distance_to, #geocoded?, #to_coordinates

Class Method Details

.included(base) ⇒ Object

Implementation of 'included' hook method.


15
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
# File 'lib/geocoder/stores/active_record.rb', line 15

def self.included(base)
  base.extend ClassMethods
  base.class_eval do

    # scope: geocoded objects
    scope :geocoded, lambda {
      where("#{table_name}.#{geocoder_options[:latitude]} IS NOT NULL " +
        "AND #{table_name}.#{geocoder_options[:longitude]} IS NOT NULL")
    }

    # scope: not-geocoded objects
    scope :not_geocoded, lambda {
      where("#{table_name}.#{geocoder_options[:latitude]} IS NULL " +
        "OR #{table_name}.#{geocoder_options[:longitude]} IS NULL")
    }

    # scope: not-reverse geocoded objects
    scope :not_reverse_geocoded, lambda {
      where("#{table_name}.#{geocoder_options[:fetched_address]} IS NULL")
    }

    ##
    # Find all objects within a radius of the given location.
    # Location may be either a string to geocode or an array of
    # coordinates (<tt>[lat,lon]</tt>). Also takes an options hash
    # (see Geocoder::Store::ActiveRecord::ClassMethods.near_scope_options
    # for details).
    #
    scope :near, lambda{ |location, *args|
      latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
      if Geocoder::Calculations.coordinates_present?(latitude, longitude)
        options = near_scope_options(latitude, longitude, *args)
        select(options[:select]).where(options[:conditions]).
          order(options[:order])
      else
        # If no lat/lon given we don't want any results, but we still
        # need distance and bearing columns so you can add, for example:
        # .order("distance")
        select(select_clause(nil, null_value, null_value)).where(false_condition)
      end
    }

    ##
    # Find all objects within the area of a given bounding box.
    # Bounds must be an array of locations specifying the southwest
    # corner followed by the northeast corner of the box
    # (<tt>[[sw_lat, sw_lon], [ne_lat, ne_lon]]</tt>).
    #
    scope :within_bounding_box, lambda{ |*bounds|
      sw_lat, sw_lng, ne_lat, ne_lng = bounds.flatten if bounds
      if sw_lat && sw_lng && ne_lat && ne_lng
        where(Geocoder::Sql.within_bounding_box(
          sw_lat, sw_lng, ne_lat, ne_lng,
          full_column_name(geocoder_options[:latitude]),
          full_column_name(geocoder_options[:longitude])
        ))
      else
        select(select_clause(nil, null_value, null_value)).where(false_condition)
      end
    }
  end
end

Instance Method Details

#geocodeObject Also known as: fetch_coordinates

Look up coordinates and assign to latitude and longitude attributes (or other as specified in geocoded_by). Returns coordinates (array).


297
298
299
300
301
302
303
304
305
306
307
# File 'lib/geocoder/stores/active_record.rb', line 297

def geocode
  do_lookup(false) do |o,rs|
    if r = rs.first
      unless r.latitude.nil? or r.longitude.nil?
        o.__send__  "#{self.class.geocoder_options[:latitude]}=",  r.latitude
        o.__send__  "#{self.class.geocoder_options[:longitude]}=", r.longitude
      end
      r.coordinates
    end
  end
end

#nearbys(radius = 20, options = {}) ⇒ Object

Get nearby geocoded objects. Takes the same options hash as the near class method (scope). Returns nil if the object is not geocoded.


287
288
289
290
291
# File 'lib/geocoder/stores/active_record.rb', line 287

def nearbys(radius = 20, options = {})
  return nil unless geocoded?
  options.merge!(:exclude => self) unless send(self.class.primary_key).nil?
  self.class.near(self, radius, options)
end

#reverse_geocodeObject Also known as: fetch_address

Look up address and assign to address attribute (or other as specified in reverse_geocoded_by). Returns address (string).


315
316
317
318
319
320
321
322
323
324
# File 'lib/geocoder/stores/active_record.rb', line 315

def reverse_geocode
  do_lookup(true) do |o,rs|
    if r = rs.first
      unless r.address.nil?
        o.__send__ "#{self.class.geocoder_options[:fetched_address]}=", r.address
      end
      r.address
    end
  end
end