Как устранить сбои сферической геометрии при объединении пространственных данных

#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:

У вас есть два варианта:

  1. отключите обработку s2 через sf::sf_use_s2(FALSE) в вашем скрипте; теоретически поведение должно вернуться к тому, которое было до выпуска 1.0
  2. исправьте сферическую геометрию вашего объекта 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()