Pour comprendre la mise en mémoire tampon géodésique , l'équipe de développement du géotraitement d'Esri fait la distinction entre la mise en mémoire tampon euclidienne et géodésique. Ils concluent avec "la mise en mémoire tampon euclidienne effectuée sur les classes d'entités projetées peut produire des tampons trompeurs et techniquement incorrects. Cependant, la mise en mémoire tampon géodésique produira toujours des résultats qui sont géographiquement précis car les tampons géodésiques ne sont pas affectés par les distorsions introduites par les systèmes de coordonnées projetées".
Je dois travailler avec un jeu de données global ponctuel et les coordonnées ne sont pas projetées ( +proj=longlat +ellps=WGS84 +datum=WGS84
). Existe-t-il une fonction pour créer un tampon géodésique dans R lorsque la largeur est donnée en unités métriques? Je suis au courant gBuffer
du rgeos
paquet. Cette fonction crée un tampon en unités de l'objet géographique utilisé ( exemple ), donc, je dois projeter les coordonnées pour pouvoir créer un tampon de X km souhaité. Projeter puis appliquer un gBuffer
moyen fait en fait un tampon euclidien par opposition à un tampon géodésique dont j'ai besoin. Voici un code pour illustrer mes préoccupations:
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")
L'image ci-dessous représente les tampons euclidiens déformés (rayon de 1000 km) produits avec le code ci-dessus.
Robert J. Hijmans dans Introduction au paquet «géosphère» , la section 4 Point at distance and bearing
donne un exemple de la façon de faire des «polygones circulaires avec un rayon fixe, mais en coordonnées de longitude / latitude», qui je pense peut être appelé un «tampon géodésique». J'ai suivi cette idée et j'ai écrit du code qui, espérons-le, fait la bonne chose, mais je me demande s'il y a déjà une fonction R de tampon géodésique dans un paquet qui permet un rayon métrique en entrée:
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")
L'image ci-dessous représente les tampons géodésiques (1000 km de rayon).
Edit 2019-02-12 : Pour plus de commodité, j'ai encapsulé une version de la fonction dans le package geobuffer . N'hésitez pas à contribuer avec des demandes de tirage.
R
c'est possible - c'est une excellente suggestion. Mais comme pour un modèle de Terre sphérique, il s'agit d'une projection si simple, il est assez simple d'écrire directement le code.Réponses:
Dans la plupart des cas, il sera suffisamment précis pour utiliser un modèle sphérique de la terre - et le codage sera plus facile et les calculs beaucoup plus rapides.
Suivant les suggestions de M. Kennedy dans un commentaire, cette solution tamponne le pôle Nord (ce qui est facile: la limite du tampon se trouve à une latitude fixe), puis fait pivoter ce tampon dans n'importe quel emplacement souhaité.
La rotation est effectuée en convertissant le tampon d'origine en coordonnées géocentriques cartésiennes (XYZ), en faisant tourner celles avec une multiplication matricielle (rapide) le long du méridien principal vers la latitude cible, en reconvertissant ses coordonnées en géographiques (lat-lon), puis en les faisant tourner le tampon autour de l'axe de la Terre simplement en ajoutant la longitude cible à chaque seconde coordonnée.
Pourquoi le faire en deux étapes alors que (normalement) une seule multiplication matricielle fonctionnerait? Parce qu'il n'y a pas besoin de code spécial pour identifier les ruptures au méridien de +/- 180 degrés. Au lieu de cela, cette approche peut générer des longitudes au-delà de la plage d'origine (que ce soit -180 à 180 degrés ou 0 à 360 ou autre), mais ce faisant, les procédures standard de dessin de polygones (et d'autres procédures analytiques) fonctionneront correctement sans modification. Si vous devez avoir des longitudes dans une plage donnée, réduisez-les simplement à 360 degrés modulo à la toute fin: c'est rapide et facile.
Lors de la mise en mémoire tampon des points, tous les tampons ont généralement le même rayon. Cette solution modulaire permet une accélération dans ce cas: vous pouvez tamponner le pôle Nord puis le convertir en coordonnées XYZ une fois pour toutes. La mise en mémoire tampon de chaque point nécessite ainsi une multiplication matricielle (très rapide), une reconversion en coordonnées lat-lon et un décalage des longitudes (également très rapide). Attendez-vous à générer environ 10 000 tampons haute résolution (360 sommets) par seconde.
Ce
R
code montre les détails. Puisque son but est l'illustration, il n'utilise aucun module complémentaire; rien n'est caché ou enterré. Il comprend un test dans lequel un ensemble de points aléatoires est généré, mis en mémoire tampon et affiché en utilisant ses coordonnées lat-lon (géographiques) brutes. Voici la sortie:la source