1.需要
postgis関数を使用してポリゴンサーフェスをいくつかの小さなポリゴンサーフェスにカットすると、それぞれの面積はほぼ同じになります
2、アイデア
1. ST_GeneratePointsメソッドを使用して、ポリゴンを面積に比例する一連のポイントに変換します(ポイントが多いほど、効果が高くなり、約1000ポイントが適切です)。
2.ポリゴンをk個の等しい部分にカットすることを計画していると仮定して、ST_ClusterKMeansメソッドを使用して、これらの変換されたポイントをk個のクラスターに集約します。
3. ST_Centroidメソッドを使用して、各クラスターの平均中心を見つけます。
4.計算された平均中心をST_VoronoiPolygonsメソッドの入力パラメーターとして使用して、各ポイントによってマップされたポリゴンサーフェスを計算できます。
5. ST_Intersectionを使用して、これらのマップされた面と初期化されたポリゴンを切り取り、結果を取得します。
三、練習
1.テストデータを描画します
id = 1の都市からselectgeomとしてテーブルデータを作成します。
2. ST_GeneratePointsメソッドを使用して、ポリゴンを面積に比例する一連のポイントに変換します
CREATE TABLE data_points AS SELECT(ST_Dump(ST_GeneratePoints(geom、2000)))。geom AS geom FROM data;
3. ST_ClusterKMeansメソッドを使用して、ポイントをクラスター化し、サーフェスをk個のパーツに分割し、k個のクラスターをクラスター化します。
CREATE TABLE data_clustered AS SELECT geom、ST_ClusterKMeans(geom、10)over()AS cluster FROM data_points;
4. ST_Centroidメソッドを使用して、各クラスターの平均中心を見つけます
CREATE TABLE data_centers AS SELECT cluster、ST_Centroid(ST_collect(geom))AS geom FROM data_clustered GROUP BY cluster;
5. ST_VoronoiPolygonsメソッドを使用して、平均中心のボロノイサーフェスを生成します
CREATE TABLE data_voronoi AS SELECT(ST_Dump(ST_VoronoiPolygons(ST_collect(geom))))。geom AS geom FROM data_centers;
6. ST_Intersectionメソッドを使用して、ボロノイサーフェスと最初のポリゴンサーフェスを交差させます
CREATE TABLE data_divided AS SELECT ST_Intersection(a.geom、b.geom)AS geom FROM data a CROSS JOIN data_voronoi b;
各ステップでSQLを記述し、結果データを表示できるようにデータをテーブルに格納します。ただし、使用の便宜のために、上記のSQLは処理のために関数に統合されています。この関数は、一時テーブルを使用してトランザクションの同時実行の競合を回避し、uuidを使用して一時テーブル名の競合を防止します。createextension "uuid-ossp"を実行する必要があります。 ;-次のuuidの拡張子を作成します。
関数my_polygon_split(作成または交換 -入力面split_geom形状の(ポリゴン)、 split_numの整数で、 -分割数 GEOM幾何アウト(ポリゴン) -出力切断面 )としてジオメトリのセット戻り $$ 宣言 RECレコードを、 テキストtemp_points; temp_ClusterKMeansテキスト; temp_ClusterCentroidテキスト; temp_VoronoiPolygonsテキスト; 開始 -一時テーブル名の競合の同時時間を防止するため、 temp_points:= 'temp_points' || uuid_generate_v4(); temp_ClusterKMeans:= 'temp_ClusterKMeans' || uuid_generate_v4(); temp_ClusterCentroid:= 'temp_ClusterCentroid' || uuid_generate_v4(); temp_VoronoiPolygons:= 'temp_VoronoiPolygons' || uuid_generate_v4(); -生成点 実行format( 'create temp table "%s" on commit drop as SELECT row_number()over()as gid、(ST_Dump(ST_GeneratePoints($ 1、2000)))。geom'、temp_points)using split_geom; -点成簇executeformat ( 'create temp table "%s" on commit drop as SELECT t.geom、ST_ClusterKMeans(t.geom、$ 1)over()AS cluster from "%s" t'、temp_ClusterKMeans、temp_points) split_numを使用します。 -簇的中心点 実行形式( 'コミット時に一時テーブル "%s"を作成してSELECT t.cluster、ST_Centroid(ST_collect(t.geom))AS geom FROM "%s" t GROUP BY t.cluster'、 temp_ClusterCentroid、temp_ClusterKMeans); -ボロノイ図造面 format( 'create temp table "%s" on commit drop as SELECT(ST_Dump(ST_VoronoiPolygons(ST_collect(t.geom))))。geom AS geom FROM "%s" t'、temp_VoronoiPolygons、temp_ClusterCentroid); --split_geom ループ geom:= rec.geom;を使用した実行形式( 'SELECT ST_Intersection($ 1、b.geom)AS geom FROM "%s" b'、temp_VoronoiPolygons)のrecの交差切断分割 次に戻る; ループの終了; 戻る; 終わり; $$ 言語plpgsqlstrict;
最後に、メソッドtestを呼び出します。
元のデータは次のとおりです。
以下に示すように面カットを実行した後、各面を10個にカットし、次のステートメントを実行して、test_polygonテーブルで各面をカットし、その結果を一時テーブルテストに入れます。
CREATE TABLE test AS select my_polygon_split(geom、10)from test_polygon