3
votes

Transformez le résultat de `st_bbox ()` en un autre CRS

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


1 commentaires

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 .


3 Réponses :


1
votes

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 


0 commentaires

1
votes

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


0 commentaires

0
votes

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()


0 commentaires