Vì vậy, tôi sẽ chuẩn bị một chiếc bánh cho bạn - đĩa trái cây, sử dụng các công cụ PostGis, như bạn yêu cầu, nếu tôi hiểu chính xác câu hỏi và như tôi đã đề cập, trách nhiệm đối với hoạt động của lò PostGIS do đội ngũ sáng tạo của cô ấy chịu.
Tôi sẽ yêu cầu không bị xúc phạm bởi bất cứ ai theo phong cách hài hước của tôi và hiểu nó như một trò chơi!
Tệp gốc là trái cây thái lát và hình dạng đơn giản (sau đây gọi là trái cây), xem Hình 1 bên dưới.
Đây là công thức của tôi, và tôi sẽ được giúp đỡ bởi những lập trình viên thân yêu, người mà bạn sẽ tìm hiểu sau này. Hãy bắt đầu, và để làm điều này, chúng tôi sẽ tạo ra một loại bột trong đó trái cây của chúng tôi sẽ được đặt, để chạy kịch bản:
create table poly_extent as
SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Xem kết quả trong Hình 2 bên dưới
Bây giờ, nếu có ít trái cây, như trong hình của tôi, hãy tạo đường viền của bộ đệm ngoài trên trái cây hoặc nếu có nhiều trái cây, hãy tạo đường viền của bộ đệm âm, để chạy tập lệnh:
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;
Và cắt các đường đệm xung quanh mỗi quả
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1)
WHERE ST_IsClosed(geom)=true;
Xem kết quả trong Hình 3 bên dưới
(Trên thực tế, tôi đã nghĩ rằng kết quả là tôi sẽ nhận được các đường gãy (chẳng hạn như trong một vòng tròn), nhưng nếu các số liệu khó khăn, đôi khi phá vỡ được, ví dụ, một bên của hình chữ nhật rơi ra, v.v. )
Sau đó, bạn cần chia các dòng thu được một cách thuận tiện cho bạn thành các phân đoạn bằng nhau và trích xuất các điểm từ chúng
create table poly_buff_dump_pt as
SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Kết quả, xem Hình 4 bên dưới
Bây giờ hãy chạy công cụ Voronoi, ở nơi này tôi đã sử dụng công cụ được đề xuất bởi liên kết MickyT: /gis//a/172246/120129
, do đó bạn sẽ tạo các bảng có tên là voronoi Vì thực tế, người trợ lý đầu tiên của tôi là tách biệt với đầu bếp nhờ đầu bếp! :-).
Cách thứ hai trong bước này là chạy hàm ST_VoronoiPolygons.
Kết quả, xem Hình 5 bên dưới
Bây giờ, cắt bỏ các phần bổ sung bằng cách chạy tập lệnh:
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);
Kết quả, xem Hình 6 bên dưới.
Bây giờ hãy chạy tập lệnh để căn chỉnh kiểu geodata trong LineString:
create table poly_voronoi_dump as
SELECT (ST_Dump(geom)).geom as geom
FROM poly_voronoi_cut;
Và bây giờ tôi sẽ yêu cầu "người bạn đời thứ hai của tôi" nhận nhiệm vụ của mình và trộn bánh chào mừng (Jeff - /gis//a/785/120129 ), san bằng nó trong một lớp duy nhất và cho điều đó , cảm ơn tôi cho nó!
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
)
);
Bây giờ là lúc để tôi đi làm, nơi tôi chạy kịch bản:
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;
và một kịch bản khác:
create table poly_voronoi_union_area as
SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union
GROUP BY id;
xem hình 7 bên dưới
Như bạn có thể thấy trong hình, các vết cắt của chúng tôi có các lớp nhỏ, có thể được loại bỏ, như một tùy chọn sử dụng ST_SnapToGrid (hoặc theo cách khác):
Và cuối cùng, chúng tôi sẽ cắt trái cây nướng ra khỏi chiếc bánh của mình, tôi thậm chí còn hơi mệt khi đứng cạnh lò nướng, :-)
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);
Kết quả xem hình 8
Tất cả mọi thứ từ ngày này, bây giờ mọi người sẽ học cách nướng bánh nướng ngon - đĩa trái cây. Giúp mình tất cả, và chọn những mảnh bạn, thích cho tất cả mọi người.
(Thật đáng tiếc khi tôi thực sự không thể nuôi tất cả mọi người, không phải bằng bánh điện tử, nhưng với bánh thật, có lẽ cơn đói sẽ chấm dứt trên Trái đất ...)
Chỉnh sửa: Anh đào trên chiếc bánh có thể trông như thế này :-):
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;
hoặc là
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;
Với bạn là Mr.Baker tốt và công bằng, cảm ơn tất cả và chúc may mắn ,: -) ...
Giải pháp ban đầu.
Kịch bản này được gọi là: ST_VoronoiDiagramsFromPolygons.