Какой самый эффективный способ получить области, где широта / долгота подпадают под действие?

area имеет много coordinates coordinate модель имеет два атрибута: latitude и longitude

Есть ли способ рефакторить это? Прямо сейчас это работает, но выполняет запрос типа n+1:

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

Я пытаюсь получить все areas, под которые подпадают latitude и longitude

Я использую гем Geokit, но буду рад переключиться, если есть что-то более эффективное, чем я должен заниматься.


person Christian Fazzini    schedule 08.04.2020    source источник
comment
Вы используете postgresql, тогда вы можете сделать это непосредственно на уровне базы данных. Существуют определенные типы данных для точки postgresql.org/docs/9.3/datatype. -geometric.html#AEN6706, но не уверен, как вам нужно структурировать запросы, но это возможно, немного просмотрите, поищите по адресу: stackoverflow.com/questions/10034636/   -  person Roland Studer    schedule 08.04.2020


Ответы (1)


В зависимости от того, сколько областей должна содержать ваша база данных, у вас могут быть разные стратегии.

Если у вас относительно небольшое количество областей, и каждая область имеет небольшое количество координат, вы можете preload или даже eager_load координаты в память.

# 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

Если количество областей достаточно велико, чтобы взорвать вашу память, то, возможно, ваш текущий подход является лучшим. Кстати, я не знаком с типами данных геолокации в PostgreSQL.

person Aetherus    schedule 08.04.2020
comment
К сожалению, и areas, и coordinates будут содержать несколько сотен записей. Районов в городе может быть от 20 до 50. Координатов гораздо больше - person Christian Fazzini; 09.04.2020