#r #sf
Вопрос:
У меня есть шейп-файл (с несколькими полигонами) и фрейм данных с координатами. Я хочу присвоить каждую координату в фрейме данных полигону в шейп-файле. Итак, чтобы добавить столбец во фрейм данных с именем или идентификатором полигона, вот ссылка на данные
library(sf)
library(readr)
shape <- read_sf("data/mesopelagic_regions/GlasgowMesopelagicProvinces_v1_2017.shp")
data<- read_csv("data/data.csv")
Но когда я пытаюсь их объединить, я всегда получаю сообщение об ошибке
pts = st_as_sf(data, coords = c("dec_lon", "dec_lat"), crs= 4326)
st_join(pts, shape)
я пробовал over()
функции и другие трюки, например st_make_valid()
, но я всегда получаю эту ошибку:
Error in s2_geography_from_wkb(x, oriented = oriented, check = check) : Evaluation error: Found 30 features with invalid spherical geometry.
Это недавняя проблема (до того, как мой код работал), но теперь я не могу использовать пакет sf для выполнения этой задачи, я всегда получаю эту ошибку. Я обновил библиотеки, чтобы посмотреть, поможет ли это, но я не смог заставить это работать.
Я был бы очень признателен за вашу помощь в этом вопросе
Ответ №1:
У вас есть два варианта:
- отключите обработку s2 через
sf::sf_use_s2(FALSE)
в вашем скрипте; теоретически поведение должно вернуться к тому, которое было до выпуска 1.0 - исправьте сферическую геометрию вашего объекта polygons; это будет зависеть от фактического характера ваших ошибок.
Я не могу получить доступ к вашему файлу и убедиться, но этот фрагмент кода помог мне в прошлом:
yer_object$geometry <- yer_object$geometry %>%
s2::s2_rebuild() %>%
sf::st_as_sfc()
Комментарии:
1. вы правы! Я попробовал
sf::sf_use_s2(FALSE)
, и теперь это работает!2. Супер, рад быть полезным! 🙂
3. Я тоже наткнулся на эту ошибку, и это сводило меня с ума, потому что операция выполняется гладко в python с использованием тех же входных данных. @jiladata Не могли бы вы быть так любезны, чтобы объяснить, что изменилось в версии 1.0, что вызвало неожиданное поведение? Спасибо
4. Привет, @IvanP! Изменение в sf v1.0 заключалось в переходе с серверного движка для непроецируемых координат (географических, т.Е. широтных, как в EPSG 4326) с GEOS на s2 от Google. GEOS рассматривает проекционные координаты как плоские (т.Е. Две точки лежат на линии бесконечной максимальной длины), в то время как s2 является более «правильным» (две точки лежат на большом круге окружности 40 075 километров). Изменение серверной части по умолчанию имело последствия, поскольку и GEOS, и s2 используют ярлыки и принимают (разные) предположения. Взгляните на r-spatial.github.io/sf/articles/sf7.html для получения дополнительной информации
5. Спасибо за четкое объяснение! Я быстро просмотрел документацию sf v1.0 и оказался на той же странице, на которую вы ссылались.
Ответ №2:
Я обнаружил, что эта «недопустимая сферическая геометрия» продолжает появляться. Если вышеприведенное s2::s2_rebuild()
решение не работает, решение, которое обычно работает для меня, включает в себя проектирование и упрощение (небольшое уменьшение разрешения карты). Если ваше приложение может работать с меньшим разрешением, попробуйте это.
library(tidyverse)
library(sf)
crs_N = 3995 #northern polar projection
# example of FAILING map - with bad spherical geometry.
m_RU <- rnaturalearthdata::countries50 %>%
st_as_sf() %>%
filter((admin %in% c("Russia") )) |>
st_as_s2()
В примере я выбрал Россию, потому что она пересекает линию данных, что может быть одной из проблем. Я переключаюсь на полярную проекцию Арктики и уменьшаю разрешение карты до 10 км (в данном случае 5 км недостаточно!).
# with 2 extra lines the problem is gone
m_RU <- rnaturalearthdata::countries50 %>%
st_as_sf() %>%
filter((admin %in% c("Russia") )) |>
st_transform(crs = crs_N) |>
st_simplify(dTolerance = 10000) |> # to get rid of duplicate vertex (reduce to 10km steps)
st_as_s2()