我试图用100公里的半径范围,缓冲点在我的数据集。我使用的是从包装gBuffer
功能rgeos
。这是我到目前为止有:
head( sampledf )
# postalcode lat lon city province
#1 A0A0A0 47.05564 -53.20198 Gander NL
#4 A0A1C0 47.31741 -52.81218 St. John's NL
coordinates( sampledf ) <- c( "lon", "lat" )
proj4string( sampledf ) <- CRS( "+proj=longlat +datum=WGS84" )
distInMeters <- 1000
pc100km <- gBuffer( sampledf, width=100*distInMeters, byid=TRUE )
我得到以下警告:
在gBuffer(sampledf,宽度= 100个* distInMeters,byid = TRUE):空间对象不被投影; GEOS预计平面坐标
从我的理解/阅读,我需要从“地理”的数据集的改变坐标参考系统(CRS),尤其是投影到“投射”。我不知道知道如何改变这种情况。这些都是加拿大的地址,我可以补充。所以NAD83在我看来,一个自然的投影选择,但我可能是错的。
任何/所有帮助将不胜感激。
随着越来越多一点点的挖掘,事实证明,用“预计”坐标参照系就是这么简单
# To get Statscan CRS, see here:
# http://spatialreference.org/ref/epsg/3347/
pc <- spTransform( sampledf, CRS( "+init=epsg:3347" ) )
EPSG3347,由加拿大统计局(足够用于加拿大地址)使用,采用的是等角圆锥投影。需要注意的是NAD83是不合适的:它是一个“地理”,而不是“投射” CRS。缓冲点
pc100km <- gBuffer( pc, width=100*distm, byid=TRUE )
# Add data, and write to shapefile
pc100km <- SpatialPolygonsDataFrame( pc100km, data=pc100km@data )
writeOGR( pc100km, "pc100km", "pc100km", driver="ESRI Shapefile" )
作为@MichaelChirico指出,您的数据投射到usergeos::gBuffer()
应谨慎应用。我不是在大地测量学方面的专家,但据我从这个ESRI文章(Understanding Geodesic Buffering)的理解,突出然后应用gBuffer
意味着实际生产欧氏缓冲区,而不是测地线的。欧氏缓冲区由投影坐标系统引入的失真影响。这些扭曲可能有一些担心,如果你的分析,涉及面广的缓冲器特别是更广泛的跨区域大的纬度(我相信加拿大是一个很好的候选人)。
前段时间我遇到了同样的问题来了,我的目标我对gis.stackexchange问题 - Euclidean and Geodesic Buffering in R。我想我当时和还提出了给定的答案将R代码是有关这个问题在这里。
其主要思想是利用geosphere::destPoint()
的。欲了解更多细节和更快的替代方案,看到上面的提到的gis.stackexchange链接。这是我的应用在你的两点旧的尝试:
library(geosphere)
library(sp)
pts <- data.frame(lon = c(-53.20198, -52.81218),
lat = c(47.05564, 47.31741))
pts
#> lon lat
#> 1 -53.20198 47.05564
#> 2 -52.81218 47.31741
make_GeodesicBuffer <- function(pts, width) {
# A) Construct buffers as points at given distance and bearing ---------------
dg <- seq(from = 0, to = 360, by = 5)
# Construct equidistant points defining circle shapes (the "buffer points")
buff.XY <- geosphere::destPoint(p = pts,
b = rep(dg, each = length(pts)),
d = width)
# B) Make SpatialPolygons -------------------------------------------------
# Group (split) "buffer points" by id
buff.XY <- as.data.frame(buff.XY)
id <- rep(1:dim(pts)[1], times = length(dg))
lst <- split(buff.XY, id)
# Make SpatialPolygons out of the list of coordinates
poly <- lapply(lst, sp::Polygon, hole = FALSE)
polys <- lapply(list(poly), sp::Polygons, ID = NA)
spolys <- sp::SpatialPolygons(Srl = polys,
proj4string = CRS("+proj=longlat +ellps=WGS84 +datum=WGS84"))
# Disaggregate (split in unique polygons)
spolys <- sp::disaggregate(spolys)
return(spolys)
}
pts_buf_100km <- make_GeodesicBuffer(as.matrix(pts), width = 100*10^3)
# Make a kml file and check the results on Google Earth
library(plotKML)
#> plotKML version 0.5-9 (2019-01-04)
#> URL: http://plotkml.r-forge.r-project.org/
kml(pts_buf_100km, file.name = "pts_buf_100km.kml")
#> KML file opened for writing...
#> Writing to KML...
#> Closing pts_buf_100km.kml
由reprex package创建于2019年2月11日(v0.2.1)
而对于玩具的时候,我包裹在一个包中的功能 - geobuffer
下面是一个例子:
# install.packages("devtools") # if you do not have devtools, then install it
devtools::install_github("valentinitnelav/geobuffer")
library(geobuffer)
pts <- data.frame(lon = c(-53.20198, -52.81218),
lat = c(47.05564, 47.31741))
pts_buf_100km <- geobuffer_pts(xy = pts, dist_m = 100*10^3)
由reprex package创建于2019年2月11日(v0.2.1)
其他人可能会想出更好的解决方案,但现在,这很适合于我的问题,希望能够解决其他的问题也是如此。