Ich habe ein paar Tage mit einem Problem zu kämpfen und festgestellt, dass viele Leute auch stecken bleiben, wenn es um Schnittpunkte in PostGIS (v2.5) geht. Aus diesem Grund habe ich mich entschlossen, eine detailliertere und allgemeinere, häufig gestellte Frage zu stellen.
Ich habe folgende Tabelle:
DROP TABLE IF EXISTS tbl_foo;
CREATE TABLE tbl_foo (
id bigint NOT NULL,
geom public.geometry(MultiPolygon, 4326),
att_category character varying(15),
att_value integer
);
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(1, ST_SetSRID('MULTIPOLYGON (((0 6, 0 12, 8 9, 0 6)))'::geometry,4326) , 'cat1', 2 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(2, ST_SetSRID('MULTIPOLYGON (((5 0, 5 12, 9 12, 9 0, 5 0)))'::geometry,4326), 'cat1', 1 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(3, ST_SetSRID('MULTIPOLYGON (((4 4, 3 8, 4 12, 7 14,10 12, 11 8, 10 4, 4 4)))'::geometry,4326) , 'cat2', 5 );
Es sieht aus wie das:
Ich möchte alle untergeordneten Polygone basierend auf dem Schnittpunkt der übergeordneten Polygone erhalten. Für das Ergebnis wäre zu erwarten:
- Die untergeordneten Polygone ohne Überlappung zwischen ihnen.
- Eine Spalte, die die Summe des Werts ihrer übergeordneten Polygone enthält.
- Eine Spalte, die die Anzahl der übergeordneten Polygone einer Kategorie enthält
- Eine Spalte, die die Anzahl einer anderen Kategorie enthält
- Eine Spalte, die die Kategorie des untergeordneten Polygons enthält, basierend auf der folgenden Regel: -Wenn ALLE übergeordneten Polygone aus einer Klasse stammen, hat das untergeordnete Polygon auch diese Klasse. Andernfalls ist die Kategorie des untergeordneten Polygons eine dritte Kategorie.
So sieht es aus:
Also, am Ende erzielte die Ausgabetabelle (für dieses Beispiel) hat 7 Zeilen (alle den 7, nicht-überlappende, Kind Polygone), mit Spalten category
, sum_value
, ct_overlap_cat1
,ct_overlap_cat2
Der folgende Code, den ich gestartet habe, gibt mir die einzelnen Schnittpunkte und vergleicht einen Elternteil mit einem anderen.
SELECT
(ST_Dump(
ST_SymDifference(a.geom, b.geom)
)).geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom)
UNION ALL
SELECT
ST_Intersection(a.geom, b.geom) as geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom);
Wie durchlaufe ich rekursiv das Ergebnis dieses genannten Codes, dass ich unabhängig von der Anzahl der Überlappungspolygone immer die "kleinsten" (untergeordneten) Polygone erhalte (Abb. 2)?