Как рассчитать географические центроиды по группам?

Мне нужно рассчитать географический центр тяжести различных полигонов, сгруппированных по категориям. Позвольте мне привести пример. Допустим, у нас есть этот набор данных нф.

library("sf")
nc <- st_read(system.file("/shape/nc.shp", package="sf"))

Допустим, мы группируем разные полигоны по категориям.

df <- data.frame(id=rep(1:10,rep=10))
nc <- cbind(nc,df)

Если мы построим его, то увидим, что разные полигоны относятся к разным категориям. Самое главное, что эти полигоны не всегда являются смежными.

plot(nc["id"])

Я хотел бы рассчитать географический центроид для каждой категории. Один из вариантов, который я рассматриваю, заключался в том, чтобы сначала растворить разные полигоны, а затем вычислить центроид. Однако, поскольку полигоны не являются смежными, это не работает.

p <- nc %>% group_by(id) %>%
  summarise(geometry = st_union(geometry)) %>%
  ungroup()

Кроме того, если я попробую код ниже, он даст мне центроид каждого многоугольника, а не по группе

p <- nc %>% group_by(id) %>%
    summarise(geometry = st_centroid(geometry),.groups = "keep")

Любая идея о том, как получить центр тяжести по группе?

Если вы создадите точки со средней широтой для группы и средней долготой для группы, поможет ли это? Я не могу понять, как мы можем вычислить центроиды несмежных полигонов. Могу я спросить, зачем вам нужны эти указанные центроиды?

Lucca Nielsen 17.05.2022 15:47
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
1
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, это работает, если вы group_by, st_union в резюме, а затем находите центроид.

library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1; sf_use_s2() is TRUE
library(tidyverse)

nc <- st_read(system.file("/shape/nc.shp", package="sf"))
#> Reading layer `nc' from data source 
#>   `/home/x/R/x86_64-pc-linux-gnu-library/4.0/sf/shape/nc.shp' 
#>   using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS:  NAD27

df <- data.frame(id=rep(1:10,rep=10))
nc <- cbind(nc,df)


# new sf data.frame, get centroids by group
nc_grouped <- nc %>%
                group_by(id) %>%
                summarise(st_union(geometry)) %>%
                st_centroid() 
#> Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
#> geometries of x

# plot everything
ggplot() + 
  geom_sf(data = nc, aes(fill = id, alpha = .2)) +
  geom_sf(data = nc_grouped, aes(color = id), size = 3) + 
  scale_fill_viridis_c() +
  scale_color_viridis_c()

Плохо видно, но они все есть.

# plotting only id ==1, looks about right.
ggplot() + 
  geom_sf(data = nc[nc$id == 1,]) + 
  geom_sf(data = nc_grouped[nc_grouped$id == 1,])

Проверка только 1-й группы выглядит примерно так.



nc %>% group_by(id) %>%
  summarise(geometry = st_centroid(geometry),.groups = "keep")
#> Simple feature collection with 100 features and 1 field
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -84.05986 ymin: 34.07671 xmax: -75.8095 ymax: 36.49111
#> Geodetic CRS:  NAD27
#> # A tibble: 100 × 2
#> # Groups:   id [10]
#>       id             geometry
#>    <int>          <POINT [°]>
#>  1     1  (-81.49823 36.4314)
#>  2     1 (-79.33478 36.39346)
#>  3     1 (-76.61642 36.14886)
#>  4     1 (-77.98691 35.96228)
#>  5     1 (-81.17403 35.91575)
#>  6     1 (-77.37784 35.58906)
#>  7     1 (-81.91783 35.39871)
#>  8     1 (-80.24928 35.31388)
#>  9     1 (-84.05986 35.13111)
#> 10     1 (-77.10388 35.13065)
#> # … with 90 more rows

Created on 2022-05-17 by the reprex package (v2.0.1)

Другие вопросы по теме