Присоединиться на основе максимального перекрытия в PostGIS / PostGresQL?

11

У меня есть два набора полигонов в двух таблицах. Наборы перекрывают друг друга. Для каждого многоугольника в наборе A я хотел бы получить идентификатор многоугольника в наборе B, который он перекрывает больше всего. Я использую PostgreSQL с расширением PostGIS.

Я достаточно разбираюсь в SQL, чтобы знать, что вы можете присоединиться только на основе условий true / false. Так что это не сработает:

SELECT
  a.id as a_id,
  b.id as b_id,
FROM
  a
JOIN
  b
ON
  max(ST_Area(ST_Intersection(a.geom, b.geom)))

потому что max () не может быть в предложении ON.

ST_Intersects()это тест на истинность / ложность, поэтому я мог бы присоединиться к нему, но полигоны в наборе A часто перекрываются с более чем одним полигоном в наборе B, и мне нужно знать, какой из них перекрывается больше всего . Предполагается, что ST_Intersects просто возвращает первый перекрывающийся идентификатор, с которым столкнулся, независимо от степени перекрытия.

Кажется, это должно быть выполнимо, но это вне меня. есть идеи?

Хью Стимсон
источник

Ответы:

13

Вы можете использовать что-то вроде:

SELECT DISTINCT ON (a.id)
  a.id as a_id,
  b.id as b_id,
  ST_Area(ST_Intersection(a.geom, b.geom)) as intersect_area
FROM a, b
ORDER BY a.id, ST_Area(ST_Intersection(a.geom, b.geom)) DESC

Это:

1) Рассчитывает ST_Area (ST_Intersection (a.geom, b.geom)) для каждой (a, b) пары записей.

2) Заказывает их по a.id и по intersect_area, когда a.id равны.

3) В каждой группе с равным a.id он выбирает первую запись (первая запись имеет наибольшее значение intersect_area из-за упорядочения на шаге 2).

Игорь Романченко
источник
Это решает проблему очень аккуратно. Спасибо Спасибо! DISTINCT ONэто ново для меня - очень удобно в этом контексте.
Хью Стимсон