Я новичок в R и пытаюсь превратить SpatRaster большего размера в SpatVector. К сожалению, используя vec <- as.polygons(растр) Я получаю сообщение об ошибке: [as.polygons] растр слишком велик.
Поэтому я решил, что могу сделать плитки меньшего размера, а затем снова связать векторы вместе.
мой код пока выглядит так (обучающий растр намного меньше и его можно полигонизировать без создания тайлов)
f <- system.file("ex/logo.tif", package = "terra")
r <- rast(f)
r_tiles <- makeTiles(r, c(34,51), filename = "training/tile_.tif")
for(i in 1:length(r_tiles)) {
raster <- assign(paste0("tile_",i), rast(paste("training/tile_",i,".tif", sep = ""))) #kleine Raster wieder einlesen
polygon <- as.polygons(raster, aggregate = F)
writeVector(polygon, filename = paste("training/pol_",i,".gpkg", sep = ""))
assign(paste0("pol_",i), vect(paste("training/pol_",i,".gpkg", sep = "")))
}
Сейчас я хочу связать все меньшие векторы вместе, чтобы снова получить один больший SpatVector с теми же размерами, что и исходный растр.
Я знаю, что могу сделать
bigPol <- rbind(pol_1, pol_2, pol_3, pol_4, pol_5, pol_6)
Но есть ли более плавный способ, используя какой-то цикл? Я думал что-то вроде
for(j in 1: length(r_tiles)){bigPol <- rbind(paste0("pol_", i, sep = "")
Но, конечно, это не работает.
Спасибо! Это выглядит намного более гладко. Теперь я попробовал loopfunction_train <- function(i) paste0("pol_", i, sep = "") bigPol <- rbind(list(lapply(seq_len(r_tiles), loopfunction_train))) и получил ошибку. Ошибка в seq_len(r_tiles): аргумент должен быть приведён к неотрицательному целому числу. Кроме того: Предупреждающие сообщения: 1: В seq_len(r_tiles): первый элемент, используемый в аргументе length.out 2: В lapply(seq_len(r_tiles),loopfunction_train) : NA, введенные путем принуждения. Знаете ли вы, как это решить?
Извини. Попробуйте seq_len(length(r_tiles)). В противном случае узнайте, как получить длину r_tiles. Я никогда не работал с растрами, увы.
Это помогло получить правильную длину, но у меня все еще были проблемы с получением правильного формата, поэтому я мог использовать его в rbind().
Теперь я нашел способ обойти это, просто поместив все в первый цикл: for(i in 1:length(r_tiles)) { raster <- assign(paste0("tile_",i), rast(paste("training/tile_",i,".tif", sep = ""))) polygon <- as.polygons(raster, aggregate = F) writeVector(polygon, filename = paste("training/pol_",i,".gpkg", sep = "")) assign(paste0("pol_",i), vect(paste("training/pol_",i,".gpkg", sep = ""))) if (i==1) big_poly = polygon if (i>1) big_poly = rbind(big_poly, polygon) }
Это может сработать, но это очень неэффективно. Проблема будет с big_poly = rbind(big_poly, polygon), особенно если часть big имени объекта точна. Вам действительно, действительно следует переместить привязку за пределы цикла. См., например, главу 3 The R Inferno.





Следуя рекомендациям, вы можете применить функцию r-ish для выполнения этой работы:
library(terra)
f <- system.file("ex/logo.tif", package = "terra")
r <- rast(f)
r_tiles <- makeTiles(r, c(34,51), filename = "training/tile_.tif")
path = 'training'
list.files(path, pattern = '.tif$', full.names = T)
polygonize = function(fname, out_path){
r = rast(fname)
polygon = as.polygons(r, aggregate = F)
filename = gsub('.tif','.shp',basename(fname))
writeVector(polygon, filename = file.path(out_path, filename))
}
sapply(r_tiles, polygonize, out_path = path)
Затем достаточно просто загрузить файлы в список и снова использовать vect:
vects = list.files(path, pattern = '.shp$', full.names = T)
vs = lapply(vects, function(x){vect(x)})
v = vect(vs)
plot(v)
Добро пожаловать в ТАК! Цикл
forиassignмогут работать, но, как вы говорите, это неуклюже. Более рациональный способ сделать что-то — преобразовать тело цикла в функцию и использоватьlapply. Затем вы можете выполнить привязку одновременно. Например, что-то вродеbigPol <- rbindlist(lapply(seq_len(r_tiles), myLoopFunction)). На этом сайте и в других местах есть множество примеров преобразования цикловforв вызовыlapply.