Read more

Find geocoded records that are close to a location (radius search)

Arne Hartherz
November 16, 2011Software engineer at makandra GmbH

When you have objects in your database that hold latitude and longitude and you want to find others that are close to given coordinates you can use the Graticule gem.

Graticule

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

Graticule Show archive.org snapshot offers several methods to compute the distance between two geo-dated objects but fetching records from the database that are within a given radius of a location is a bit trickier:

def close_destinations(latitude, longitude)
  distance_sql = Graticule::Distance::Spherical.to_sql(:latitude => latitude, :longitude => longitude, :units => :kilometers)
  Destination.all(:conditions => [ "#{distance_sql} <= 10" ])
end

The above code will find every Destination that is close to the given latitude and longitude: Using to_sql Show archive.org snapshot will give you an SQL snippet to compute the distance from the given geo point on database level. Just use it to SELECT (maybe using AS distance) or to put into WHERE conditions.

Note that above we computed the distance in kilometers; by default, Graticule uses miles. Also, though the Earth is not at a perfect sphere, spherical distance computation it is good enough in most cases.

ActiveRecord integration: ActsAsGeocodable

When dealing with geo data, you'd often use acts_as_geocodable Show archive.org snapshot for your Rails applications. There you can just use your model's upgraded find Show archive.org snapshot to achieve the same:
Destination.all(:within => 10, :origin => some_other_destination, :units => :kilometers)

The acts_as_geocodable gem uses Graticule itself.

If your model is not using acts_as_geocodable using plain Graticule will just do the job.

Support from the database

  • MySQL 5 has spatial support Show archive.org snapshot . This involves custom data types and funny SQL syntax.
  • It also lets you index such columns for faster querying, unfortunately SPATIAL indexes are only available for MyISAM table at the moment. This means you might need to extract your geocode fields to another table for fast querying.
Posted by Arne Hartherz to makandra dev (2011-11-16 18:04)