¿Unirse según la superposición máxima en PostGIS / PostGresQL?

11

Tengo dos conjuntos de polígonos en dos tablas. Los conjuntos se superponen entre sí. Para cada polígono en el conjunto A, me gustaría obtener la ID del polígono en el conjunto B que se superpone más. Estoy usando PostgreSQL con la extensión PostGIS.

Sé lo suficiente sobre SQL para saber que solo puedes unirte en base a condiciones verdaderas / falsas. Entonces esto no 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 () no puede estar en la cláusula ON.

ST_Intersects()es una prueba de verdadero / falso, por lo que podría unirme a eso, pero los polígonos en el conjunto A a menudo se superponen con más de un polígono en el conjunto B, y necesito saber cuál se superpone más . ST_Intersects presumiblemente solo devolvería la primera ID superpuesta que encontró, independientemente de la extensión de la superposición.

Parece que debería ser factible, pero está más allá de mí. ¿Alguna idea?

Hugh Stimson
fuente

Respuestas:

13

Podrías 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

Eso:

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

2) Los ordena por a.id y por intersect_area cuando a.id son iguales.

3) En cada grupo de igual a.id, selecciona el primer registro (el primer registro tiene la intersección_area más alta debido al pedido en el paso 2).

Igor Romanchenko
fuente
Eso resuelve muy bien el problema. ¡Gracias Gracias! DISTINCT ONes nuevo para mí, muy útil en este contexto.
Hugh Stimson el