From 1a4d501c00cbc032da3d032c3cc3022a59af59f4 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Thu, 1 Oct 2009 00:54:35 -0400
Subject: [PATCH] Add 'nearbys' instance method.

---
 README.rdoc     |  1 +
 lib/geocoder.rb | 34 ++++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/README.rdoc b/README.rdoc
index 1987b505..6c93dbf7 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -43,6 +43,7 @@ Assuming +obj+ has a valid string for its +location+:
 
   obj.fetch_coordinates              # returns coordinates [lat, lon]
   obj.fetch_and_assign_coordinates   # writes values to object
+  obj.nearbys(30)                    # gets other objects within given radius
 
 Find distance between object and a point:
 
diff --git a/lib/geocoder.rb b/lib/geocoder.rb
index 576c1fdc..82f95ee5 100644
--- a/lib/geocoder.rb
+++ b/lib/geocoder.rb
@@ -110,6 +110,22 @@ module Geocoder
       defined?(@geocoder_longitude_attr) ?
         @geocoder_longitude_attr : :longitude
     end
+    
+    ##
+    # Get the coordinates [lat,lon] of an object.
+    # This seems cleaner than polluting the object method namespace.
+    #
+    def get_coordinates_of(object)
+      [object.send(geocoder_latitude_attr),
+      object.send(geocoder_longitude_attr)]
+    end
+  end
+  
+  ##
+  # Is this object geocoded? (Does it have latitude and longitude?)
+  #
+  def geocoded?
+    self.class.get_coordinates_of(self).compact.size > 0
   end
   
   ##
@@ -117,14 +133,24 @@ module Geocoder
   # are defined in <tt>distance_between</tt> class method.
   #
   def distance_to(lat, lon, units = :mi)
-    mylat = read_attribute(self.class.geocoder_latitude_attr)
-    mylon = read_attribute(self.class.geocoder_longitude_attr)
+    return nil unless geocoded?
+    mylat,mylon = self.class.get_coordinates_of(self)
     Geocoder.distance_between(mylat, mylon, lat, lon, :units => units)
   end
   
   ##
-  # Fetch coordinates based on the object's location. Returns an
-  # array <tt>[lat,lon]</tt>.
+  # Get other geocoded objects within a given radius.
+  # The object must be geocoded before this method is called.
+  #
+  def nearbys(radius = 20)
+    return [] unless geocoded?
+    lat,lon = self.class.get_coordinates_of(self)
+    self.class.find_near([lat, lon], radius) - [self]
+  end
+  
+  ##
+  # Fetch coordinates based on the object's location.
+  # Returns an array <tt>[lat,lon]</tt>.
   #
   def fetch_coordinates
     location = read_attribute(self.class.geocoder_method_name)
-- 
GitLab