Próbuję wykonać rekursywne przecięcie wszystkich wielokątów w tabeli przestrzennej i uzyskać wynikowe (wielokropkowe) pololigony oraz informacje o każdym skrzyżowaniu dla każdego z nich.Posturcze rekurencyjne skrzyżowanie poligonów
Obraz (naprawdę nie w skali) to wytłumaczyć:
Powiedzmy istnieją A, B, C
kwadratów w tabeli. Chciałbym mieć poligony A, B, C, A+B, A+C, B+C, A+B+C
na wyjściu i muszę wiedzieć, że A+B
jest przecięciem A
i B
i tak dalej.
Do tej pory mam zapytanie, które wykonuje przecięcia, ale nie "odcina" przeciętej części oryginalnych wielokątów. Na przykład:
Polygon A should be A - (A+B) - (A+C) - (A+B+C)
Polygon A+C should be A+C - (A+B+C)
Obraz wyniku otrzymuję teraz na A
i A+C
wielokątów:
Oto skrypt testowy, korzystając z placów w obrazach jako dane. Patrząc na kolumnę area
, jest jasne, że brakuje jakiejś rekurencyjnej wartości zmiennej ST_, po prostu nie mogę zrozumieć, jak to zrobić. Każdy pomysł jest mile widziany.
-- Create a test table
CREATE TABLE test (
name text PRIMARY KEY,
geom geometry(POLYGON)
);
-- Insert test data
INSERT INTO test (name, geom) VALUES
('A', ST_GeomFromText('POLYGON((1 2, 1 6, 5 6, 5 2, 1 2))')),
('B', ST_GeomFromText('POLYGON((0 0, 0 4, 4 4, 4 0, 0 0))')),
('C', ST_GeomFromText('POLYGON((2 0, 2 4, 6 4, 6 0, 2 0))'));
-- Query
WITH RECURSIVE
source (rownum, geom, ret) AS (
SELECT row_number() OVER (ORDER BY name ASC), ST_Multi(geom), ARRAY[name] FROM test
),
r (rownum, geom, ret, incroci) AS (
SELECT rownum, geom, ret, 0 FROM source
UNION ALL
SELECT s.rownum, ST_CollectionExtract(ST_Intersection(s.geom, r.geom), 3), (r.ret || s.ret), (r.incroci + 1)
FROM source AS s INNER JOIN r ON s.rownum > r.rownum AND ST_Intersects(s.geom, r.geom) AND ST_Area(ST_Intersection(s.geom, r.geom)) > 0.5
),
result (geom, ret) AS (
SELECT ST_Union(geom) AS geom, ret FROM r GROUP BY ret
)
SELECT geom, ST_Area(geom) AS area, ret FROM result ORDER BY ret
funkcja Okno nie jest to bezwzględnie konieczne w tym konkretnym przykładzie, oczywiście, ale ten kod jest uproszczoną wersją mojego prawdziwego przypadku, który robi kilka rzeczy na boku.
Używam PostgreSQL 9.2 i postgis 2,0
Dziękuję bardzo, bardzo sprytnie, używając takiego połączenia! – Eggplant