缓冲器(GEO),其与gbuffer R个空间分

问题描述 投票:10回答:2

我试图用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在我看来,一个自然的投影选择,但我可能是错的。

任何/所有帮助将不胜感激。

r gis geospatial
2个回答
19
投票

随着越来越多一点点的挖掘,事实证明,用“预计”坐标参照系就是这么简单

# 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" ) 

3
投票

作为@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)

enter image description here


而对于玩具的时候,我包裹在一个包中的功能 - 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)

其他人可能会想出更好的解决方案,但现在,这很适合于我的问题,希望能够解决其他的问题也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.