Dalam Memahami Buffer Geodesik , Tim Pengembangan Geoproses Esri membedakan antara Euclidean dan Buffering Geodesik. Mereka menyimpulkan dengan "Buffer Euclidean yang dilakukan pada kelas fitur yang diproyeksikan dapat menghasilkan buffer yang menyesatkan dan salah secara teknis. Namun, buffering geodesik akan selalu menghasilkan hasil yang akurat secara geografis karena buffer geodesik tidak terpengaruh oleh distorsi yang diperkenalkan oleh sistem koordinat yang diproyeksikan".
Saya harus bekerja dengan dataset global titik dan koordinatnya tidak diproyeksikan ( +proj=longlat +ellps=WGS84 +datum=WGS84
). Apakah ada fungsi untuk membuat buffer geodesik dalam R ketika lebar diberikan dalam satuan metrik? Saya tahu gBuffer
dari rgeos
paket. Fungsi ini membuat buffer dalam satuan objek spasial yang digunakan ( contoh ), jadi, saya harus memproyeksikan koordinat untuk dapat membuat buffer X km yang diinginkan. Memproyeksikan dan kemudian menerapkan gBuffer
cara yang benar-benar membuat buffer Euclidean sebagai lawan dari Geodesic yang saya butuhkan. Di bawah ini adalah beberapa kode untuk menggambarkan kekhawatiran saya:
require(rgeos)
require(sp)
require(plotKML)
# Generate a random grid-points for a (almost) global bounding box
b.box <- as(raster::extent(120, -120, -60, 60), "SpatialPolygons")
proj4string(b.box) <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
set.seed(2017)
pts <- sp::spsample(b.box, n=100, type="regular")
plot(pts@coords)
# Project to Mollweide to be able to apply buffer with `gBuffer`
# (one could use other projection)
pts.moll <- sp::spTransform(pts, CRSobj = "+proj=moll")
# create 1000 km buffers around the points
buf1000km.moll <- rgeos::gBuffer(spgeom = pts.moll, byid = TRUE, width = 10^6)
plot(buf1000km.moll)
# convert back to WGS84 unprojected
buf1000km.WGS84 <- sp::spTransform(buf1000km.moll, CRSobj = proj4string(pts))
plot(buf1000km.WGS84) # distorsions are present
# save as KML to better visualize distorted Euclidian buffers on Google Earth
plotKML::kml(buf1000km.WGS84, file.name = "buf1000km.WGS84.kml")
Gambar di bawah ini menggambarkan buffer Euclidian yang terdistorsi (radius 1000 km) yang dihasilkan dengan kode dari atas.
Robert J. Hijmans dalam Pengantar paket "geosphere" , bagian 4 Point at distance and bearing
memberikan contoh tentang bagaimana membuat "poligon melingkar dengan jari-jari tetap, tetapi dalam koordinat bujur / lintang", yang saya pikir dapat disebut "buffer geodesik". Saya mengacaukan ide ini dan saya menulis beberapa kode yang semoga melakukan hal yang benar, tetapi saya bertanya-tanya apakah sudah ada beberapa fungsi R-geodesik-buffer dalam beberapa paket yang memungkinkan radius metrik sebagai input:
require(geosphere)
make_GeodesicBuffer <- function(pts, width) {
### A) Construct buffers as points at given distance and bearing
# a vector of bearings (fallows a circle)
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:length(pts), 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(as.character("+proj=longlat +ellps=WGS84 +datum=WGS84")))
# Disaggregate (split in unique polygons)
spolys <- sp::disaggregate(spolys)
return(spolys)
}
buf1000km.geodesic <- make_GeodesicBuffer(pts, width=10^6)
# save as KML to visualize geodesic buffers on Google Earth
plotKML::kml(buf1000km.geodesic, file.name = "buf1000km.geodesic.kml")
Gambar di bawah ini menggambarkan buffer Geodesic (radius 1000 km).
Sunting 2019-02-12 : Untuk kenyamanan, saya membungkus versi fungsi dalam paket geobuffer . Jangan ragu untuk berkontribusi dengan permintaan tarik.
R
bisa melakukan itu - itu saran yang bagus. Tetapi karena untuk model Bumi bulat ini adalah proyeksi yang sangat sederhana, cukup sederhana untuk menulis kode secara langsung.