Diện tích của bộ đệm tròn là một hàm tăng đơn điệu của bán kính bộ đệm (dù sao trên hệ tọa độ phẳng). Vì vậy, một chiến lược tìm kiếm đơn giản có thể tìm thấy một bán kính R
sao cho diện tích của vùng đệm bán kính được R
cắt theo vùng đa giác A
là (tối đa một số dung sai) s
.
Thuật toán tìm kiếm đơn giản nhất sẽ chỉ là tìm kiếm nhị phân. Bắt đầu với hai bán kính, một rất nhỏ và một rất lớn, sao cho diện tích bạn muốn nằm ở đâu đó giữa vùng đệm được cắt của các bán kính đó. Sau đó, chỉ cần lấy điểm giữa của những vùng đó và tính toán các vùng đệm và tìm hiểu xem bán kính bạn muốn ở trên hay dưới điểm giữa. Cập nhật giới hạn bán kính của bạn và lặp lại cho đến khi bạn đạt được trong phạm vi dung sai của khu vực bạn muốn.
Viết một tìm kiếm nhị phân bằng Python và sử dụng API Python của ArcGIS nghe có vẻ là một cách tốt để tìm hiểu! Tôi khá chắc chắn rằng tôi đã làm điều này trong R, nhiều năm trước ...
Đây là một số mã 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))
}
Sử dụng:
Đầu tiên thiết lập một khu vực đa giác đơn giản của Vương quốc Anh:
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)
Bây giờ xác định một điểm:
p = SpatialPoints(coords=list(x=269042, y=235937), proj4string=CRS("+init=epsg:27700"))
Sau đó, bạn chỉ cần:
b = buff_with_area(p, uk, 10000000000, 1, 10000)
Đây là danh sách có hai thành phần, b
là bộ đệm:
plot(b$b, col=2)
plot(uk, add=TRUE)
và nó có đúng khu vực:
gArea(b$b)
[1] 1e+10
và r
là đầu ra từ uniroot
, bao gồm giá trị bán kính đệm.
> b$r$root
[1] 63338.88
Vì vậy, trong trường hợp này, chiều rộng bộ đệm là dưới 64km.
Điều duy nhất cần giải quyết ở đây là các giá trị ban đầu thấp hơn và cao hơn - Tôi đoán bạn có thể giao tiếp với bán kính thấp hơn sqrt(A/pi)
và trên không quan trọng vì thuật toán tìm kiếm sẽ tăng nó cho đến khi nó bắt được khoảng.
Thuật toán tìm kiếm có thể thất bại nếu bán kính tối đa ban đầu thực sự quá lớn, vì bạn có thể đệm toàn bộ khu vực của mình với bán kính rất lớn, trong trường hợp thay đổi bán kính sẽ không thay đổi khu vực ... Nhưng các giới hạn hợp lý sẽ ngăn chặn điều này xảy ra.