Створіть область буферів, обмежених береговою лінією


10

Я намагаюся використовувати ArcGIS 10.2 для створення буфера точок на основі заздалегідь визначеної області (наприклад, 400 кв. Км). Крім того, буфери деяких пунктів знаходяться близько до берегової лінії, що вимагає відсікання буферів на узбережжі і все одно має ту саму площу, що і внутрішня (400 кв. Км).

Хтось знає, як це можна було зробити з Model Builder або Arcpy?

Я маю обмежені навички роботи з Arcpy і R, але з радістю працюю над деякими сценаріями, щоб отримати рішення для цього.

Будь ласка, дивіться зображення нижче, яке показує графічне зображення того, що я намагаюся досягти

[1]


2
Чи зможете ви включити зображення того, що ви намагаєтесь описати словами?
PolyGeo

Як би ви зробили площі більшими, коли потім ріжете? Подовжуючи радіус буфера?
Пітер Хорсбёлл Мёллер

Відповіді:


15

Площа кругового буфера - це монотонно зростаюча функція радіусу буфера (так чи інакше на планарній системі координат). Таким чином, проста стратегія пошуку може знайти радіус, Rтакий, що площа буфера радіуса, Rобрізана до полігональної області, Aє (до деякого допуску) s.

Найпростішим алгоритмом пошуку був би просто двійковий пошук. Почніть з двох радіусів, одного дуже малого та одного дуже великого, так що потрібна область знаходиться десь між площею обрізаних буферів цих радіусів. Тоді просто візьміть середню точку цих і обчисліть області буфера і з’ясуйте, чи потрібний радіус вище або нижче середини. Оновіть обмеження радіусу та повторюйте, поки не досягнете деякої толерантності до потрібної області.

Написання двійкового пошуку в Python та використання API ArcGIS Python звучить як хороший спосіб вчитися! Я впевнений, що робив це в R, років тому ...

Ось декілька код 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))
}

Використання:

Спочатку встановіть простий полігональний регіон Великобританії:

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)

Тепер визначте крапку:

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

Тоді ви просто:

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

Це список з двома компонентами, bце буфер:

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

і він має потрібну область:

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

і rє виходом з uniroot, який включає значення радіусу буфера.

> b$r$root
[1] 63338.88

Так що в цьому випадку ширина буфера була трохи менше 64 км.

Єдине, з чим тут можна зіткнутися, - це нижнє та верхнє початкові значення - я думаю, ви можете інтуїти нижній радіус як, sqrt(A/pi)а верхній не так важливий, оскільки алгоритм пошуку збільшуватиме його, поки він не захопить інтервал.

Алгоритм пошуку може вийти з ладу, якщо початковий максимальний радіус дійсно занадто великий, оскільки ви, можливо, буферизуєте весь ваш регіон з величезним радіусом, і в цьому випадку зміна радіусу не може змінити область ... Але розумні межі повинні зупинити це.


Як ти це зробив у R? Я забув згадати, що у мене є досвід роботи в галузі R, тому я не заперечую проти рішення, використовуючи R.
Функех-Монке

rgeosПакет і його gBufferфункції, швидше за все ...
Spacedman

Насправді я кажу брехню, я реалізував щось подібне на Python як плагін QGIS - він буферував багатокутники, поки буферизований полі був 2х (або Nx) площею початкового багатокутника. Хоча алгоритм пошуку однаковий.
Розміщений

+1. Перевагами підходу, показаного в Rкоді, є: (а) він відокремлює обчислення ГІС від логіки пошуку та (б) він використовує великі літери алгоритмів пошуку (в uniroot), які були оптимізовані та протестовані - вам не потрібно писати себе (і це, швидше за все, не буде найефективнішим).
whuber

Я підозрюю, що scipy реалізує подібні алгоритми кореневого пошуку в своєму модулі оптимізації: docs.scipy.org/doc/scipy/reference/optimize.html (так, uniroot цитує Brent, scipy має функції Brent-ish)
Spacedman

1

Це майже неможливо через положення очок. Можна створити буфери розміром 400 км 2 , але пункти, розташовані ближче до берегової лінії, завжди матимуть меншу площу порівняно з подальшими (> 400 км 2 ).

Єдине, що ви можете зробити - це виконати аналіз буфера на точках і обрізати створені буфери за допомогою функції узбережжя.


2
Це може бути неможливим , але це може бути NP Повна проблема, яка може заплутати рішення. Досконалість області - це складне завдання (може знадобитися кілька ітерацій, щоб наблизитися).
Вінс

3
Це не неможливо, і навіть не важко!
Розміщений
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.