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