Skip to content

Instantly share code, notes, and snippets.

@malandrina
Created December 13, 2013 21:42
Show Gist options
  • Save malandrina/7951856 to your computer and use it in GitHub Desktop.
Save malandrina/7951856 to your computer and use it in GitHub Desktop.
module GeospatialObject
METERS_PER_MILE = 1609.34
module Callbacks
def set_geographic_point
ActiveRecord::Base.connection.execute(<<-TEXT
UPDATE addresses
SET geographic_point = ST_GeographyFromText('POINT(' || longitude || ' ' || latitude || ')')
WHERE id = #{self.id}
TEXT
)
end
end
def self.extended(base)
base.send(:include, Callbacks)
base.after_save :set_geographic_point
base.set_rgeo_factory_for_column(
:geographic_point,
RGeo::Geographic.spherical_factory(srid: 4326)
)
end
def by_location(coordinates, distance_in_miles)
distance_in_meters = distance_in_miles * METERS_PER_MILE
if coordinates.blank?
scoped
else
where(
"ST_DWithin(geographic_point, st_setsrid(st_makepoint(?, ?), 4326), ?)",
coordinates[:longitude],
coordinates[:latitude],
distance_in_meters
)
end
end
def order_by_distance(coordinates)
if coordinates.blank?
scoped
else
order(distance_from_coordinates(coordinates))
end
end
def distance_from_coordinates(coordinates)
search_point = RGeo::Geographic.spherical_factory.point(
coordinates[:longitude],
coordinates[:latitude]
)
"ST_Distance(geographic_point, ST_GeographyFromText('#{search_point}'))/#{METERS_PER_MILE}"
end
module_function :distance_from_coordinates
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment