El área de un búfer circular es una función monotónicamente creciente del radio del búfer (de todos modos, en un sistema de coordenadas planas). Entonces, una estrategia de búsqueda simple puede encontrar un radio R
tal que el área del búfer de radio R
recortado a la región poligonal A
sea (hasta cierta tolerancia) s
.
El algoritmo de búsqueda más simple sería una búsqueda binaria. Comience con dos radios, uno muy pequeño y otro muy grande, de modo que el área que desee esté en algún lugar entre el área de los búferes recortados de esos radios. Luego solo tome el punto medio de esos y calcule las áreas de búfer, y descubra si el radio que desea está por encima o por debajo del punto medio. Actualice sus límites de radio y repita hasta llegar a cierta tolerancia del área deseada.
¡Escribir una búsqueda binaria en Python y usar la API ArcGIS Python suena como una buena manera de aprender! Estoy bastante seguro de que hice esto en R, hace años ...
Aquí hay un código 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))
}
Uso:
Primero configure una región poligonal del Reino Unido simple:
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)
Ahora defina un punto:
p = SpatialPoints(coords=list(x=269042, y=235937), proj4string=CRS("+init=epsg:27700"))
Entonces solo:
b = buff_with_area(p, uk, 10000000000, 1, 10000)
Esta es una lista con dos componentes, b
es el búfer:
plot(b$b, col=2)
plot(uk, add=TRUE)
y tiene el área correcta:
gArea(b$b)
[1] 1e+10
y r
es la salida de uniroot
, que incluye el valor del radio del búfer.
> b$r$root
[1] 63338.88
Entonces, en este caso, el ancho del búfer era un poco menos de 64 km.
Las únicas cosas con las que puede jugar aquí son los valores iniciales inferiores y superiores: supongo que puede intuir un radio más bajo sqrt(A/pi)
y el superior no es tan importante ya que el algoritmo de búsqueda lo aumentará hasta que capture el intervalo.
El algoritmo de búsqueda podría fallar si el radio máximo inicial es realmente demasiado grande, ya que podría estar amortiguando toda su región con un radio enorme, en cuyo caso cambiar el radio no cambiará el área ... Pero los límites sensibles deberían evitar que esto suceda.