Beitritt basierend auf maximaler Überlappung in PostGIS / PostGresQL?

11

Ich habe zwei Sätze von Polygonen in zwei Tabellen. Die Sätze überlappen sich. Für jedes Polygon in Satz A möchte ich die ID des Polygons in Satz B erhalten, das sich am meisten überlappt. Ich verwende PostgreSQL mit der PostGIS-Erweiterung.

Ich weiß gerade genug über SQL, um zu wissen, dass Sie nur basierend auf True / False-Bedingungen beitreten können. Das wird also nicht funktionieren:

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

weil max () nicht in der ON-Klausel enthalten sein kann.

ST_Intersects()ist ein wahr / falsch-Test, also könnte ich mich dem anschließen, aber Polygone in Satz A überlappen sich oft mit mehr als einem Polygon in Satz B, und ich muss wissen, welches sich am meisten überlappt . ST_Intersects würde vermutlich nur die erste überlappende ID zurückgeben, auf die es gestoßen ist, unabhängig vom Ausmaß der Überlappung.

Dies scheint machbar zu sein, aber es ist mir ein Rätsel. Irgendwelche Gedanken?

Hugh Stimson
quelle

Antworten:

13

Sie könnten etwas verwenden wie:

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

Es:

1) Berechnet ST_Area (ST_Intersection (a.geom, b.geom)) für jedes (a, b) Datensatzpaar.

2) Ordnet sie nach a.id und nach intersect_area, wenn a.id gleich sind.

3) In jeder Gruppe von gleichem a.id wird der erste Datensatz ausgewählt (der erste Datensatz hat aufgrund der Reihenfolge in Schritt 2 den höchsten intersect_area).

Igor Romanchenko
quelle
Das löst das Problem sehr ordentlich. Danke Danke! DISTINCT ONist neu für mich - sehr praktisch in diesem Zusammenhang.
Hugh Stimson