Existe-t-il un moyen simple de transformer la délimitation d'une entité simple (objet sf ) en un autre CRS?
Le résultat de la fonction st_bbox () est de la classe bbox . Il n'est pas possible d'utiliser st_transform () pour le transformer en un autre CRS.
J'utilise une boîte englobante calculée basée sur EPSG: 28992 :
sf::st_bbox(xmin = 187470, xmax =194587,
ymin = 409753, ymax = 412715,
crs = st_crs(28992))
Maintenant, je veux transformer cette boîte en EPSG: 4326
3 Réponses :
Une façon de le faire est de créer un sfc_MULTIPOINT intermédiaire, de le transformer en 4326, puis d'extraire le cadre englobant de cet objet:
pts <- st_multipoint(rbind(c(187470, 409753), c(194587, 412715))) %>% st_sfc(crs = st_crs(28992))
pts <- pts %>% st_transform(crs = 4326)
st_bbox(pts)
xmin ymin xmax ymax
5.856639 51.675634 5.959866 51.701799
Il existe une méthode st_as_sfc pour les objets bbox , nous pouvons donc transformer une bbox comme ceci:
library(sf)
bb = sf::st_bbox(c(xmin = 187470, xmax =194587,
ymin = 409753, ymax = 412715),
crs = st_crs(28992))
bb_ll = st_bbox(
st_transform(
st_as_sfc(bb),
4326
)
)
# or pipey
library(magrittr)
bb_ll = bb %>%
st_as_sfc() %>%
st_transform(crs = 4326) %>%
st_bbox()
bb_ll
xmin ymin xmax ymax
5.856639 51.675176 5.959866 51.702257
Comme l'a noté @spacedman, un rectangle dans un système de coordonnées peut ne pas être un rectangle dans un autre. Certains systèmes de coordonnées sont beaucoup plus courbes que d'autres!
Pour transformer une boîte englobante de manière plus sûre, vous pouvez ajouter des sommets en utilisant st_make_grid (n = peu importe).
library(sf)
library(dplyr)
bb_orig = st_bbox(c(xmin = 40, xmax =-40,
ymin = 45, ymax = 55),
crs = st_crs(4326)) #lag/long
new_crs = 3995 # arctic polar stereographic
bb_simple_reproj = bb_orig %>%
st_as_sfc() %>%
st_transform(crs=new_crs) %>%
st_bbox
bb_better_reproj = bb_orig %>%
st_make_grid(n=10) %>%
st_transform(crs = new_crs) %>%
st_bbox()
# 100 random points inside the original bounding box (grey)
sample_from_bb_orig = st_sample(st_as_sfc(bb_orig), 1000) %>%
st_transform(new_crs)
plot(st_geometry(sample_from_bb_orig), col="grey")
# if the bbox was only transformed as simple rectangle we would get (red):
# red points indicate those missed by the simple bbox reprojection -- note that many are missed!
plot(st_geometry(st_as_sfc(bb_simple_reproj)), border="red", add=TRUE)
plot(st_difference(sample_from_bb_orig, st_as_sfc(bb_simple_reproj)) , col="red", add=TRUE)
# using 'better' repojection, with more vertices added (blue)
# blue points indicate those missed by the simple bbox reprojection
plot(st_geometry(st_as_sfc(bb_better_reproj)), border="blue", add=TRUE)
plot(st_difference(sample_from_bb_orig, st_as_sfc(bb_better_reproj)) , col="blue", pch="x", add=TRUE)
Ce n'est pas sûr à 100%, mais mieux que de simplement transformer le polygone rectangulaire (qui ne transforme que les sommets d'angle, rien entre les deux). Trop de sommets de grille est vraiment lent. Je trouve que ~ 10-20 fonctionne bien dans la plupart des cas.
Un exemple (utilisant différents systèmes de référence de coordonnées (CRS) que l'OP pour illustrer):
# pipey code to show the steps clearly
library(sf)
library(dplyr)
bb_better_reproj = bb_orig %>%
st_make_grid(n=10) %>% #this also makes it into a polygon
st_transform(crs = 4326) %>%
st_bbox()
Notez qu'un rectangle dans un système de coordonnées peut ne pas être un rectangle dans un autre. Si vous voulez vraiment projeter la forme complète de la boîte plutôt que les quatre coins, vous devez créer un polygone rectangulaire avec plus de sommets le long des côtés et projeter cela .