Bu yüzden, sizin için bir pasta hazırlayacağım - meyve tabağı, PostGIS araçlarını kullanarak, istediğiniz gibi, soruyu doğru bir şekilde anladıysam ve bahsettiğim gibi, PostGIS fırınının işletilmesinin sorumluluğu yaratıcı ekibi tarafından karşılanıyor.
Mizahi tarzımda kimsenin rahatsız olmamasını ve oyun olarak anlamasını isteyeceğim!
Orijinal dosya dilimlenmiş meyve ve basit şekillerdir (bundan sonra meyve olarak anılacaktır), aşağıdaki Şekil 1'e bakın.
İşte benim tarifim ve daha sonra öğreneceğiniz sevgili programcılar tarafından bana yardımcı olacağım. Başlayalım ve bunun için meyvelerinizin yerleştirileceği bir hamur oluşturacağız, bunun için senaryoyu çalıştırın:
create table poly_extent as
SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Aşağıdaki Şekil 2'deki sonuca bakın
Şimdi, resmimdeki gibi az sayıda meyve varsa, meyvede harici tamponun kenarlığını oluşturun veya çok fazla meyve varsa, komut dosyasını çalıştıran negatif tamponun kenarlığını oluşturun:
create table poly_buff_dump as
SELECT ((ST_Dump(ST_Boundary(ST_Union(ST_Buffer((geom),0.01, 'join=mitre mitre_limit=5.0'))))).geom) geom FROM poly;
Ve her meyve etrafında tampon çizgilerini dilimleyin
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1)
WHERE ST_IsClosed(geom)=true;
Aşağıdaki Şekil 3'teki sonuca bakın
(Aslında, sonuç olarak kırık çizgiler elde edeceğimi düşündüm (bir daire gibi), ancak rakamlar zorsa, bazen aralar elde edilir, yanlış olanlar, örneğin, dikdörtgenin bir tarafı düştü vb. )
Sonra elde edilen çizgileri sizin için uygun bir şekilde eşit segmentlere ayırmanız ve onlardan puan almanız gerekir
create table poly_buff_dump_pt as
SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Sonuç, aşağıdaki Şekil 4'e bakın
Şimdi Voronoi aracını çalıştırın, bu yerde MickyT bağlantısının önerdiği aracı kullandım: /gis//a/172246/120129
, bunun sonucunda “voronoi adıyla tablolar oluşturacaksınız” “İlk asistanımın” şeften ayrı olması, şefin teşekkürler! :-).
Bu adımdaki ikinci yol ST_VoronoiPolygons işlevini çalıştırmaktır.
Sonuç, aşağıdaki Şekil 5'e bakın
Şimdi, komut dosyasını çalıştırarak fazladan parçaları kesin:
create table poly_voronoi_cut as
SELECT ST_Intersection(a.geom, b.geom) geom
FROM voronoi a INNER JOIN poly_extent b ON ST_Intersects(a.geom, b.geom);
Sonuç olarak, aşağıdaki Şekil 6'ya bakın.
Şimdi, LineString'deki coğrafi veri türünü hizalamak için komut dosyasını çalıştırın:
create table poly_voronoi_dump as
SELECT (ST_Dump(geom)).geom as geom
FROM poly_voronoi_cut;
Ve şimdi "ikinci dostumdan" görevlerimi yerine getirmesini ve kek kalıbını karıştırmasını isteyeceğim (Jeff - /gis//a/785/120129 ), tek bir katmanda düzleştirelim ve bunun için , bunun için bana teşekkürler!
CREATE TABLE poly_overlay_cut AS
SELECT geom FROM ST_Dump((
SELECT ST_Polygonize(geom) AS geom FROM (
SELECT ST_Union(geom) AS geom FROM (
SELECT ST_ExteriorRing(geom) AS geom FROM poly_voronoi_dump) AS lines
) AS noded_lines
)
);
Şimdi senaryoyu çalıştırdığım işe gelme zamanı:
create table poly_voronoi_union as
SELECT b.id, (ST_ConvexHull(ST_Union(a.geom, b.geom))) geom
FROM poly_overlay_cut a INNER JOIN poly_buff_dump b ON ST_Intersects(a.geom, b.geom)
GROUP BY b.id, a.geom, b.geom;
ve başka bir senaryo:
create table poly_voronoi_union_area as
SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union
GROUP BY id;
aşağıdaki şekil 7'ye bakınız
Resimde görebileceğiniz gibi, kesimlerimizin ST_SnapToGrid (veya başka bir şekilde) kullanılarak bir seçenek olarak kaldırılabilen küçük katmanları vardır:
Ve son olarak, pişmiş meyvemizi pastalarımızdan keseceğiz, hatta fırının yanında biraz yorgunum var :-)
create table polygon_voronoi_result as
SELECT (ST_Dump(ST_Difference(a.geom, b.geom))).geom as geom
FROM poly_voronoi_union_area_snap as a JOIN poly b ON ST_Intersects(a.geom, b.geom);
Sonuç bkz. Şekil 8
Bugünden itibaren her şey, şimdi herkes lezzetli turta pişirmeyi öğrenecek - meyve tabağı. Herkese yardım et ve herkesi sevdiğin parçaları seç.
(Gerçekten tüm insanları besleyememem üzücü, elektronik keklerle değil, gerçek keklerle, belki de açlık Dünya'da sona erecekti ...)
Düzenleme: Pasta kiraz böyle görünebilir :-):
WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM poly),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT ST_Intersection(a.geom, b.geom) geom FROM tblb a JOIN poly_extent b ON ST_Intersects(a.geom,b.geom)),
tbld AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM poly GROUP BY id, geom)
SELECT id, ST_Union(a.geom) as geom FROM tblc a JOIN tbld b ON ST_Intersects(a.geom, b.geom) GROUP BY id;
veya
WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM polygons),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM polygons GROUP BY id, geom)
SELECT id, ST_Union(a.geom) geom FROM tblb a JOIN tblc b ON ST_Intersects(a.geom, b.geom) GROUP BY id;
Komut dosyasını gözden geçirin 01.04.2020:
WITH tbla AS (
WITH atbl AS (SELECT id, (ST_ExteriorRing(((ST_Dump(geom)).geom))) geom FROM polygons),
intervals AS (SELECT generate_series (0, 501) as steps)
SELECT steps AS stp, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM intervals)) geom FROM atbl, intervals GROUP BY id, intervals.steps, geom),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM polygons GROUP BY id, geom)
SELECT id, ST_Union(a.geom) geom FROM tblb a JOIN tblc b ON ST_Intersects(a.geom, b.geom) GROUP BY id;
İyi ve adil bir şekilde BayBaker, hepinize teşekkür ederim ve iyi şanslar,: -) ...
Orijinal çözümler.
Bu komut dosyasına ST_VoronoiDiagramsFromPolygons denir.