Um das geodätische Puffern zu verstehen , unterscheidet das Esri Geoprocessing Development Team zwischen euklidischem und geodätischem Puffern. Sie schließen mit "Euklidische Pufferung, die an projizierten Feature-Classes durchgeführt wird, kann zu irreführenden und technisch inkorrekten Puffern führen. Geodätische Pufferung führt jedoch immer zu geografisch genauen Ergebnissen, da geodätische Puffer nicht durch die durch projizierte Koordinatensysteme verursachten Verzerrungen beeinflusst werden."
Ich muss mit einem globalen Punktdatensatz arbeiten und die Koordinaten sind nicht projiziert ( +proj=longlat +ellps=WGS84 +datum=WGS84
). Gibt es eine Funktion zum Erstellen eines geodätischen Puffers in R, wenn die Breite in metrischen Einheiten angegeben wird? Mir ist gBuffer
aus dem rgeos
Paket bekannt. Diese Funktion erstellt einen Puffer in Einheiten des verwendeten räumlichen Objekts ( Beispiel ). Daher muss ich die Koordinaten projizieren, um einen Puffer mit den gewünschten X km erstellen zu können. Projizieren und dann ein gBuffer
Mittel anwenden , um tatsächlich einen euklidischen Puffer zu erstellen, im Gegensatz zu einem geodätischen, den ich brauche. Unten finden Sie einen Code, der meine Bedenken veranschaulicht:
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")
Das Bild unten zeigt die verzerrten euklidischen Puffer (Radius 1000 km), die mit dem Code von oben erzeugt wurden.
Robert J. Hijmans in Abschnitt Einführung in das Paket "Geosphäre"4 Point at distance and bearing
gibt ein Beispiel für die Herstellung von "kreisförmigen Polygonen mit festem Radius, jedoch in Längen- / Breitengradkoordinaten", die meines Erachtens als "geodätischer Puffer" bezeichnet werden können. Ich bin dieser Idee gefolgt und habe Code geschrieben, der hoffentlich das Richtige tut, aber ich frage mich, ob es in einem Paket bereits eine geodätische Puffer-R-Funktion gibt, die den metrischen Radius als Eingabe zulässt:
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")
Das Bild unten zeigt die geodätischen Puffer (Radius 1000 km).
Edit 2019-02-12 : Der Einfachheit halber habe ich eine Version der Funktion in das Geobuffer- Paket eingeschlossen. Fühlen Sie sich frei, mit Pull-Anfragen beizutragen.
R
kann das - es ist ein großartiger Vorschlag. Da dies für ein sphärisches Erdmodell eine so einfache Projektion ist, ist es einfach genug, den Code direkt zu schreiben.