diff --git a/lib/geokit-rails/acts_as_mappable.rb b/lib/geokit-rails/acts_as_mappable.rb index 57a89a9..086bed8 100644 --- a/lib/geokit-rails/acts_as_mappable.rb +++ b/lib/geokit-rails/acts_as_mappable.rb @@ -11,7 +11,7 @@ module Glue # :nodoc: extend ActiveSupport::Concern module ClassMethods # :nodoc: - OPTION_SYMBOLS = [ :distance_column_name, :default_units, :default_formula, :lat_column_name, :lng_column_name, :qualified_lat_column_name, :qualified_lng_column_name, :skip_loading ] + OPTION_SYMBOLS = [ :distance_column_name, :default_units, :default_formula, :lat_column_name, :lng_column_name, :qualified_lat_column_name, :qualified_lng_column_name, :skip_loading] def acts_as_mappable(options = {}) metaclass = (class << self; self; end) @@ -157,6 +157,8 @@ def by_distance(options = {}) end def with_latlng + qualified_lat_column_name = "CAST(#{qualified_lat_column_name} AS FLOAT)" unless qualified_lat_column_name.nil? + qualified_lng_column_name = "CAST(#{qualified_lng_column_name} AS FLOAT)" unless qualified_lng_column_name.nil? where("#{qualified_lat_column_name} IS NOT NULL AND #{qualified_lng_column_name} IS NOT NULL") end @@ -258,6 +260,8 @@ def distance_conditions(options) def bound_conditions(bounds) sw,ne = bounds.sw, bounds.ne + qualified_lat_column_name = "CAST(#{qualified_lat_column_name} AS FLOAT)" unless qualified_lat_column_name.nil? + qualified_lng_column_name = "CAST(#{qualified_lng_column_name} AS FLOAT)" unless qualified_lng_column_name.nil? lng_sql = bounds.crosses_meridian? ? "(#{qualified_lng_column_name}<#{ne.lng} OR #{qualified_lng_column_name}>#{sw.lng})" : "#{qualified_lng_column_name}>#{sw.lng} AND #{qualified_lng_column_name}<#{ne.lng}" res = "#{qualified_lat_column_name}>#{sw.lat} AND #{qualified_lat_column_name}<#{ne.lat} AND #{lng_sql}" #Arel::Nodes::SqlLiteral.new("(#{res})") if res.present? @@ -352,13 +356,13 @@ def flat_distance_sql(origin, units) end def get_lat(origin) - origin.respond_to?(:lat) ? origin.lat \ - : origin.send(:"#{lat_column_name}") + origin.respond_to?(:lat) ? origin.lat.to_f \ + : origin.send(:"#{lat_column_name}").to_f end def get_lng(origin) - origin.respond_to?(:lng) ? origin.lng \ - : origin.send(:"#{lng_column_name}") + origin.respond_to?(:lng) ? origin.lng.to_f \ + : origin.send(:"#{lng_column_name}").to_f end end # ClassMethods diff --git a/lib/geokit-rails/adapters/postgresql.rb b/lib/geokit-rails/adapters/postgresql.rb index 8636cf5..a09341d 100644 --- a/lib/geokit-rails/adapters/postgresql.rb +++ b/lib/geokit-rails/adapters/postgresql.rb @@ -3,6 +3,11 @@ module Adapters class PostgreSQL < Abstract def sphere_distance_sql(lat, lng, multiplier) + lat = "CAST(#{lat} AS FLOAT)" + lng = "CAST(#{lng} AS FLOAT)" + qualified_lat_column_name = "CAST(#{qualified_lat_column_name} AS FLOAT)" unless qualified_lat_column_name.nil? + qualified_lng_column_name = "CAST(#{qualified_lng_column_name} AS FLOAT)" unless qualified_lng_column_name.nil? + %| (ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+ COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+ @@ -11,6 +16,10 @@ def sphere_distance_sql(lat, lng, multiplier) end def flat_distance_sql(origin, lat_degree_units, lng_degree_units) + lat_degree_units = "CAST(#{lat_degree_units} AS FLOAT)" + lng_degree_units = "CAST(#{lng_degree_units} AS FLOAT)" + qualified_lat_column_name = "CAST(#{qualified_lat_column_name} AS FLOAT)" unless qualified_lat_column_name.nil? + qualified_lng_column_name = "CAST(#{qualified_lng_column_name} AS FLOAT)" unless qualified_lng_column_name.nil? %| SQRT(POW(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+ POW(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))