Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all items within a bounding box with PostGIS and Rails

I have a Rails model that uses a PostGIS POINT type to store the coordinates of a location. How can I query all locations that are contained within a bounding box? The bounding box comes from Google Maps like this:

/locations?within=40.766159%2C-73.989786%2C40.772781%2C-73.979905&per_page=500

then in my model I have a scope to handle this, but can't figure out how to get the query right:

scope :within, ->(box_string) {
    sw = box_string.split(",")[0..1].reverse.map {|c| c.to_f}
    ne = box_string.split(",")[2..3].reverse.map {|c| c.to_f}
    box = "BOX3D(#{sw[0]} #{sw[1]}, #{ne[0]} #{ne[1]})"
    where( ***WHAT DO I DO HERE?*** )
  }
like image 938
Avishai Avatar asked Jan 11 '13 21:01

Avishai


1 Answers

Using the rgeo gem:

Gemfile:

gem 'rgeo'

model.rb:

def self.within_box(sw_lat, sw_lon, ne_lat, ne_lon)
  factory = RGeo::Geographic.spherical_factory
  sw = factory.point(sw_lon, sw_lat)
  ne = factory.point(ne_lon, ne_lat)
  window = RGeo::Cartesian::BoundingBox.create_from_points(sw, ne).to_geometry
  where("your_point_column && ?", window)
end

Note that the argument order for the factory point method is (lon, lat).

You may want to use the activerecord-postgis-adapter gem, which includes rgeo).

like image 165
tee Avatar answered Oct 23 '22 07:10

tee