2016-09-22 11 views
0

У меня есть два тематических растровых слоя r1 и r2 для той же самой области, каждая из которых соответствует одной и той же схеме классификации и имеет 16 классов. Мне нужно найти минимальное расстояние между ячейкой r1 и ячейкой r2, но с тем же значением. Например. n-я ячейка в r1 имеет значение 10 и координаты x1,y1. А в r2 есть 2 ячейки со значением 10 и координаты x1+2,y1+2 и x1-0.5,y1-0.5. Таким образом, значение, которое мне нужно для этой ячейки, будет 0,5,0,5.Поиск минимального расстояния между двумя пикселями растрового слоя в R

Я пробовал distance от raster package, но он дает расстояние для всех ячеек, которые являются NA, до ближайшей ячейки, которая не является NA. Я смущен тем, как включить в него второй растровый слой.

ответ

0

Итак, используйте rasterToPoints для извлечения объекта SpatialPoints для уникального тематического класса. Затем используйте функцию sp :: spDists, чтобы найти расстояние между вашими точками.

library(raster) 


r1 <- raster(nrow=10,ncol=10) 
r2 <- raster(nrow=10,ncol=10) 

set.seed(1) 
r1[] <- ceiling(runif(100,0,10)) 
r2[] <- ceiling(runif(100,0,10)) 

dist.class <- NULL 
for(i in unique(values(r1))){ 
p1 <- rasterToPoints(r1, fun=function(xx) xx==i, spatial=T) 
p2 <- rasterToPoints(r2, fun=function(xx) xx==i, spatial=T) 
dist.class[i] <- min(spDists(p1,p2)) 
} 
cbind(class = unique(values(r1)),dist.class) 

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

0

Вы можете использовать knn из class упаковки, так что для каждой ячейки r1 индекса находки ближайшей ячейки r2 с одной и той же категорией:

library(class) 
library(raster) 
#example of two rasters 
r1 <- raster(ncol = 600, nrow = 300) 
r2 <- raster(ncol = 600, nrow = 300) 
#fill each with categories that rabge from 1 to 16 
r1[] <- sample(1:16, ncell(r1), T) 
r2[] <- sample(1:16, ncell(r2), T) 
# coordinates of cells extracted 
xy = xyFromCell(r1, 1:ncell(r1)) 
#multiply values of raster with a relatively large number so cells thet belong 
#to each category have smaller distance with reagrd to other categories. 
v1 = values(r1) * 1000000 
v2 = values(r2) * 1000000 
# the function returns indices of nearest cells 
out = knn(cbind(v2, xy) ,cbind(v1, xy) ,1:ncell(r1), k=1) 
0

Памяти безопасного подход с использованием растрового-пакета будет использовать функцию layerize(), чтобы разделить ваше растровое значение в стек двоичных растров (16 в вашем случае), а затем использовать функцию distance() для вычисления расстояний в слоях r2, маскируя их соответствующими уровнями r1. Что-то вроде этого:

layers1 <- layerize(r1, falseNA=TRUE) 
layers2 <- layerize(r2, falseNA=TRUE) 

# now you can loop over the layers (use foreach loop if you want 
# to speed things up using parallel processing) 

dist.stack <- layers1 

for (i in 1:nlayers(r1)) { 
    dist.i <- distance(layers2[[i]]) 
    dist.mask.i <- mask(dist, layers1[[i]]) 
    dist.stack[[i]] <- dist.mask.i 
} 

# if you want pairwise distances for all classes in one layer, simply 
# combine them using sum() 

dist.combine <- sum(dist.stack, na.rm=TRUE)