1

I have a database of places with lat/lng information and I'd like to create a json feed that returns a list of places within an x mile radius of the current lat/lng of a user. What's the best way to do something like this?

My javascript will likely make an ajax call with the current lat/lng and the backend will handle what places get returned. Then I'll render those places using js. (LMK if you think that's the best way to handle this and if so, how does the backend logic work?)

locoboy
  • 38,002
  • 70
  • 184
  • 260
  • Which database are you using? Some are better at this kind of thing than others! – Paul Russell Nov 14 '12 at 06:51
  • 1
    This related question might lead you in the right direction, but Paul is right, it is highly dependent on your DB. http://stackoverflow.com/questions/2234204/latitude-longitude-find-nearest-latitude-longitude-complex-sql-or-complex-calc – Cecchi Nov 14 '12 at 07:00
  • db is postgres and based on rails ORM ActiveRecord – locoboy Nov 14 '12 at 07:26
  • I'd check out Google Maps for Rails as well. Going to use it on one of my own projects soon hopefully. https://github.com/apneadiving/Google-Maps-for-Rails – Paul Nov 14 '12 at 09:41
  • I actually do use gmaps4rails how exactly would i use it for this situation? – locoboy Nov 24 '12 at 23:59

3 Answers3

3

Check out the Geocoder gem. It supports ActiveRecord and several DB engines, including PostgreSQL.

If you have a Venue model, you can add geocoding to it and do things like:

nearby_places = Venue.near([lat, long], distance)

There is also an example on advanced queries at GitHub for this project, quoted in full below.


When querying for objects (if you're using ActiveRecord) you can also look within a square rather than a radius (circle) by using the within_bounding_box scope:

distance = 20
center_point = [40.71, 100.23]
box = Geocoder::Calculations.bounding_box(center_point, distance)
Venue.within_bounding_box(box)

This can also dramatically improve query performance, especially when used in conjunction with indexes on the latitude/longitude columns. Note, however, that returned results do not include distance and bearing attributes. If you want to improve performance AND have access to distance and bearing info, use both scopes:

Venue.near(center_point, distance).within_bounding_box(box)
Lars Haugseth
  • 14,721
  • 2
  • 45
  • 49
0

You can do in this way:

1) make ajax call from your javascript block:

$.ajax({
  url: '<%= url_for :action => :find_places  %>', 
  data: {
    lat: $('#lat_field').val(),
    ing: $('#ing_field').val()
  },
  dataType: 'json',
  success: function( data ) {
    response( $.map( data, function( places ) {
      // do something with places
      // like places.name and so on
      // this function will be called for each item in json array
    }));
  }   
});

2) catch this action in your controller

def find_places
  @places_array = Array.new
  @places_array[0] = {:name => ' ...', :others => '...'}
  respond_with @places_array.to_json
end

3) dont forget to add respond_to :json in the beginning of your controller and get 'find_places' in your routes.rb.

Actually it will be more 'Ruby'-style to proceed result of your calculation in find_places.js.erb file which have acces to your controller instance variable. In this case you dont need to use json at all.

0

Hmm, postgres has a geospatial extension called postgis that's worth looking into. I've actually had better experience with sphinx, which can use any db table (mysql, mongo, sqlite, even csv or xml) as a source.

pguardiario
  • 53,827
  • 19
  • 119
  • 159