Geographic Information Systems Asked by Wei Liao on May 10, 2021
I have a lot of polygons (shapefile) and need to creat their own buffer according to the area of each polygons,despite I have found some infomation in Creating OUTSIDE_ONLY buffer around polygon using R?.
# create basic function
outerBuffer<-function(x, dist){
buff<-buffer(x, width =dist - 1, dissolve = F)
e<-erase(buff,x)
return(e)
}
library(maptools)
library(rgdal)
# create data
p1 = shapefile('42gp.shp')
# apply function, create only outside buffer
a2<-outerBuffer(p1,500)
# highlight isobath with the buffer and add outline
plot(buf, outline=FALSE, n = 10, col = 2, lwd=.4)
plot(buf, lwd = 0.7, fg = 2)
# }
# tradaaa ! :)
plot(a2, col = "white", main= "Outer buffer only")
What can I write the R script for creating their own buffer according to the area of each polygons?
I don't think you can easily compute the required buffer distance to return a buffer of a given area, except for simple figures like squares and circles.
The solution will depend on the fact that the buffer area always increases with buffer width (it is "monotone increasing"). Write a function that takes a polygon and a buffer size and returns the difference between the ring area and the area of the polygon. Your problem is then finding a buffer width where this function returns zero, which you can do with the uniroot
function.
So in full you need these three functions:
outerBuffer<-function(x, dist){
## I don't udnerstand why you had "dist-1" here:
buff<-buffer(x, width =dist, dissolve = F)
e<-erase(buff,x)
return(e)
}
areadiff <- function(dist, x){
area(x)-area(outerBuffer(x, dist))
}
matchAreaBuff <- function(shp, bufferarea,
min=0.000001, max=10*sqrt(area(shp))){
zerofind = uniroot(areadiff, c(min, max), x=shp)
return(list(
buffer = outerBuffer(shp, zerofind$root),
root = zerofind
))
}
Then for some single shape shp
you can do:
Get a buffer with the area equal to the area of shp
:
> matchedbuffer = matchAreaBuff(shp, area(shp))
Plot the buffer and the original polygon:
> plot(matchedbuffer$buffer)
> plot(shp, add=TRUE, col="red")
Check the areas match:
> area(shp)
[1] 0.1416047
> area(matchedbuffer$buffer)
[1] 0.1416076
The buffer width was:
> matchedbuffer$root$root
[1] 0.06890648
The other parts of matchedbuffer$root
are the output from uniroot
and will tell you if the process converged well and the precision.
Note you may have to change the min and max parameters if your shape is on a wildly different scale to mine, or there might be some extra parameters to uniroot
that let it search for an interval that has a zero crossing in it.
Answered by Spacedman on May 10, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP