From d6fb334846dbff623a5e48d5c76cea32683a5a37 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Tue, 5 Apr 2011 14:27:17 -0400
Subject: [PATCH] Change bounding_box argument format.

---
 lib/geocoder/calculations.rb       | 26 +++++++++++++++++------
 lib/geocoder/orms/active_record.rb |  2 +-
 test/geocoder_test.rb              | 34 ++++++++++++++++++++++++++----
 3 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb
index 292b559b..7aa0b4b0 100644
--- a/lib/geocoder/calculations.rb
+++ b/lib/geocoder/calculations.rb
@@ -185,14 +185,26 @@ module Geocoder
     # roughly limiting the possible solutions in a geo-spatial search
     # (ActiveRecord queries use it thusly).
     #
-    def bounding_box(latitude, longitude, radius, options = {})
-      units = options[:units] || :mi
-      radius = radius.to_f
+    # See Geocoder::Calculations.distance_between for
+    # ways of specifying the point. Also accepts an options hash:
+    #
+    # * <tt>:units</tt> - <tt>:mi</tt> (default) or <tt>:km</tt>
+    #
+    def bounding_box(point, radius, options = {}, *args)
+      if point.is_a?(Numeric)
+        warn "DEPRECATION WARNING: Instead of passing latitude/longitude as separate arguments to the bounding_box method, please pass an array [#{point},#{radius}], a geocoded object, or a geocodable address (string). The old argument format will not be supported in Geocoder v.1.0."
+        point   = [point, radius]
+        radius  = options
+        options = args.first || {}
+      end
+      lat,lon = extract_coordinates(point)
+      radius  = radius.to_f
+      units   = options[:units] || :mi
       [
-        latitude  - (radius / latitude_degree_distance(units)),
-        longitude - (radius / longitude_degree_distance(latitude, units)),
-        latitude  + (radius / latitude_degree_distance(units)),
-        longitude + (radius / longitude_degree_distance(latitude, units))
+        lat - (radius / latitude_degree_distance(units)),
+        lon - (radius / longitude_degree_distance(lat, units)),
+        lat + (radius / latitude_degree_distance(units)),
+        lon + (radius / longitude_degree_distance(lat, units))
       ]
     end
 
diff --git a/lib/geocoder/orms/active_record.rb b/lib/geocoder/orms/active_record.rb
index 615b044f..69c4d2d4 100644
--- a/lib/geocoder/orms/active_record.rb
+++ b/lib/geocoder/orms/active_record.rb
@@ -171,7 +171,7 @@ module Geocoder::Orm
       def default_near_scope_options(latitude, longitude, radius, options)
         lat_attr = geocoder_options[:latitude]
         lon_attr = geocoder_options[:longitude]
-        b = Geocoder::Calculations.bounding_box(latitude, longitude, radius, options)
+        b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
         conditions = \
           ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
           [b[0], b[2], b[1], b[3]]
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index 3cc67138..264647e2 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -145,7 +145,7 @@ class GeocoderTest < Test::Unit::TestCase
   end
 
 
-  # --- calcluations ---
+  # --- calculations: degree distance ---
 
   def test_longitude_degree_distance_at_equator
     assert_equal 69, Geocoder::Calculations.longitude_degree_distance(0).round
@@ -159,6 +159,9 @@ class GeocoderTest < Test::Unit::TestCase
     assert_equal 0, Geocoder::Calculations.longitude_degree_distance(89.98).round
   end
 
+
+  # --- calculations: distance between ---
+
   def test_distance_between_in_miles
     assert_equal 69, Geocoder::Calculations.distance_between([0,0], [0,1]).round
     la_to_ny = Geocoder::Calculations.distance_between([34.05,-118.25], [40.72,-74]).round
@@ -171,6 +174,9 @@ class GeocoderTest < Test::Unit::TestCase
     assert (la_to_ny - 3942).abs < 10
   end
 
+
+  # --- calculations: geographic center ---
+
   def test_geographic_center_with_arrays
     assert_equal [0.0, 0.5],
       Geocoder::Calculations.geographic_center([[0,0], [0,1]])
@@ -184,6 +190,9 @@ class GeocoderTest < Test::Unit::TestCase
     assert_equal [0.0, 0.5], Geocoder::Calculations.geographic_center([p1, p2])
   end
 
+
+  # --- calculations: bounding box ---
+
   def test_bounding_box_calculation_in_miles
     center = [51, 7] # Cologne, DE
     radius = 10 # miles
@@ -191,7 +200,7 @@ class GeocoderTest < Test::Unit::TestCase
     dlat = radius / Geocoder::Calculations.longitude_degree_distance(center[0])
     corners = [50.86, 6.77, 51.14, 7.23]
     assert_equal corners.map{ |i| (i * 100).round },
-      Geocoder::Calculations.bounding_box(center[0], center[1], radius).map{ |i| (i * 100).round }
+      Geocoder::Calculations.bounding_box(center, radius).map{ |i| (i * 100).round }
   end
 
   def test_bounding_box_calculation_in_kilometers
@@ -201,11 +210,28 @@ class GeocoderTest < Test::Unit::TestCase
     dlat = radius / Geocoder::Calculations.longitude_degree_distance(center[0], :km)
     corners = [50, 5.41, 52, 8.59]
     assert_equal corners.map{ |i| (i * 100).round },
-      Geocoder::Calculations.bounding_box(center[0], center[1], radius, :units => :km).map{ |i| (i * 100).round }
+      Geocoder::Calculations.bounding_box(center, radius, :units => :km).map{ |i| (i * 100).round }
+  end
+
+  def test_bounding_box_calculation_with_object
+    center = [51, 7] # Cologne, DE
+    radius = 10 # miles
+    dlon = radius / Geocoder::Calculations.latitude_degree_distance
+    dlat = radius / Geocoder::Calculations.longitude_degree_distance(center[0])
+    corners = [50.86, 6.77, 51.14, 7.23]
+    obj = Landmark.new("Cologne", center[0], center[1])
+    assert_equal corners.map{ |i| (i * 100).round },
+      Geocoder::Calculations.bounding_box(obj, radius).map{ |i| (i * 100).round }
+  end
+
+  def test_bounding_box_calculation_with_address_string
+    assert_nothing_raised do
+      Geocoder::Calculations.bounding_box("4893 Clay St, San Francisco, CA", 50)
+    end
   end
 
 
-  # --- bearing ---
+  # --- calculations: bearing ---
 
   def test_compass_points
     assert_equal "N",  Geocoder::Calculations.compass_point(0)
-- 
GitLab