我正在尝试使用ArcGIS 10.2基于预定义区域(例如400平方公里)创建点的缓冲区。除此之外,某些点的缓冲区靠近海岸线,因此需要将缓冲区修剪在海岸线上,并且仍然具有与内陆缓冲区相同的面积(400平方公里)。
有谁知道可以使用“模型开发器”或“ Arcpy”完成此操作吗?
我在Arcpy和R方面的技能有限,但是很乐意进行一些脚本编写以获得解决方案。
请参见下面的图片,其中显示了我要实现的目标的图形表示
我正在尝试使用ArcGIS 10.2基于预定义区域(例如400平方公里)创建点的缓冲区。除此之外,某些点的缓冲区靠近海岸线,因此需要将缓冲区修剪在海岸线上,并且仍然具有与内陆缓冲区相同的面积(400平方公里)。
有谁知道可以使用“模型开发器”或“ Arcpy”完成此操作吗?
我在Arcpy和R方面的技能有限,但是很乐意进行一些脚本编写以获得解决方案。
请参见下面的图片,其中显示了我要实现的目标的图形表示
Answers:
圆形缓冲区的面积是缓冲区半径的单调递增函数(无论如何在平面坐标系上)。因此,一种简单的搜索策略可以找到一个半径R
,使得半径缓冲区的R
区域A
被裁剪为多边形区域(达到一定容差)s
。
最简单的搜索算法只是二进制搜索。从两个半径开始,一个很小,一个很大,这样您想要的区域就在这些半径的裁剪缓冲区的区域之间。然后,只需取这些半径的中点并计算缓冲区,然后找出所需的半径是在中点之上还是之下。更新半径限制并重复,直到达到所需区域的一定公差为止。
用Python编写二进制搜索并使用ArcGIS Python API听起来像是学习的好方法!我很确定我几年前已经在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)
而上限则不那么重要,因为搜索算法会增大它直到捕获间隔。
如果初始最大半径确实太大,则搜索算法可能会失败,因为您可能会以很大的半径缓冲整个区域,在这种情况下,更改半径不会更改面积。但是明智的限制应该阻止这种情况的发生。
rgeos
程序包及其gBuffer
功能,最有可能...
R
代码中显示的方法的优点是(a)将GIS计算与搜索逻辑分开,并且(b)利用uniroot
经过优化和测试的搜索算法(in ),您不必编写一个自己(这可能不是最有效的)。