Participar com base na sobreposição máxima no PostGIS / PostGresQL?

11

Eu tenho dois conjuntos de polígonos em duas tabelas. Os conjuntos se sobrepõem. Para cada polígono no conjunto A, gostaria de obter o ID do polígono no conjunto B que mais se sobrepõe. Estou usando o PostgreSQL com a extensão PostGIS.

Eu sei o suficiente sobre SQL para saber que você só pode ingressar com base em condições verdadeiras / falsas. Portanto, isso não vai funcionar:

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)))

porque max () não pode estar na cláusula ON.

ST_Intersects()é um teste verdadeiro / falso, então eu poderia participar disso, mas os polígonos no conjunto A geralmente se sobrepõem a mais de um polígono no conjunto B, e preciso saber qual deles se sobrepõe mais . ST_Intersects presumivelmente retornaria o primeiro ID sobreposto encontrado, independentemente da extensão da sobreposição.

Parece que deve ser possível, mas está além de mim. Alguma ideia?

Hugh Stimson
fonte

Respostas:

13

Você pode usar algo como:

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

Isto:

1) Calcula ST_Area (ST_Intersection (a.geom, b.geom)) para cada (a, b) par de registros.

2) Ordena-os por a.id e por intersect_area quando a.id são iguais.

3) Em cada grupo de a.id igual, ele seleciona o primeiro registro (o primeiro registro tem a maior área de intersecção por causa da ordem na etapa 2).

Igor Romanchenko
fonte
Isso resolve o problema com muito cuidado. Obrigado, obrigado! DISTINCT ONé novo para mim - muito útil neste contexto.
Hugh Stimson