Получить расстояния между границами из SpatialPolygon и растровых пикселей

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

  1. Как правильно определить границу объекта SpatialPolygon. В настоящее время у меня есть два варианта, но я не могу решить, какой из них лучше. Во-первых, я могу принудить объект SpatialPolygon as к объекту SpatialLines, а затем к SpatialPoints. Во-вторых, я могу raster::rasterize SpatialPolygon. Думаю, у каждого варианта есть свои плюсы и минусы.

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

Следующий код можно использовать для получения примера SpatialPolygonsDataFrame:

#Get the world map and select two countries [Colombia and Venezuela]
library(maptools) #To get the polygon data 
data(wrld_simpl)
colven <- c("Colombia", "Venezuela")
colven_map <- wrld_simpl[wrld_simpl$NAME %in% colven, ]

Растровые данные можно создать с помощью этого кода:

library(raster)
raster <- raster(colven_map, nrow=100, ncol=100)
raster[] <- 1:length(raster)
raster_colven <- mask(raster, colven_map)

Пример

заранее спасибо


person topcat    schedule 20.01.2016    source источник
comment
Ваше изображение не отображается.   -  person Roman Luštrik    schedule 20.01.2016
comment
Пожалуйста, задайте хороший вопрос R: создайте автономный воспроизводимый пример и покажите код.   -  person Robert Hijmans    schedule 21.01.2016
comment
Я изменил вопрос и добавил несколько фрагментов кода для получения данных SpatialPolygon и растра. Спасибо за рекомендацию Роберт.   -  person topcat    schedule 21.01.2016


Ответы (1)


#example data
library(maptools) #To get the polygon data 
data(wrld_simpl)
colven <- wrld_simpl[wrld_simpl$NAME %in% c("Colombia", "Venezuela"), ]

library(raster)
raster <- raster(colven, nrow=100, ncol=100)
raster[] <- 1:length(raster)
raster <- mask(raster, colven)

Я создаю несколько случайных интересующих ячеек

set.seed(33)
cells <- sample(ncell(raster), 10)
xy <- xyFromCell(raster, cells)
sp <- SpatialPoints(xy, proj4string=crs(colven))

А затем используйте rgeos

library(rgeos)
# inside Colombia only
col <- colven[colven$NAME == "Colombia", ]
sp <- gIntersection(sp, col)

# get the border between Venezuela and Colombia
ven <- colven[colven$NAME == "Venezuela", ]
border <- gIntersection(col, ven)

# get the distance
# this fails for me, that seems to be a bug in rgeos for these data
gDistance(sp, border, byid=TRUE)  

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

library(geosphere)
dist2Line(xy, border)

Если вам нужно расстояние от всей ячейки сетки Колумбии до границы, вы также можете сделать:

rborder <- rasterize(border,  raster)
dborder <- distance(rborder)
dbcol <- mask(dborder, col)

См. функции в пакете gdistance, если вам нужно расстояние от места в Колумбии до границы с Венесуэлой, путешествуя только по Колумбии.

person Robert Hijmans    schedule 21.01.2016
comment
d <- gDistance(polygon, p) будет вычислять расстояние от каждого пикселя (теперь точки) до границы или до центра полигона? Ну, я хочу, чтобы расстояние было до красной границы, а не до синей. Пиксели внутри полигона или расстояние между пикселями вне полигона и синей рамкой меня не интересуют. - person topcat; 21.01.2016
comment
Роберт, я добавил гораздо больше деталей и воспроизводимый код без необходимости скачивать что-либо. Я сделал это исходя из того, что этот пост может помочь другим с похожими проблемами и сделать мои вопросы более понятными. Спасибо за ваши рекомендации. - person topcat; 21.01.2016
comment
Спасибо, это идея. - person Robert Hijmans; 22.01.2016
comment
reos::gIntersect дает мне несколько ошибок из-за сложности (я думаю) пересечения между полигонами. Можно ли замаскировать растр с одной из сторон: col_raster <- mask(raster, col) и посчитать расстояние до границы с ven? Я думал также о выпуклом корпусе, чтобы упростить многоугольники, но это не очень хорошее решение. - person topcat; 23.01.2016