円形バッファーの面積は、バッファー半径の単調増加関数です(とにかく平面座標系で)。したがって、単純な検索戦略は、多角形領域にクリップされたR
半径のバッファのR
領域A
が(ある程度の許容範囲まで)であるような半径を見つけることができますs
。
最も単純な検索アルゴリズムは、バイナリ検索です。1つの非常に小さい半径と1つの非常に大きい半径の2つの半径から開始して、必要な領域が、それらの半径のクリップされたバッファーの領域の間のどこかにあるようにします。次に、それらの中間点を取り、バッファー領域を計算し、必要な半径が中間点の上か下かを計算します。半径の制限を更新し、目的の領域の許容範囲内になるまで繰り返します。
Pythonでバイナリ検索を記述し、ArcGIS Python APIを使用することは、学ぶのに良い方法のように思えます!私はこれをRで何年も前に行ったとかなり確信しています...
ここにいくつかのRコードがあります:
cropareabuff <- function(pt, region, target){
f = function(r){
b = rgeos::gBuffer(pt, width=r)
return(gArea(gIntersection(b, region)) - target)
}
f
}
buff_with_area <- function(pt, region, target, lower, upper){
f = cropareabuff(pt, region, target)
r = uniroot(f, lower=lower, upper=upper, extendInt="upX")
list(r=r, b=gIntersection(rgeos::gBuffer(pt, width=r$root), region))
}
使用法:
最初に、シンプルなUKポリゴンリージョンを設定します。
library(raster); library(rgeos); library(rgdal)
uk = getData("GADM", country="GBR", level=0)
uk = spTransform(uk,CRS("+init=epsg:27700"))
uk = gSimplify(uk, tol=1000)
次に、ポイントを定義します。
p = SpatialPoints(coords=list(x=269042, y=235937), proj4string=CRS("+init=epsg:27700"))
それからあなたはただ:
b = buff_with_area(p, uk, 10000000000, 1, 10000)
これは2つのコンポーネントを含むリストでb
あり、バッファです。
plot(b$b, col=2)
plot(uk, add=TRUE)
そしてそれは正しい領域を持っています:
gArea(b$b)
[1] 1e+10
以下とr
から出力されるuniroot
バッファ半径値を含みます。
> b$r$root
[1] 63338.88
したがって、この場合のバッファ幅は64km弱でした。
ここでいじる唯一の事柄はより低いそしてより高い初期値です-私はあなたがより低い半径を直感することができsqrt(A/pi)
、検索アルゴリズムがそれが間隔を捕獲するまでそれを増やすので、より高い半径はそれほど重要ではないと思います。
領域全体を巨大な半径でバッファリングしている可能性があるため、初期最大半径が本当に大きすぎると、検索アルゴリズムが失敗する可能性があります。