From f7dec053589d8e2f83c28b8192552a7566b0eff0 Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Thu, 24 Mar 2011 23:07:48 -0400 Subject: [PATCH] Rename method and move to Calculations module. --- lib/geocoder/calculations.rb | 21 +++++++++++++++++++++ lib/geocoder/orms/active_record.rb | 18 ++---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb index 0a9b553e..84f4e339 100644 --- a/lib/geocoder/calculations.rb +++ b/lib/geocoder/calculations.rb @@ -147,6 +147,27 @@ module Geocoder to_degrees [lat, lon] end + ## + # Returns coordinates of the lower-left and upper-right corners of a box + # with the given point at its center. The radius is the shortest distance + # from the center point to any side of the box (the length of each side + # is twice the radius). + # + # This is useful for finding corner points of a map viewport, or for + # 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 + [ + 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)) + ] + end + ## # Convert degrees to radians. # If an array (or multiple arguments) is passed, diff --git a/lib/geocoder/orms/active_record.rb b/lib/geocoder/orms/active_record.rb index ad00e2d5..9dec1d4b 100644 --- a/lib/geocoder/orms/active_record.rb +++ b/lib/geocoder/orms/active_record.rb @@ -172,9 +172,10 @@ 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) conditions = \ ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] + - coordinate_bounds(latitude, longitude, radius) + [b[0], b[2], b[1], b[3]] if obj = options[:exclude] conditions[0] << " AND #{table_name}.id != ?" conditions << obj.id @@ -187,21 +188,6 @@ module Geocoder::Orm :conditions => conditions } end - - ## - # Get the rough high/low lat/long bounds for a geographic point and - # radius. Returns an array: <tt>[lat_lo, lat_hi, lon_lo, lon_hi]</tt>. - # Used to constrain search to a (radius x radius) square. - # - def coordinate_bounds(latitude, longitude, radius, units = :mi) - radius = radius.to_f - [ - latitude - (radius / Geocoder::Calculations.latitude_degree_distance(units)), - latitude + (radius / Geocoder::Calculations.latitude_degree_distance(units)), - longitude - (radius / Geocoder::Calculations.longitude_degree_distance(latitude, units)), - longitude + (radius / Geocoder::Calculations.longitude_degree_distance(latitude, units)) - ] - end end ## -- GitLab