割合でPostGISジオメトリを拡大する


10

PostGISジオメトリの周りにバッファを追加する方法を探していますが、バッファのサイズはジオメトリのサイズに依存するはずです。つまり、各ジオメトリを、たとえば5%拡大する必要があります。

交差するジオメトリを探しているのですが、考慮に入れたいジオメトリごとに最大5%のエラーが発生する可能性があります。

誰もがこれについて最善の方法を知っていますか?

データベースには100万行あるので、かなり高速にしたいと思います。


2
何の5%?ポリゴンを使用していると仮定すると、最大幅の5%、最も狭い幅、バウンディングボックス、重心からの頂点の距離...ですか?ポイントやラインについて話している場合、それはさらに意味がありません!
MerseyViking、2012

頂点と重心の距離は、おそらく5%の面積増加でも大丈夫でしょう。ジオメトリをスケーリングして境界ボックスを埋める場合は、境界ボックスを増やしても問題ありません。すべての形状は閉じた多角形です(大部分は四角形です)。
ジェームズベイカー

回答:


8

コメントは、5%を高い精度で達成する必要がないことを示唆しています。(もしそうであれば、それはかかります長い万ポリゴンをバッファリングするための時間を!)従って、我々は呼び出すことができピザ原理直線的要因によって2D機能を再スケーリングAによって、そのエリアを再スケール^ 2。

推論の流れは次のとおりです。

  • 形状があまり複雑でない場合、特に凸型の場合は、バッファリングにより、中心点を中心に形状を再スケーリングするのと同等の結果が得られます。(ただし、バッファリングはディスク以外のシェイプのリスケーリングと同等ではないことを理解することが重要です。一部の凹型シェイプの場合、リスケーリングによって計算された「バッファ」には、実際には元のシェイプ自体の一部が含まれない場合があります。したがって、最終的には我々はなります形状の本物のバッファを計算するが、唯一推定するヒューリスティックとしてこのおおよその等価性を使用しているどのくらいでバッファリングすること。)

  • バッファ領域が5%大きくなる場合、再スケーリングの量はsqrt(1 + 5/100)となり、1.025に近くなります。つまり、形状を全方向に2.5%拡大する必要があります。 。

  • 同様に、形状に「直径」(典型的な距離に等しい)があると考える場合、その半径は2.5%増加するはずです。これは、直径の2.5%/ 2 = 1.25%に相当します。

  • 形状の境界ボックスから典型的な直径を推定できます。たとえば、ボックスの辺の長さの算術平均または幾何平均を使用します。

これは、次のワークフローを示唆しています。

  1. 形状の境界ボックスを取得します。

  2. してみましょうeは箱の辺の長さの平均値とします。

  3. eの 1.25%で形状をバッファリングします。つまり、(5/100)/ 4 * eです。

手順1と2で必要な計算は非常に少ないため、これは最も迅速な解決策の1つとして機能します。精度のチェックとして、(もちろん)バッファリングされた形状の面積を計算し、それらを元の面積と比較して、希望の5%増加にどれだけ近づいているかを確認できます。バッファリングされた領域は5%以上大きくなることもありますが、それが少なくなることはまれであり、かなり少なくすることは不可能です。

チェックとイラストとして、いくつかの単純な形状を考えてみましょう。

  1. 半径rのディスクには、辺の長さが2 rの境界ボックスがあります。私たちの公式はe =(5/100)/ 4 * 2 * r = r / 40を計算します。バッファーされた形状は明らかに半径r + r / 40 = 1.025 rの同心円ディスクです。古い領域はpi * r ^ 2 でしたが、新しい領域はpi *(1.025 r)^ 2 = pi * 1.0506 * r ^ 2であり、5.06%大きくなっています。

  2. 長さrsの座標軸に平行な辺を持つ長方形は、e =(r + s)/ 2を与えます。四角形のバッファリングによる追加の領域は、側面に隣接する幅(5/100)/ 4 e = e / 80 =(r + s)/ 160の4つの四角形と、角の半径e / 80の4つの四分円からなります。他のエリアに比べて小さい四分円を無視すると、新しいエリアの合計は

    2(r + s)*(r + s)/ 160 =(r ^ 2 + s ^ 2 + 2 r * s)/ 80。

    場合は、RSがあまりにも異なっていない、我々は理解することができ、R ^ 2 + S ^ 2を約2であるR * S。この近似は、4に総新しい領域を簡素化R * Sの元の領域の/ 80 = 5%のR * sの意図したとおり、。


4

ST_Scale(http://postgis.net/docs/ST_Scale.html)とST_Translate(http://postgis.net/docs/ST_Translate.html)の組み合わせを使用したいと思います。この例は、PostGIS in Actionと第8章で類似しています。この本がない場合は、その章のコードをここからダウンロードできます。

http://www.postgis.us/chapter_08

本の抜粋例8.26を見てください:

    -- Listing 8.26 Combining Scale and Translation to maintain centroid
    SELECT xfactor, yfactor, 
       ST_Translate(ST_Scale(hex.the_geom, xfactor, yfactor), 
       ST_X(ST_Centroid(the_geom))*(1 - xfactor), 
       ST_Y(ST_Centroid(the_geom))*(1 - yfactor) ) As scaled_geometry
    FROM 
 ( SELECT ST_GeomFromText('POLYGON((0 0,64 64,64 128,0 192,-64 128,-64 64,0 0))') As the_geom)  As hex
    CROSS JOIN (SELECT x*0.5 As xfactor 
        FROM generate_series(1,4) As x) As xf
    CROSS JOIN (SELECT y*0.5 As yfactor
        FROM generate_series(1,4) As y) As yf;

動作します。今もあるようですST_Transscaleが、どういうわけかそれを機能させる方法を理解できません...
n1000

0

これはパーティーに非常に遅れていますが、私は最近これを行うカスタムPostGIS関数を開発し、必要に応じてそれを縮小しました。

ST_Dilate

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.