#r #transform #geospatial #sf
#r #преобразовать #геопространственный #sf
Вопрос:
Есть ли простой способ преобразовать ограничение простого объекта ( sf
object) в другой CRS?
Результат функции st_bbox()
относится к классу bbox
. Невозможно использовать st_transform()
для преобразования его в другой CRS.
Я использую вычисляемую ограничивающую рамку на основе EPSG: 28992
:
sf::st_bbox(xmin = 187470, xmax =194587,
ymin = 409753, ymax = 412715,
crs = st_crs(28992))
Теперь я хочу преобразовать это поле в EPSG:4326
Комментарии:
1. Обратите внимание, что прямоугольник в одной системе координат может не быть прямоугольником в другой. Если вы действительно хотите спроецировать полную форму прямоугольника, а не только четыре угла, тогда вам нужно создать прямоугольный многоугольник с большим количеством вершин по сторонам и спроецировать это .
Ответ №1:
Существует st_as_sfc
метод для bbox
объектов, поэтому мы можем преобразовать bbox
вот так:
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
Ответ №2:
Один из способов сделать это — создать промежуточное значение sfc_MULTIPOINT
, преобразовать его в 4326, затем извлечь ограничивающую рамку из этого объекта:
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
Ответ №3:
Как отметил @spacedman, прямоугольник в одной системе координат может не быть прямоугольником в другой. Некоторые системы координат намного более изогнуты, чем другие!
Чтобы более безопасно преобразовать ограничивающую рамку, вы могли бы добавить вершины, используя st_make_grid (n = что угодно).
# 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()
Это не на 100% безопасно, но лучше, чем просто преобразовать прямоугольный многоугольник (который преобразует только угловые вершины, ничего между ними). Слишком много вершин сетки работает очень медленно. Я нахожу, что ~ 10-20 хорошо работают в большинстве случаев.
Пример (с использованием систем отсчета координат, отличных от OP, для иллюстрации):
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)