ดังนั้นฉันจะเตรียมเค้กให้กับคุณ - ผลไม้โดยใช้เครื่องมือ PostGIS ตามที่คุณร้องขอถ้าฉันเข้าใจคำถามอย่างถูกต้องและอย่างที่ฉันได้กล่าวถึงความรับผิดชอบในการทำงานของเตาอบ PostGIS นั้นเป็นความรับผิดชอบของทีมงานสร้างสรรค์ของเธอ
ฉันจะขอไม่ให้ใครขุ่นเคืองในสไตล์ที่มีอารมณ์ขันของฉันและเข้าใจว่ามันเป็นเกม!
ไฟล์ต้นฉบับเป็นผลไม้ที่ถูกหั่นและมีรูปทรงที่เรียบง่าย (ต่อไปนี้จะเรียกว่าผลไม้) ดูรูปที่ 1 ด้านล่าง
นี่คือสูตรของฉันและฉันจะได้รับการช่วยเหลือในเรื่องนี้โดยโปรแกรมเมอร์ที่รักซึ่งคุณจะได้เรียนรู้ในภายหลัง มาเริ่มกันเถอะและสำหรับสิ่งนี้เราจะสร้างแป้งสาลีซึ่งจะวางผลไม้ของเราซึ่งใช้สคริปต์:
create table poly_extent as
SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
ดูผลลัพธ์ในรูปที่ 2 ด้านล่าง
ตอนนี้ถ้ามีผลไม้น้อยเช่นในรูปภาพของฉันสร้างเส้นขอบของบัฟเฟอร์ภายนอกบนผลไม้หรือถ้ามีผลไม้มากมายให้สร้างเส้นขอบของบัฟเฟอร์ลบซึ่งใช้สคริปต์:
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;
และแบ่งเส้นบัฟเฟอร์รอบผลไม้แต่ละชนิด
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1)
WHERE ST_IsClosed(geom)=true;
ดูผลลัพธ์ในรูปที่ 3 ด้านล่าง
(อันที่จริงฉันคิดว่าเป็นผลให้ฉันได้รับเส้นแตก (เช่นในวงกลม) แต่ถ้าตัวเลขเป็นเรื่องยากบางครั้งจะได้รับการแบ่งบางครั้งไม่ถูกต้องตัวอย่างเช่นด้านหนึ่งของสี่เหลี่ยมหลุดออกมา ฯลฯ )
จากนั้นคุณต้องแบ่งบรรทัดที่ได้รับในวิธีที่สะดวกสำหรับคุณในส่วนที่เท่ากันและแยกคะแนนจากพวกเขา
create table poly_buff_dump_pt as
SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
ผลลัพธ์ดูรูปที่ 4 ด้านล่าง
ตอนนี้เรียกใช้เครื่องมือ Voronoi ในที่นี้ฉันใช้เครื่องมือที่แนะนำโดยลิงค์ MickyT: /gis//a/172246/120129
เนื่องจากคุณจะสร้างตารางที่มีชื่อ“ voronoi” "สำหรับความจริงที่ว่า" ผู้ช่วยคนแรกของฉัน "แยกจากพ่อครัวขอบคุณจากพ่อครัว! :-)
วิธีที่สองในขั้นตอนนี้คือการเรียกใช้ฟังก์ชัน ST_VoronoiPolygons
ผลลัพธ์ดูรูปที่ 5 ด้านล่าง
ตอนนี้ให้ตัดส่วนเพิ่มเติมโดยเรียกใช้สคริปต์:
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);
ผลลัพธ์ดูรูปที่ 6 ด้านล่าง
ตอนนี้เรียกใช้สคริปต์เพื่อจัดตำแหน่งประเภท geodata ใน LineString:
create table poly_voronoi_dump as
SELECT (ST_Dump(geom)).geom as geom
FROM poly_voronoi_cut;
และตอนนี้ฉันจะขอให้ "เพื่อนที่สองของฉัน" ทำหน้าที่ของฉันและผสมเค้ก wel (Jeff - /gis//a/785/120129 ) ปรับระดับให้เป็นเลเยอร์เดียวและเพื่อ ขอบคุณฉันมัน!
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
)
);
ตอนนี้ถึงเวลาที่ฉันจะต้องทำงานแล้วซึ่งฉันจะเรียกใช้สคริปต์:
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;
และสคริปต์อื่น:
create table poly_voronoi_union_area as
SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union
GROUP BY id;
ดูรูปที่ 7 ด้านล่าง
ดังที่คุณเห็นในภาพการตัดของเรามีเลเยอร์เล็ก ๆ ซึ่งสามารถลบออกได้เป็นตัวเลือกโดยใช้ ST_SnapToGrid (หรืออีกวิธีหนึ่ง):
และในที่สุดเราจะตัดผลไม้อบออกจากพายของฉันฉันยังรู้สึกเหนื่อยเล็กน้อยที่ยืนอยู่ข้างเตาอบ :-)
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);
ผลลัพธ์ดูรูปที่ 8
ทุกอย่างตั้งแต่วันนี้ตอนนี้ทุกคนจะเรียนรู้ที่จะอบขนมพายแสนอร่อย - ผลไม้ ช่วยตัวเองทุกคนและเลือกชิ้นส่วนที่คุณชอบพอสำหรับทุกคน
(เป็นเรื่องน่าเสียดายที่ฉันไม่สามารถให้อาหารกับทุกคนได้จริง ๆ ไม่ใช่เค้กอิเล็กทรอนิกส์ แต่ด้วยเค้กจริงอาจจะหิวบนโลก ... )
แก้ไข:เชอร์รี่บนพายอาจมีลักษณะเช่นนี้ :-):
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;
หรือ
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;
แก้ไขสคริปต์ 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;
กับคุณเป็นคนดีและเป็นธรรม Mr.Baker ขอขอบคุณทุกท่านและขอให้โชคดี: -) ...
โซลูชั่นดั้งเดิม
สคริปต์นี้มีชื่อว่า: ST_VoronoiDiagramsFromPolygons