Créer des zones tampons limitées par un littoral


10

J'essaie d'utiliser ArcGIS 10.2 pour créer un tampon de points basé sur une zone prédéfinie (par exemple 400 km2). De plus, les tampons de certains points sont proches du littoral, ce qui nécessite que les tampons soient coupés sur le littoral et aient toujours la même superficie que ceux qui sont à l'intérieur des terres (400 km2).

Est-ce que quelqu'un sait comment cela pourrait être fait avec Model Builder ou Arcpy?

J'ai des compétences limitées avec Arcpy et R, mais je serais heureux de travailler sur certains scripts pour obtenir une solution.

Veuillez voir l'image ci-dessous montrant une représentation graphique de ce que j'essaie de réaliser

[1]


2
Pourriez-vous inclure une image de ce que vous essayez de décrire avec des mots?
PolyGeo

Comment pourriez-vous agrandir les zones lorsque vous coupez alors? En étendant le rayon du tampon?
Peter Horsbøll Møller

Réponses:


15

L'aire d'un tampon circulaire est une fonction monotone augmentant le rayon du tampon (sur un système de coordonnées planaires de toute façon). Ainsi, une stratégie de recherche simple peut trouver un rayon Rtel que la zone du tampon de rayon Rdécoupée dans la région polygonale Aest (jusqu'à une certaine tolérance) s.

L'algorithme de recherche le plus simple serait simplement une recherche binaire. Commencez avec deux rayons, un très petit et un très grand, de sorte que la zone souhaitée se situe quelque part entre la zone des tampons écrêtés de ces rayons. Ensuite, prenez simplement le milieu de celles-ci et calculez les zones tampons, et déterminez si le rayon souhaité est au-dessus ou en dessous du point médian. Mettez à jour vos limites de rayon et répétez jusqu'à ce que vous atteigniez une certaine tolérance de la zone souhaitée.

Écrire une recherche binaire en Python et utiliser l'API ArcGIS Python semble être un bon moyen d'apprendre! Je suis presque sûr d'avoir fait ça dans R, il y a des années ...

Voici un code 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))
}

Usage:

Configurez d'abord une simple région polygonale britannique:

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)

Définissez maintenant un point:

p = SpatialPoints(coords=list(x=269042, y=235937), proj4string=CRS("+init=epsg:27700"))

Ensuite, vous venez de:

b = buff_with_area(p, uk, 10000000000, 1, 10000)

Ceci est une liste avec deux composants, best le tampon:

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

et il a la bonne zone:

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

et rest la sortie de uniroot, qui inclut la valeur du rayon du tampon.

> b$r$root
[1] 63338.88

Dans ce cas, la largeur du tampon était donc un peu moins de 64 km.

Les seules choses à manipuler ici sont les valeurs initiales inférieures et supérieures - je suppose que vous pouvez intuitivement un rayon inférieur sqrt(A/pi)et la supérieure n'est pas si importante que l'algorithme de recherche l'augmentera jusqu'à ce qu'il capture l'intervalle.

L'algorithme de recherche peut échouer si le rayon max initial est vraiment trop grand, car vous pouvez tamponner toute votre région avec un rayon énorme, auquel cas le changement de rayon ne changera pas la zone ... Mais des limites raisonnables devraient empêcher cela de se produire.


Comment avez-vous fait cela dans R? J'ai oublié de mentionner que j'ai une certaine expérience en R, donc cela ne me dérangerait pas une solution utilisant R aussi.
Funkeh-Monkeh

Le rgeospaquet et sa gBufferfonction, très probablement ...
Spacedman

En fait, je dis un mensonge, j'ai implémenté quelque chose comme ça en Python en tant que plugin QGIS - il a tamponné les polygones jusqu'à ce que le poly tamponné soit 2x (ou Nx) la zone du polygone d'origine. Même algorithme de recherche.
Spacedman

+1. Les avantages de l'approche présentée dans le Rcode sont (a) il sépare les calculs SIG de la logique de recherche et (b) il capitalise sur des algorithmes de recherche (en uniroot) qui ont été optimisés et testés - vous n'avez pas besoin d'en écrire un vous-même (et ce ne sera probablement pas le plus efficace).
whuber

Je soupçonne que scipy implémente des algorithmes de recherche de racines similaires dans son module d'optimisation: docs.scipy.org/doc/scipy/reference/optimize.html (oui,? Uniroot cite Brent, scipy a des fonctions Brent-ish)
Spacedman

1

C'est presque impossible, à cause de la position des points. Vous pouvez créer des zones tampons de 400 km 2 , mais les points plus proches du littoral auront toujours une zone plus petite que ceux plus éloignés (> 400 km 2 ).

La seule chose que vous pouvez faire est d'effectuer une analyse de tampon sur les points et de découper ensuite les tampons créés avec la fonction littoral.


2
Ce n'est peut-être pas impossible , mais il peut s'agir d'un problème NP Complete qui peut confondre la solution. Obtenir la zone parfaite est le défi (cela peut prendre des dizaines d'itérations pour se rapprocher).
Vince

3
Ce n'est pas impossible, et ce n'est même pas difficile!
Spacedman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.