Whats the most efficient way to get areas where lat/lng fall under?

172 Views Asked by At

area has many coordinates coordinate model has two attributes: latitude and longitude

Is there anyway to refactor this? Right now it works, but it does a kind of n+1 query:

areas.each_with_object([]) do |area, array|
  geokit_lat_lngs = area.coordinates.order(sequence: :asc).map do |coordinate|
    Geokit::LatLng.new(coordinate.latitude, coordinate.longitude)
  end

  polygon = Geokit::Polygon.new(geokit_lat_lngs)
  point   = Geokit::LatLng.new(latitude, longitude)
  array << area.id if polygon.contains?(point)
end

Im trying to get all areas that latitude and longitude fall under

Im using the Geokit gem, but happy to switch, if there is something more efficient that I should be doing

1

There are 1 best solutions below

1
Aetherus On

Depending on how many areas your database supposed to hold, you can have different strategies.

If you have a relatively small number of areas, and each area has a small number of coordinates, you can preload or even eager_load the coordinates into memory.

# Suppose `areas` is an `ActiveRecord::Relation`, not just an array
areas.preload(:coordinates).each_with_object([]) do |area, array|
  # Do an in-memory sort
  geokit_lat_lngs = area.coordinates.sort_by(&:sequence).map do |coordinate|
    # ...
  end
end

If the number of areas is big enough to explode your memory, then maybe your current approach is the best one. By the way, I'm not familiar with the geolocation data types in PostgreSQL.