データセット内のポイントを半径100kmでバッファリングしようとしています。パッケージ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、width = 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" ) )
STATSCAN(カナダの住所に適しています)で使用されるEPSG3347は、ランベルト正角円錐図法を使用します。 NAD83は不適切であることに注意してください。これは、「予測された」CRSではなく「地理的な」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の記事( 測地線バッファリングについて )から理解できる限り、gBuffer
を投影して適用すると、実際に生成することを意味しますEuclidean =バッファとは対照的に測地線バッファ。ユークリッドバッファは、投影された座標系によって導入された歪みの影響を受けます。これらの歪みは、分析に広いバッファーが含まれている場合、特に広い範囲の緯度の範囲が広い場合は、心配する必要があるかもしれません(カナダが良い候補だと思います)。
しばらく前に同じ問題に遭遇し、質問をgis.stackexchangeに向けました- Rのユークリッドおよび測地線バッファリング 。私が提案したRコードと与えられた答えは、ここでもこの質問に関連していると思います。
主なアイデアは、geosphere::destPoint()
を利用することです。詳細とより高速な代替手段については、上記のgis.stackexchangeリンクを参照してください。これがあなたの2つのポイントに適用された私の古い試みです:
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
2019-02-11に reprexパッケージ (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)
2019-02-11に reprexパッケージ (v0.2.1)によって作成されました
他の人はより良い解決策を思い付くかもしれませんが、今のところ、これは私の問題に対してうまく機能し、うまくいけば他の問題も解決できるでしょう。