Crear zonas de amortiguamiento limitadas por una costa

10

Estoy tratando de usar ArcGIS 10.2 para crear un búfer de puntos basado en un área predefinida (por ejemplo, 400 km2). Además de eso, los amortiguadores de algunos de los puntos están cerca de la costa que requiere que los amortiguadores se recorten en la costa y aún tengan la misma área que los que están tierra adentro (400 km2).

¿Alguien sabe cómo podría hacerse esto con Model Builder o Arcpy?

Tengo habilidades limitadas con Arcpy y R, pero estaría encantado de trabajar en algunos scripts para obtener una solución para esto.

Vea la imagen a continuación que muestra una representación gráfica de lo que estoy tratando de lograr

[1]

Funkeh-Monkeh
fuente
2
¿Sería capaz de incluir una imagen de lo que está tratando de describir en palabras?
PolyGeo
¿Cómo agrandarías las áreas cuando cortes? ¿Extendiendo el radio del búfer?
Peter Horsbøll Møller

Respuestas:

15

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 Rtal que el área del búfer de radio Rrecortado a la región poligonal Asea ​​(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, bes el búfer:

plot(b$b, col=2)
plot(uk, add=TRUE)

y tiene el área correcta:

gArea(b$b)
[1] 1e+10

y res 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.

Hombre espacial
fuente
¿Cómo hiciste esto en R? Olvidé mencionar que tengo algo de experiencia en R, así que no me importaría una solución con R también.
Funkeh-Monkeh
El rgeospaquete y su gBufferfunción, muy probablemente ...
Spacedman
En realidad digo una mentira, implementé algo así en Python como un complemento QGIS: protegió los polígonos hasta que el poli amortiguado tenía 2x (o Nx) el área del polígono original. Sin embargo, el mismo algoritmo de búsqueda.
Spacedman
+1. Las ventajas del enfoque que se muestra en el Rcódigo son: (a) separa los cálculos de SIG de la lógica de búsqueda y (b) aprovecha los algoritmos de búsqueda (en uniroot) que han sido optimizados y probados; no tiene que escribir uno usted mismo (y probablemente no será el más eficiente).
whuber
Sospecho que scipy implementa algoritmos de búsqueda de raíz similares en su módulo de optimización: docs.scipy.org/doc/scipy/reference/optimize.html (sí,? Uniroot cita a Brent, scipy tiene funciones Brent-ish)
Spacedman
1

Es casi imposible, debido a la posición de los puntos. Puede crear zonas de amortiguamiento de 400 km 2 , pero los puntos más cercanos a la costa siempre tendrán un área más pequeña en comparación con las más alejadas (> 400 km 2 ).

Lo único que puede hacer es realizar un análisis de búfer en los puntos y luego recortar los búferes creados con la función de línea de costa.

Stefan
fuente
2
Puede que no sea imposible , pero podría ser un problema NP Complete que puede confundir la solución. Conseguir que el área sea perfecta es el desafío (puede tomar decenas de iteraciones para acercarse).
Vince
3
¡No es imposible, y ni siquiera es difícil!
Spacedman