• Stars
    star
    107
  • Rank 313,359 (Top 7 %)
  • Language
    Ruby
  • License
    MIT License
  • Created about 13 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Search records with latitude and longitude within a radius

ActiveRecord + PostgreSQL Earthdistance Build Status Code Climate

Check distances with latitude and longitude using PostgreSQL special indexes. This gem enables your model to query the database using the earthdistance extension. This should be much faster than using trigonometry functions over standard indexes.

Requirements

Postgresql 9.1+ with contrib and Rails 3.1+ On Ubuntu, this is easy: sudo apt-get install postgresql-contrib-9.1

On Mac you have a couple of options:

Install

Earthdistance is a PostgreSQL contrib module, check it out first.

Then, just add this to your Gemfile:

gem 'activerecord-postgres-earthdistance'

And run your bundler:

bundle install

Now you need to create a migration that adds earthdistance support for your PostgreSQL database:

rails g earth_distance:setup

Run it:

rake db:migrate

Now let's add some gist indexes to make queries ultra-fast. For the model Place we could create an index over the lat and lng fields:

rails g migration add_index_to_places

Edit the created migration:

class AddIndexToPlaces < ActiveRecord::Migration
  def up
    add_earthdistance_index :places
  end

  def down
    remove_earthdistance_index :places
  end
end

This will create the index with a SQL like this:

CREATE INDEX places_earthdistance_ix ON places USING GIST (ll_to_earth(lat, lng));

Usage

This gem only provides a custom serialization coder. If you want to use it just put in your Gemfile:

gem 'activerecord-postgres-earthdistance'

Now add a line (for each earthdistance column) on the model you have your earthdistance columns. Assuming a model called Person, with a data field on it, the code should look like:

class Place < ActiveRecord::Base
  acts_as_geolocated
end

This way, you will automatically look for columns with names such as lat/latitude and lng/longitude. But you can use alternative names passing them as:

class Place < ActiveRecord::Base
  acts_as_geolocated lat: 'latitude_column_name', lng: 'longitude_column_name'
end

You can also locale other entities through an geolocated association as in:

class Job < ActiveRecord::Base
  belongs_to :job
  acts_as_geolocated through: :job
end

Querying the database

To query for all places within a given radius of 100 meters from the origin -22.951916,-43.210487 just use:

Place.within_radius(100, -22.951916, -43.210487).all

You can also order the records based on the distance from a point

Place.within_radius(100, -22.951916,-43.210487).order_by_distance(-22.951916,-43.210487)

To query on associated models (the joins will be included for you):

Job.within_radius(100, -22.951916,-43.210487)

The within_radius query performs two checks: first against the bounding box, followed by computing the exact distance for all contained elements. The latter might be computationally expensive for big ranges. So if precision is not an issue but query speed is, you might want to query against the bounding box only:

Place.within_box(1_000_000, -22.951916,-43.210487)

Select the distance from a point:

point = [-22.951916, -43.210487]
closest = Place.within_radius(100, *point).order_by_distance(*point).selecting_distance_from(*point).first
closest.distance

Test Database

To have earthdistance enabled when you load your database schema (as happens in rake db:test:prepare), you have two options.

The first option is creating a template database with earthdistance installed and set the template option in database.yml to that database.

The second option is to uncomment or add the following line in config/application.rb

config.active_record.schema_format = :sql

This will change your schema dumps from Ruby to SQL. If you're unsure about the implications of this change, we suggest reading this Rails Guide.

Help

You can use issues in github for that. Or else you can reach us at twitter: @dbiazus

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don’t break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright © 2010 Diogo Biazus. See LICENSE for details.

More Repositories

1

activerecord-postgres-hstore

Goodbye serialize, hello hstore. Speed up hashes in the database.
Ruby
840
star
2

postgres-copy

Simple PostgreSQL's COPY command support in ActiveRecord models
Ruby
429
star
3

postgres-websockets

PostgreSQL + Websockets
Haskell
337
star
4

carrierwave-postgresql

Use PostgreSQL large objects (AKA BLOBs) to store your files inside the database
Ruby
56
star
5

elm-workshop

Elm + PostgREST workshop, building a simple database query user interface.
Elm
33
star
6

postgresql_lo_streamer

A Rails engine to stream PostgreSQL Large Objects to clients
Ruby
20
star
7

hasql-notifications

Use PostgreSQL LISTEN/NOTIFY with your Hasql Types
Haskell
12
star
8

pg-recorder

Relay PostgreSQL notifications to user defined functions
Haskell
12
star
9

git-tutorial

Dummy project to work with git
10
star
10

haskell-tools

Website to view haskell projects from Github
Haskell
8
star
11

pasta

PostgreSQL AST Assembler
Haskell
6
star
12

user_notifier

Simple pattern for keeping track of messages sent to users based on model events with different templates.
Ruby
6
star
13

reader-tutorial

Tutorial using ReaderT and mock IO functions for testing
Haskell
5
star
14

trabalho_compiladores

Old undergrad compiler course assignment. Everything is in portuguese.
C
4
star
15

jquery.fixedmask

JQuery plugin for fixed size input mask
JavaScript
4
star
16

postgrest-tutorial

PLpgSQL
4
star
17

postgrest-benchmark

Let's do some performance testing!
PLpgSQL
3
star
18

m36-auth

just testing project-m36
Haskell
2
star
19

impress.pg

Apresentação sobre o PostgreSQL
JavaScript
2
star
20

php_in_rio

Apresentação sobre o PostgreSQL para o PHP'n Rio 2012
JavaScript
1
star
21

m36-talk

Elm
1
star
22

receive-order

Haskell Tutorial using servant to build a simple JSON endpoint
Haskell
1
star
23

dojo_pgday2012

JavaScript
1
star
24

haskell_wreq_workshop

Just an example of wreq project with a Lib missing implementation
Haskell
1
star
25

bigodes

Apresentação sobre bigodes na desconf
JavaScript
1
star
26

data-modelling-workshop

Some data modelling tips for the Rails developer
Ruby
1
star