Permalink
Browse files

Removed unecessary module and some whitespace (so git will stop compl…

…aining).
  • Loading branch information...
1 parent cabe721 commit 3d2388854410afe55f4c4c68caec2daade13fc0c @josevalim josevalim committed Jun 3, 2009
Showing with 114 additions and 121 deletions.
  1. +114 −121 lib/geokit-rails/acts_as_mappable.rb
@@ -47,17 +47,19 @@ module ClassMethods # :nodoc:
# For anything more customized, we recommend you forgo the auto_geocode option
# and create your own AR callback to handle geocoding.
def acts_as_mappable(options = {})
+ metaclass = (class << self; self; end)
+
# Mix in the module, but ensure to do so just once.
- return if !defined?(Geokit::Mappable) || self.included_modules.include?(Geokit::ActsAsMappable::InstanceMethods)
+ return if !defined?(Geokit::Mappable) || metaclass.included_modules.include?(Geokit::ActsAsMappable::SingletonMethods)
- send :include, Geokit::ActsAsMappable::InstanceMethods
+ send :extend, Geokit::ActsAsMappable::SingletonMethods
send :include, Geokit::Mappable
cattr_accessor :through
self.through = options[:through]
if reflection = Geokit::ActsAsMappable.end_of_reflection_chain(self.through, self)
- (class << self; self; end).instance_eval do
+ metaclass.instance_eval do
[ :distance_column_name, :default_units, :default_formula, :lat_column_name, :lng_column_name, :qualified_lat_column_name, :qualified_lng_column_name ].each do |method_name|
define_method method_name do
reflection.klass.send(method_name)
@@ -104,7 +106,6 @@ def auto_geocode_address
geo.success
end
-
def self.end_of_reflection_chain(through, klass)
while through
reflection = nil
@@ -125,110 +126,104 @@ def self.end_of_reflection_chain(through, klass)
end
# Instance methods to mix into ActiveRecord.
- module InstanceMethods #:nodoc:
- # Mix class methods into module.
- def self.included(base) # :nodoc:
- base.extend SingletonMethods
+ module SingletonMethods #:nodoc:
+
+ # Extends the existing find method in potentially two ways:
+ # - If a mappable instance exists in the options, adds a distance column.
+ # - If a mappable instance exists in the options and the distance column exists in the
+ # conditions, substitutes the distance sql for the distance column -- this saves
+ # having to write the gory SQL.
+ def find(*args)
+ prepare_for_find_or_count(:find, args)
+ super(*args)
end
-
- # Class singleton methods to mix into ActiveRecord.
- module SingletonMethods # :nodoc:
- # Extends the existing find method in potentially two ways:
- # - If a mappable instance exists in the options, adds a distance column.
- # - If a mappable instance exists in the options and the distance column exists in the
- # conditions, substitutes the distance sql for the distance column -- this saves
- # having to write the gory SQL.
- def find(*args)
- prepare_for_find_or_count(:find, args)
- super(*args)
- end
-
- # Extends the existing count method by:
- # - If a mappable instance exists in the options and the distance column exists in the
- # conditions, substitutes the distance sql for the distance column -- this saves
- # having to write the gory SQL.
- def count(*args)
- prepare_for_find_or_count(:count, args)
- super(*args)
- end
-
- # Finds within a distance radius.
- def find_within(distance, options={})
- options[:within] = distance
- find(:all, options)
- end
- alias find_inside find_within
-
- # Finds beyond a distance radius.
- def find_beyond(distance, options={})
- options[:beyond] = distance
- find(:all, options)
- end
- alias find_outside find_beyond
-
- # Finds according to a range. Accepts inclusive or exclusive ranges.
- def find_by_range(range, options={})
- options[:range] = range
- find(:all, options)
- end
-
- # Finds the closest to the origin.
- def find_closest(options={})
- find(:nearest, options)
- end
- alias find_nearest find_closest
-
- # Finds the farthest from the origin.
- def find_farthest(options={})
- find(:farthest, options)
- end
- # Finds within rectangular bounds (sw,ne).
- def find_within_bounds(bounds, options={})
- options[:bounds] = bounds
- find(:all, options)
- end
-
- # counts within a distance radius.
- def count_within(distance, options={})
- options[:within] = distance
- count(options)
- end
- alias count_inside count_within
+ # Extends the existing count method by:
+ # - If a mappable instance exists in the options and the distance column exists in the
+ # conditions, substitutes the distance sql for the distance column -- this saves
+ # having to write the gory SQL.
+ def count(*args)
+ prepare_for_find_or_count(:count, args)
+ super(*args)
+ end
- # Counts beyond a distance radius.
- def count_beyond(distance, options={})
- options[:beyond] = distance
- count(options)
- end
- alias count_outside count_beyond
-
- # Counts according to a range. Accepts inclusive or exclusive ranges.
- def count_by_range(range, options={})
- options[:range] = range
- count(options)
- end
+ # Finds within a distance radius.
+ def find_within(distance, options={})
+ options[:within] = distance
+ find(:all, options)
+ end
+ alias find_inside find_within
+
+ # Finds beyond a distance radius.
+ def find_beyond(distance, options={})
+ options[:beyond] = distance
+ find(:all, options)
+ end
+ alias find_outside find_beyond
+
+ # Finds according to a range. Accepts inclusive or exclusive ranges.
+ def find_by_range(range, options={})
+ options[:range] = range
+ find(:all, options)
+ end
+
+ # Finds the closest to the origin.
+ def find_closest(options={})
+ find(:nearest, options)
+ end
+ alias find_nearest find_closest
+
+ # Finds the farthest from the origin.
+ def find_farthest(options={})
+ find(:farthest, options)
+ end
+
+ # Finds within rectangular bounds (sw,ne).
+ def find_within_bounds(bounds, options={})
+ options[:bounds] = bounds
+ find(:all, options)
+ end
+
+ # counts within a distance radius.
+ def count_within(distance, options={})
+ options[:within] = distance
+ count(options)
+ end
+ alias count_inside count_within
+
+ # Counts beyond a distance radius.
+ def count_beyond(distance, options={})
+ options[:beyond] = distance
+ count(options)
+ end
+ alias count_outside count_beyond
+
+ # Counts according to a range. Accepts inclusive or exclusive ranges.
+ def count_by_range(range, options={})
+ options[:range] = range
+ count(options)
+ end
- # Finds within rectangular bounds (sw,ne).
- def count_within_bounds(bounds, options={})
- options[:bounds] = bounds
- count(options)
+ # Finds within rectangular bounds (sw,ne).
+ def count_within_bounds(bounds, options={})
+ options[:bounds] = bounds
+ count(options)
+ end
+
+ # Returns the distance calculation to be used as a display column or a condition. This
+ # is provide for anyone wanting access to the raw SQL.
+ def distance_sql(origin, units=default_units, formula=default_formula)
+ case formula
+ when :sphere
+ sql = sphere_distance_sql(origin, units)
+ when :flat
+ sql = flat_distance_sql(origin, units)
end
-
- # Returns the distance calculation to be used as a display column or a condition. This
- # is provide for anyone wanting access to the raw SQL.
- def distance_sql(origin, units=default_units, formula=default_formula)
- case formula
- when :sphere
- sql = sphere_distance_sql(origin, units)
- when :flat
- sql = flat_distance_sql(origin, units)
- end
- sql
- end
+ sql
+ end
+
+ private
- private
-
# Prepares either a find or a count action by parsing through the options and
# conditionally adding to the select clause for finders.
def prepare_for_find_or_count(action, args)
@@ -239,7 +234,7 @@ def prepare_for_find_or_count(action, args)
units = extract_units_from_options(options)
formula = extract_formula_from_options(options)
bounds = extract_bounds_from_options(options)
-
+
# Only proceed if this is a geokit-related query
if origin || bounds
# if no explicit bounds were given, try formulating them from the point and distance given
@@ -258,12 +253,12 @@ def prepare_for_find_or_count(action, args)
# Unfortunatley, we need to do extra work if you use an :include. See the method for more info.
handle_order_with_include(options,origin,units,formula) if options.include?(:include) && options.include?(:order) && origin
end
-
+
# Restore options minus the extra options that we used for the
# Geokit API.
args.push(options)
end
-
+
def apply_include_for_through(options)
if self.through
case options[:include]
@@ -276,7 +271,7 @@ def apply_include_for_through(options)
end
end
end
-
+
# If we're here, it means that 1) an origin argument, 2) an :include, 3) an :order clause were supplied.
# Now we have to sub some SQL into the :order clause. The reason is that when you do an :include,
# ActiveRecord drops the psuedo-column (specificically, distance) which we supplied for :select.
@@ -285,7 +280,7 @@ def handle_order_with_include(options, origin, units, formula)
# replace the distance_column_name with the distance sql in order clause
options[:order].sub!(distance_column_name, distance_sql(origin, units, formula))
end
-
+
# Looks for mapping-specific tokens and makes appropriate translations so that the
# original finder has its expected arguments. Resets the the scope argument to
# :first and ensures the limit is set to one.
@@ -301,7 +296,7 @@ def apply_find_scope(args, options)
options[:order] = "#{distance_column_name} DESC"
end
end
-
+
# If it's a :within query, add a bounding box to improve performance.
# This only gets called if a :bounds argument is not otherwise supplied.
def formulate_bounds_from_distance(options, origin, units)
@@ -313,7 +308,7 @@ def formulate_bounds_from_distance(options, origin, units)
nil
end
end
-
+
# Replace :within, :beyond and :range distance tokens with the appropriate distance
# where clauses. Removes these tokens from the options hash.
def apply_distance_scope(options)
@@ -357,7 +352,7 @@ def extract_units_from_options(options)
options.delete(:units)
units
end
-
+
# Extract the formula out of the options if it exists and returns it. If
# there is no :formula key, it uses the default. The side effect of the
# method is to remove the :formula key from the options hash.
@@ -366,19 +361,18 @@ def extract_formula_from_options(options)
options.delete(:formula)
formula
end
-
+
def extract_bounds_from_options(options)
bounds = options.delete(:bounds)
bounds = Geokit::Bounds.normalize(bounds) if bounds
end
-
+
# Geocode IP address.
def geocode_ip_address(origin)
geo_location = Geokit::Geocoders::MultiGeocoder.geocode(origin)
return geo_location if geo_location.success
raise Geokit::Geocoders::GeocodeError
end
-
# Given a point in a variety of (an address to geocode,
# an array of [lat,lng], or an object with appropriate lat/lng methods, an IP addres)
@@ -387,7 +381,7 @@ def geocode_ip_address(origin)
def normalize_point_to_lat_lng(point)
res = geocode_ip_address(point) if point.is_a?(String) && /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/.match(point)
res = Geokit::LatLng.normalize(point) unless res
- res
+ res
end
# Augments the select with the distance SQL.
@@ -408,7 +402,7 @@ def substitute_distance_in_conditions(options, origin, units=default_units, form
pattern = Regexp.new("\\b#{distance_column_name}\\b")
condition.gsub!(pattern, distance_sql(origin, units, formula))
end
-
+
# Returns the distance SQL using the spherical world formula (Haversine). The SQL is tuned
# to the database in use.
def sphere_distance_sql(origin, units)
@@ -453,20 +447,19 @@ def flat_distance_sql(origin, units)
sql = "unhandled #{connection.adapter_name.downcase} adapter"
end
end
- end
end
end
end
# Extend Array with a sort_by_distance method.
-# This method creates a "distance" attribute on each object,
-# calculates the distance from the passed origin,
-# and finally sorts the array by the resulting distance.
class Array
+ # This method creates a "distance" attribute on each object, calculates the
+ # distance from the passed origin, and finally sorts the array by the
+ # resulting distance.
def sort_by_distance_from(origin, opts={})
- distance_attribute_name = opts.delete(:distance_attribute_name) || 'distance'
+ distance_attribute_name = opts.delete(:distance_attribute_name) || 'distance'
self.each do |e|
- e.class.send(:attr_accessor, distance_attribute_name) if !e.respond_to? "#{distance_attribute_name}="
+ e.class.send(:attr_accessor, distance_attribute_name) if !e.respond_to?("#{distance_attribute_name}=")
e.send("#{distance_attribute_name}=", e.distance_to(origin,opts))
end
self.sort!{|a,b|a.send(distance_attribute_name) <=> b.send(distance_attribute_name)}

0 comments on commit 3d23888

Please sign in to comment.