terra::extract exact=TRUE ошибка TopologyException

Вопрос или проблема

Я сравнивал функциональные возможности terra::extract и exactextractr::exact_extract. Я заметил, что для terra::extract параметр exact = TRUE иногда не работает, но weight=TRUE работает.

  1. Когда лучше использовать exact vs weight?
  2. Есть ли ошибка в extract с аргументом exact=TRUE?
  3. Можно ли получить долю перекрытия пикселей из полигона, как в exact_extract(rast, poly), но для terra::extract?
library(sf)
library(terra)
library(exactextractr)

rt=list(test1= matrix(1:100, ncol=10), 
     test2= matrix(201:300, ncol=10))

rast1 <- terra::rast((rt$test1))
rast2 <- terra::rast((rt$test1+2))

rast = c(rast1, rast2)

val1 = 0
val2 = 1.50
vac1= c(val1, val1, val2, val1, val2, val2, val1, val2, val1, val1)
vm1 = matrix(vac1, ncol = 2, byrow = TRUE)
pol1 = st_polygon(list(vm1))
pol2 = st_polygon(list(vm1+2))
pol3= st_polygon(list(vm1+4, vm1+6))
poly = st_sfc(pol1, pol2, pol3) %>% st_as_sf()

names(rast) <- c('t1', 't2')
rast_m=mask(rast, poly)

pt.pix = xyFromCell(rast, 1:100)


plot(rast_m[[1]]);plot(poly, add = TRUE)
plot(st_multipoint(pt.pix), add= TRUE, pch = ".", cex = 5)
text(st_multipoint(pt.pix+.15), labels = values(rast[[1]]))

values(rast_m[[1]]) %>% mean(., na.rm = T)

terra::extract(x = rast, y = poly, 'sum', exact = FALSE)


terra::extract(x = rast, y = poly, 'sum', exact = TRUE)

Выдает

Ошибка: TopologyException: Входная геометрия 1 недействительна: Дыра находится вне оболочки на 6 6

Но с weight это работает…

terra::extract(x = rast, y = poly, 'mean', weight = TRUE)
# (10+10+4.5+19/4)/(1.5^2)
exact_extract(rast, poly, 'mean')
e = exact_extract(rast, poly)

вставьте описание изображения здесь

Ответ или решение

Ошибка TopologyException в terra::extract exact=TRUE: Подробный анализ

Введение в проблему

Работа с пространственными данными в R требует внимательного подхода к выбору методов и функций, особенно когда речь идет о пакетах, таких как terra и exactextractr. При использовании функции terra::extract с параметром exact=TRUE вы столкнулись с ошибкой TopologyException: Input geom 1 is invalid: Hole lies outside shell. Это явление связано с особенностями обработки геометрии в R и потребует более глубокого понимания как самой функции, так и используемых данных.

Когда использовать exact против weight

  1. Использование exact=TRUE:
    Этот параметр предназначен для точного извлечения значений растровых данных по полигонам. Он полезен в ситуациях, когда нужно получить значения, точно соответствующие границам полигонов, особенно когда у вас есть сложные геометрические структуры или когда критично важно учитывать границы в анализе данных. Однако этот метод может не работать корректно при наличии ошибок в геометриках (например, самопересеченных полигонов), что ведет к ошибкам TopologyException.

  2. Использование weight=TRUE:
    Этот параметр, напротив, применяет весовое значение при экстракции, что позволяет учитывать частичное перекрытие пикселей с полигонами. Это особенно полезно, когда полигоны имеют сложные формы и могут охватывать только часть пикселей. В данном случае weight=TRUE может корректно работать даже при наличии топологических ошибок в полигонах, так как он учитывает долю перекрытия.

Возможные ошибки в extract с exact=TRUE

Проблема, с которой вы столкнулись, может указывать на наличие ошибок в вашей геометрии. Функция terra::extract требует, чтобы входные геометрии были корректными, что означает отсутствие самопересечений и отверстий, находящихся вне оболочки полигона.

Для исправления ситуации рекомендуется:

  • Проверить и исправить полигоны с помощью функции st_make_valid() из пакета sf, которая автоматически исправит геометрию.
  • Использовать функции для анализа и корректировки планарной формы полигона перед выполнением экстракции.

Экстракция пропорции пикселей перекрытия с помощью terra::extract

В вопросе задано, возможно ли получить пропорцию перекрытия пикселей с полигоном, как в exact_extract. Прямо в terra::extract такой функциональности нет. Однако можно рассмотреть следующий подход:

  1. Используйте terra::extract с weight=TRUE для получения взвешенных значений.
  2. Посчитайте общую площадь полигона и общую площадь покрытия пикселями, чтобы вычислить пропорцию.

Вот пример кода, который может помочь в решении задачи:

library(terra)
library(sf)

# Допустим, poly - ваш полигон, а rast - ваш растровый объект
# Получаем значения с учетом веса
weighted_values <- terra::extract(rast, poly, weight=TRUE)

# Вычисляем общую площадь полигонов
polygon_area <- st_area(poly)

# Получаем сумму весов
total_weight <- sum(weighted_values$weight, na.rm=TRUE)

# Вычисляем пропорцию перекрытия
proportion_overlap <- total_weight / polygon_area

Заключение

В итоге, ошибки, возникающие при использовании exact=TRUE, часто связаны с неправильной геометрией, что требует предварительной проверки. Параметр weight=TRUE предоставляет большую гибкость и позволяет избежать ошибок в сложных случаях. Важно также помнить о том, что terra::extract не предлагает прямого способа получения пропорции перекрытия, однако это можно обойти с помощью дополнительных расчетов.

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

Оцените материал
Добавить комментарий

Капча загружается...