Al comprender el almacenamiento en búfer geodésico , el equipo de desarrollo de geoprocesamiento de Esri distingue entre el almacenamiento en búfer geodésico y euclidiano. Concluyen con "El almacenamiento en búfer euclidiano realizado en clases de entidad proyectadas puede producir amortiguadores engañosos y técnicamente incorrectos. Sin embargo, el almacenamiento en búfer geodésico siempre producirá resultados geográficamente precisos porque los amortiguadores geodésicos no se ven afectados por las distorsiones introducidas por los sistemas de coordenadas proyectados".
Tengo que trabajar con un conjunto de datos global de puntos y las coordenadas no están proyectadas ( +proj=longlat +ellps=WGS84 +datum=WGS84
). ¿Existe una función para crear un búfer geodésico en R cuando el ancho se da en unidades métricas? Soy consciente de gBuffer
de rgeos
paquete. Esta función crea un búfer en unidades del objeto espacial que se usa ( ejemplo ), por lo tanto, tengo que proyectar las coordenadas para poder crear un búfer de X km deseado. Proyectando y luego aplicando un gBuffer
medio en realidad haciendo un búfer euclidiano en lugar de uno geodésico que necesito. A continuación hay un código para ilustrar mis preocupaciones:
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")
La imagen a continuación muestra los buffers euclidianos distorsionados (radio de 1000 km) producidos con el código desde arriba.
Robert J. Hijmans en Introducción al paquete de "geosfera" , sección 4 Point at distance and bearing
da un ejemplo de cómo hacer "polígonos circulares con un radio fijo, pero en coordenadas de longitud / latitud", que creo que se puede llamar un "amortiguador geodésico". Seguí esta idea y escribí un código que con suerte hace lo correcto, pero me pregunto si ya hay alguna función R de búfer geodésico en algún paquete que permita el radio métrico como entrada:
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")
La siguiente imagen muestra los amortiguadores geodésicos (radio de 1000 km).
Editar 2019-02-12 : por conveniencia, incluí una versión de la función en el paquete de geobuffer . Siéntase libre de contribuir con solicitudes de extracción.
R
puedo hacer eso, es una gran sugerencia. Pero dado que para un modelo esférico de la Tierra esta es una proyección tan simple, es lo suficientemente simple como para escribir el código directamente.