Erstellen Sie Flächenpuffer, die durch eine Küstenlinie begrenzt sind

10

Ich versuche, mit ArcGIS 10.2 einen Punktepuffer basierend auf einem vordefinierten Bereich (z. B. 400 km²) zu erstellen. Darüber hinaus befinden sich die Puffer einiger Punkte in Küstennähe, sodass die Puffer an der Küste abgeschnitten werden müssen, und haben immer noch dieselbe Fläche wie die im Landesinneren (400 km²).

Weiß jemand, wie dies mit Model Builder oder Arcpy gemacht werden kann?

Ich habe nur begrenzte Kenntnisse mit Arcpy und R, würde aber gerne an einigen Skripten arbeiten, um eine Lösung dafür zu finden.

Das Bild unten zeigt eine grafische Darstellung dessen, was ich erreichen möchte

[1]

Funkeh-Monkeh
quelle
2
Könnten Sie ein Bild von dem, was Sie beschreiben möchten, in Worte fassen?
PolyGeo
Wie würden Sie die Flächen größer machen, wenn Sie dann schneiden? Durch Erweitern des Radius des Puffers?
Peter Horsbøll Møller

Antworten:

15

Die Fläche eines Kreispuffers ist eine monoton ansteigende Funktion des Pufferradius (auf einem planaren Koordinatensystem sowieso). Eine einfache Suchstrategie kann also einen Radius finden, Rso dass der Bereich des Puffers des Radius, der Rauf den polygonalen Bereich begrenzt Aist, (bis zu einer gewissen Toleranz) ist s.

Der einfachste Suchalgorithmus wäre nur eine binäre Suche. Beginnen Sie mit zwei Radien, einem sehr kleinen und einem sehr großen, so dass der gewünschte Bereich irgendwo zwischen dem Bereich der abgeschnittenen Puffer dieser Radien liegt. Nehmen Sie dann einfach den Mittelpunkt dieser und berechnen Sie die Pufferbereiche und stellen Sie fest, ob der gewünschte Radius über oder unter dem Mittelpunkt liegt. Aktualisieren Sie Ihre Radiusgrenzen und wiederholen Sie den Vorgang, bis Sie eine gewisse Toleranz für den gewünschten Bereich erreicht haben.

Das Schreiben einer binären Suche in Python und die Verwendung der ArcGIS Python-API klingt nach einer guten Lernmethode! Ich bin mir ziemlich sicher, dass ich das vor Jahren in R gemacht habe ...

Hier ist ein R-Code:

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))
}

Verwendungszweck:

Richten Sie zunächst eine einfache polygonale Region in Großbritannien ein:

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)

Definieren Sie nun einen Punkt:

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

Dann bist du einfach:

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

Dies ist eine Liste mit zwei Komponenten, bist der Puffer:

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

und es hat den richtigen Bereich:

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

und rist die Ausgabe von uniroot, die den Pufferradiuswert enthält.

> b$r$root
[1] 63338.88

In diesem Fall lag die Pufferbreite also etwas unter 64 km.

Die einzigen Dinge, mit denen Sie hier herumspielen müssen, sind die unteren und oberen Anfangswerte - ich denke, Sie können einen unteren Radius als intuitiv verstehen, sqrt(A/pi)und der obere ist nicht so wichtig, da der Suchalgorithmus ihn vergrößert, bis er das Intervall erfasst.

Der Suchalgorithmus schlägt möglicherweise fehl, wenn der anfängliche maximale Radius wirklich zu groß ist, da Sie möglicherweise Ihre gesamte Region mit einem großen Radius puffern. In diesem Fall ändert eine Änderung des Radius nicht den Bereich ... Aber sinnvolle Grenzen sollten dies verhindern.

Spacedman
quelle
Wie hast du das in R gemacht? Ich habe vergessen zu erwähnen, dass ich einige Erfahrungen mit R habe, daher würde mir eine Lösung mit R nichts ausmachen.
Funkeh-Monkeh
Das rgeosPaket und seine gBufferFunktion, höchstwahrscheinlich ...
Spacedman
Eigentlich lüge ich, ich habe so etwas in Python als QGIS-Plugin implementiert - es hat Polygone gepuffert, bis das gepufferte Poly 2x (oder Nx) der Fläche des ursprünglichen Polygons war. Gleicher Suchalgorithmus.
Spacedman
+1. Die Vorteile des im RCode gezeigten Ansatzes sind: (a) Er trennt die GIS-Berechnungen von der Suchlogik und (b) Er nutzt unirootoptimierte und getestete Suchalgorithmen (in ) - Sie müssen keinen schreiben selbst (und es wird wahrscheinlich nicht das effizienteste sein).
whuber
Ich vermute, scipy implementiert ähnliche Root-Finding-Algorithmen in seinem Optimierungsmodul: docs.scipy.org/doc/scipy/reference/optimize.html (ja,? Uniroot zitiert Brent, scipy hat Brent-ish-Funktionen)
Spacedman
1

Aufgrund der Position der Punkte ist dies fast unmöglich. Sie können Puffer mit einer Länge von 400 km 2 erstellen , aber Punkte, die näher an der Küste liegen, haben immer eine kleinere Fläche als die weiter entfernten (> 400 km 2 ).

Das einzige , was Sie tun können , ist eine do ausführen Pufferanalyse auf den Punkten und Clip mit der Küste Feature anschließend die erstellten Puffer.

Stefan
quelle
2
Es mag nicht unmöglich sein , aber es könnte ein NP Complete- Problem sein, das die Lösung verwirren könnte. Den Bereich perfekt zu machen, ist die Herausforderung (es kann viele Iterationen erfordern, um näher zu kommen).
Vince
3
Es ist nicht unmöglich und es ist nicht einmal schwer!
Spacedman