Вопрос или проблема
Я сравнивал функциональные возможности terra::extract и exactextractr::exact_extract. Я заметил, что для terra::extract параметр exact = TRUE
иногда не работает, но weight=TRUE
работает.
- Когда лучше использовать
exact
vsweight
? - Есть ли ошибка в
extract
с аргументомexact=TRUE
? - Можно ли получить долю перекрытия пикселей из полигона, как в
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
-
Использование
exact=TRUE
:
Этот параметр предназначен для точного извлечения значений растровых данных по полигонам. Он полезен в ситуациях, когда нужно получить значения, точно соответствующие границам полигонов, особенно когда у вас есть сложные геометрические структуры или когда критично важно учитывать границы в анализе данных. Однако этот метод может не работать корректно при наличии ошибок в геометриках (например, самопересеченных полигонов), что ведет к ошибкам TopologyException. -
Использование
weight=TRUE
:
Этот параметр, напротив, применяет весовое значение при экстракции, что позволяет учитывать частичное перекрытие пикселей с полигонами. Это особенно полезно, когда полигоны имеют сложные формы и могут охватывать только часть пикселей. В данном случаеweight=TRUE
может корректно работать даже при наличии топологических ошибок в полигонах, так как он учитывает долю перекрытия.
Возможные ошибки в extract
с exact=TRUE
Проблема, с которой вы столкнулись, может указывать на наличие ошибок в вашей геометрии. Функция terra::extract
требует, чтобы входные геометрии были корректными, что означает отсутствие самопересечений и отверстий, находящихся вне оболочки полигона.
Для исправления ситуации рекомендуется:
- Проверить и исправить полигоны с помощью функции
st_make_valid()
из пакетаsf
, которая автоматически исправит геометрию. - Использовать функции для анализа и корректировки планарной формы полигона перед выполнением экстракции.
Экстракция пропорции пикселей перекрытия с помощью terra::extract
В вопросе задано, возможно ли получить пропорцию перекрытия пикселей с полигоном, как в exact_extract
. Прямо в terra::extract
такой функциональности нет. Однако можно рассмотреть следующий подход:
- Используйте
terra::extract
сweight=TRUE
для получения взвешенных значений. - Посчитайте общую площадь полигона и общую площадь покрытия пикселями, чтобы вычислить пропорцию.
Вот пример кода, который может помочь в решении задачи:
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
не предлагает прямого способа получения пропорции перекрытия, однако это можно обойти с помощью дополнительных расчетов.
Расширяя данный анализ, вы сможете точнее использовать библиотеки Р для работы с пространственными данными, эффективно извлекая нужную информацию и избегая возможных ошибок, связанных с геометрией.