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
# 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")
    }

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



269
270
271
272
273
274
275
276
277
278
279
# File 'lib/geocoder/stores/active_record.rb', line 269

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.



259
260
261
262
263
# File 'lib/geocoder/stores/active_record.rb', line 259

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



287
288
289
290
291
292
293
294
295
296
# File 'lib/geocoder/stores/active_record.rb', line 287

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