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).



274
275
276
277
278
279
280
281
282
283
284
# File 'lib/geocoder/stores/active_record.rb', line 274

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.



264
265
266
267
268
# File 'lib/geocoder/stores/active_record.rb', line 264

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).



292
293
294
295
296
297
298
299
300
301
# File 'lib/geocoder/stores/active_record.rb', line 292

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