2013-04-08 13 views
8

Próbowałem znaleźć efektywny czasowo sposób scalania wielu obrazów rastrowych w R. Są to sąsiadujące sceny ASTER z południowego regionu Kilimandżaro, a moim celem jest złożyć je razem, aby uzyskać jeden duży obraz.Łączenie wielu rastrów w R

To, co mam tak daleko (object 'ast14dmo reprezentujące listę obiektów RasterLayer):

# Loop through single ASTER scenes 
for (i in seq(ast14dmo.sd)) { 
    if (i == 1) { 
    # Merge current with subsequent scene 
    ast14dmo.sd.mrg <- merge(ast14dmo.sd[[i]], ast14dmo.sd[[i+1]], tolerance = 1) 
    } else if (i > 1 && i < length(ast14dmo.sd)) { 
    tmp.mrg <- merge(ast14dmo.sd[[i]], ast14dmo.sd[[i+1]], tolerance = 1) 
    ast14dmo.sd.mrg <- merge(ast14dmo.sd.mrg, tmp.mrg, tolerance = 1) 
    } else { 
    # Save merged image 
    writeRaster(ast14dmo.sd.mrg, paste(path.mrg, "/AST14DMO_sd_", z, "m_mrg", sep = ""), format = "GTiff", overwrite = TRUE) 
    } 
} 

Jak zapewne domyślić, kod działa. Łączenie trwa jednak dość długo, biorąc pod uwagę, że każdy pojedynczy obiekt rastrowy ma około 70 mb. Próbowałem też Reduce i do.call, ale to się nie udało, ponieważ nie mogłem podać argumentu "tolerancja", który omija różne pochodzenie plików rastrowych.

Ktoś ma pomysł, jak przyspieszyć działanie?

Odpowiedz

10

Albo użyć do.call

ast14dmo.sd$tolerance <- 1 
ast14dmo.sd$filename <- paste(path.mrg, "/AST14DMO_sd_", z, "m_mrg.tif", sep = "") 
ast14dmo.sd$overwrite <- TRUE 
mm <- do.call(merge, ast14dmo.sd) 

lub tutaj, na przykład w rastrze :: scalić

r1 <- raster(xmx=-150, ymn=60, ncols=30, nrows=30) 
r1[] <- 1:ncell(r1) 
r2 <- raster(xmn=-100, xmx=-50, ymx=50, ymn=30) 
res(r2) <- c(xres(r1), yres(r1)) 
r2[] <- 1:ncell(r2) 

x <- list(r1, r2) 
x$filename <- 'test.tif' 
x$overwrite <- TRUE 
m <- do.call(merge, x) 
+0

Świetne rozwiązanie również, dziękuję! Po prostu rzuciłem okiem na czas obliczeń i okazało się, że twoje podejście za pomocą 'do.call' działa prawie dwa razy szybciej niż' Reduce'. – fdetsch

3

Można użyć Reduce tak na przykład:

Reduce(function(...)merge(...,tolerance=1),ast14dmo.sd) 
+0

To załatwiło sprawę. Dziękuję Ci bardzo! – fdetsch

3

Funkcja "scalania" z pakietu Raster jest nieco powolna. W przypadku dużych projektów szybsza opcja jest do pracy z gdal poleceń w R.

library(gdalUtils) 
library(rgdal) 

listy kompilacji wszystkich plików rastrowych chcesz dołączyć (w bieżącym katalogu roboczym).

all_my_rasts <- c('r1.tif', 'r2.tif', 'r3.tif') 

Utwórz plik szablonu rastrowego do rozbudowy. Pomyśl o tym wielkim pustym płótnie, aby dodać płytki.

e <- extent(-131, -124, 49, 53) 
template <- raster(e) 
projection(template) <- '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' 
writeRaster(template, file="MyBigNastyRasty.tif", format="GTiff") 

Łącz wszystkie płytki rastrowe w jeden duży raster.

mosaic_rasters(gdalfile=all_my_rasts,dst_dataset="MyBigNastyRasty.tif",of="GTiff") 
gdalinfo("MyBigNastyRasty.tif") 

To powinno działać całkiem dobrze dla prędkości (szybsze niż scalić w pakiecie rastrowa), ale jeśli masz tysiące płytek można nawet zajrzeć do budowania VRT pierwszy.

+0

Czy nie ma bardziej wydajnego sposobu na określenie zasięgu bez zgadywania lat/długości? –