Буфер растров в R с переменной шириной на основе значения ячейки - PullRequest
0 голосов
/ 25 апреля 2020

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

library(raster)

stream <- raster(xmn = 385000,
            xmx = 385010,
            ymn = 7085000,
            ymx = 7085014,
            resolution = c(1,1),
            vals = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
                     NA, 1, 2,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA, 3,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA, 4, 5,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA, 8,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA, 9,10,12,NA,NA,NA,NA,
                     NA,NA,NA,NA,NA,13,15,NA,NA,NA,
                     NA,NA,NA,NA,NA,NA,18,20,21,NA,
                     NA,NA,NA,NA,NA,NA,NA,NA,28,30,
                     NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
                     NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
            crs = 26905)

plot(stream)

enter image description here

Я хотел бы буферизовать поток таким образом, чтобы ширина буфера увеличивалась при перемещении вниз по течению ( т.е. по мере накопления потока увеличивается). buffer() на это не способен.

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

# create a raster brick with the subset data
stream_brick <- brick(reclassify(stream, rcl = matrix(c(0, 10, 1, 10, 31, NA), nrow = 2, byrow = TRUE)),
                      reclassify(stream, rcl = matrix(c(0, 10, NA, 10, 20, 1, 20, 31, NA), nrow = 3, byrow = TRUE)),
                      reclassify(stream, rcl = matrix(c(0, 10, NA, 10, 31, 1), nrow = 2, byrow = TRUE)))

# create a new raster brick with the right attributes to put output of buffer in
stream_buffer_brick <- stream_brick

# buffer each layer in the of the stream brick to a different value
for (i in 1:nlayers(stream_brick)) {
  stream_buffer_brick[[i]] <- buffer(stream_brick[[i]], width = i)
}

# add the results together to get the desired output
stream_buffer <- calc(stream_buffer_brick, max, na.rm = TRUE)

plot(stream_buffer)

enter image description here

Однако я не особо рад этому методу по нескольким причинам.

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

  2. Невозможно плавно увеличивать ширину буфера при увеличении накопления потока. В этом небольшом примере это не проблема. Однако в случае, когда у вас есть большая ширина буфера (например, порядка км) в растре с относительно хорошим разрешением (например, порядка m), это становится проблематичным c. Чтобы получить (более или менее) плавно увеличивающуюся ширину буфера, вам нужно разделить данные на астрономическое количество кусков.

Если у кого-то есть мысли по поводу более чистого, более эффективного способ получения переменного буфера на основе значений входных ячеек (независимо от того, разделяет ли он данные на куски, как я это сделал или позволяет плавно увеличивать ширину буфера), пожалуйста, поделитесь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...