0

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

Christian Fazzini
  • 19,613
  • 21
  • 110
  • 215
  • Are you using postgresql, then you might wanna do it directly in the database-level. There are specific data types for point https://www.postgresql.org/docs/9.3/datatype-geometric.html#AEN6706 but not sure, how you have to structure the queries, but it is possible, browse a bit, have a loot at: https://stackoverflow.com/questions/10034636/postgresql-latitude-longitude-query – Roland Studer Apr 08 '20 at 15:04

1 Answers1

0

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.

Aetherus
  • 8,720
  • 1
  • 22
  • 36
  • Unfortunately, both `areas` and `coordinates` will contain a few hundred records. Areas in a city can range from 20-50. Coordinates much more – Christian Fazzini Apr 09 '20 at 11:29