Area buffer sirkular adalah fungsi peningkatan jari-jari buffer secara monotonik (pada sistem koordinat planar). Jadi strategi pencarian yang sederhana dapat menemukan jari R
- jari sedemikian rupa sehingga daerah penyangga jari-jari yang R
terpotong pada wilayah poligon A
adalah (hingga toleransi) s
.
Algoritma pencarian paling sederhana hanya akan menjadi pencarian biner. Mulailah dengan dua jari, satu sangat kecil dan satu sangat besar, sehingga area yang Anda inginkan berada di antara area buffer yang terpotong dari jari-jari tersebut. Kemudian ambil saja titik tengahnya dan hitung daerah penyangga, dan cari tahu apakah jari-jari yang Anda inginkan berada di atas atau di bawah titik tengah. Perbarui batas radius Anda dan ulangi sampai Anda mendapatkan toleransi di area yang Anda inginkan.
Menulis pencarian biner dengan Python dan menggunakan ArcGIS Python API terdengar seperti cara yang bagus untuk belajar! Saya cukup yakin saya sudah melakukan ini di R, tahun lalu ...
Ini beberapa kode 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))
}
Pemakaian:
Pertama-tama mengatur wilayah poligon UK sederhana:
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)
Sekarang tentukan satu poin:
p = SpatialPoints(coords=list(x=269042, y=235937), proj4string=CRS("+init=epsg:27700"))
Maka Anda hanya:
b = buff_with_area(p, uk, 10000000000, 1, 10000)
Ini adalah daftar dengan dua komponen, b
adalah buffer:
plot(b$b, col=2)
plot(uk, add=TRUE)
dan memiliki area yang tepat:
gArea(b$b)
[1] 1e+10
dan r
merupakan output dari uniroot
, yang mencakup nilai radius buffer.
> b$r$root
[1] 63338.88
Jadi dalam hal ini lebar buffer sedikit di bawah 64 km.
Satu-satunya hal untuk mengutak-atik di sini adalah nilai awal yang lebih rendah dan atas - Saya kira Anda dapat intuisi radius yang lebih rendah karena sqrt(A/pi)
dan atas tidak begitu penting karena algoritma pencarian akan meningkatkannya sampai menangkap interval.
Algoritme pencarian mungkin gagal jika jari-jari maks awal benar-benar terlalu besar, karena Anda mungkin melindungi seluruh wilayah Anda dengan jari-jari besar, dalam hal ini mengubah jari-jari tidak akan mengubah area ... Tetapi batas yang masuk akal harus menghentikan hal ini terjadi.