EasyPostgis
EasyPostgis is a gemification of the code described in Nick Gauthier's 2013 blog post 'PostGIS and Rails: A Simple Approach'.
It creates 2 scopes for use by your model:
- near(point, distance_in_meters)
- with_distance(point)
near filters the rows based on distance from the point. with_distance adds a distance column to the result.
# find the node closest to a lat lon
def self.nearest_node(lat, lng)
point = OpenStruct.new(:lat => lat, :lng => lng)
Node.with_distance(point).order("distance").first # use quoted string rather than symbol for
# distance so that rails does not append
# a table name
endInstallation
Add this line to your application's Gemfile:
gem 'easy_postgis'And then execute:
$ bundle
Or install it yourself as:
$ gem install easy_postgis
Usage
Add the postgis extension and create the index for your table in a migration:
class AddPostgis < ActiveRecord::Migration
def up
execute 'create extension postgis'
execute %{
create index index_on_node_location on nodes using gist (
ST_GeographyFromText(
'SRID=4326;POINT(' || nodes.lng || ' ' || nodes.lat || ')'
)
)
}
end
def down
execute %{drop index index_on_node_location}
end
endInclude EasyPostgis in your model:
class Address
# has lat and lng attributes
include EasyPostgis
end
some_address = Address.first
near_by_addresses = Address.near(some_address, 500) # Addresses within 500 metersDevelopment
TODO:
- you must create the test database to run the tests: psql> create database easy_postgis_test;
- you must add gis: psql> create extension postgis;
- we should allow for customization of the lat/lng column names
- we should provide a generator to create a migration that adds the index
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests.
To install this gem onto your local machine, run bundle exec rake install.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/kellyfelkins/easy_postgis.
License
The gem is available as open source under the terms of the MIT License.