Невозможно изменить экстент растра

Я хочу обрезать растр высот, чтобы добавить его в растровый стек. Это просто, я делал это раньше плавно, добавляя растр экорегионов в тот же стек. А вот с возвышением просто не работает. Теперь здесь есть несколько вопросов, посвященных этой проблеме, и я много чего пробовал...

Прежде всего, нам нужно это:

library(rgdal)
library(raster)

Мой стек предикторы2:

#Downloading the stack
predictors2_full<-getData('worldclim', var='bio', res=10)

#Cropping it, I don' need the whole world   
xmin=-120; xmax=-35; ymin=-60; ymax=35
limits <- c(xmin, xmax, ymin, ymax)
predictors2 <- crop(predictors2_full,limits)

Затем я скачал шейп-файл terr_ecorregions здесь: http://maps.tnc.org/files/shp/terr-ecoregions-TNC.zip

setwd("~/ORCHIDACEAE/Ecologicos/w2/layers/terr-ecoregions-TNC")
ecoreg = readOGR("tnc_terr_ecoregions.shp") # I've loaded...
ecoreg2 <- crop(ecoreg,extent(predictors2)) # cropped...
ecoreg2 <- rasterize(ecoreg2, predictors2)  # made the shapefile a raster
predictors4<-addLayer(predictors2,elevation,ecoreg2) # and added the raster
                                                     # to my stack

С возвышением я просто не могу. Цифровая модель рельефа основана на GMTED2010, которую можно скачать здесь: http://edcintl.cr.usgs.gov/downloads/sciweb1/shared/topo/downloads/GMTED/Grid_ZipFiles/mn30_grd.zip

elevation<-raster("w001001.adf") #I've loaded
elevation<-crop(elevation,predictors2) # and cropped

Но высота получает немного другую степень вместо предикторов2:

> extent(elevation)
class       : Extent 
xmin        : -120.0001 
xmax        : -35.00014 
ymin        : -60.00014 
ymax        : 34.99986 
> 

Я попытался сделать их равными во что бы то ни стало, о чем я читал в вопросах здесь ... Я пытался расширить, чтобы ymax высоты соответствовало высоте ymax Predictors2‹-extend(elevation,predictors2) # не работает, степень остается прежней

Я пробовал наоборот... чтобы степень предикторов2 соответствовала степени высоты... тоже ничего.

Но потом я прочитал это

Возможно, вам не захочется играть с setExtent() или extend() ‹- extend(), так как вы можете закончить с неправильными географическими координатами ваших растров — @ztl, 29 июня 2015 г.

И я попытался получить минимальный общий экстент моих растров, следуя ответу @zlt в другом вопросе об экстенте, сделав это

# Summing your rasters will only work where they are not NA
r123 = r1+r2+r3 # r123 has the minimal common extent
r1 = crop(r1, r123) # crop to that minimal extent
r2 = crop(r2, r123)
r3 = crop(r3, r123)

Для этого сначала мне пришлось установить разрешения:

res(elevation)<-res(predictors2) #fixing the resolutions... This one worked.

Но тогда r123 = r1+r2+r не сработало:

> r123=elevation+ecoreg2+predictors2
Error in elevation + ecoreg2 : first Raster object has no values

Может ли кто-нибудь дать мне подсказку по этому поводу? Я действительно хотел бы добавить свою высоту в растр. Забавно то, что у меня есть еще один стек с именем предикторы1 с точно такой же экстентом высоты... И я смог обрезать экорег и добавить экорег как к предикторам1, так и к предикторам2... Почему я не могу просто сделать то же самое с высотой? Я новичок в этом мире, и у меня закончились идеи... Я ценю любые советы.

РЕДАКТИРОВАТЬ: решение, благодаря @Val

Я добрался до этого:

#Getting the factor to aggregate (rasters are multiples of each other)
res(ecoreg2)/res(elevation)
[1] 20 20 #The factor is 20


elevation2<-aggregate(elevation, fact=20)
elevation2 <- crop(elevation2,extent(predictors2))

#Finally adding the layer:
predictors2_eco<-addLayer(predictors2,elevation2,ecoreg)

Новая проблема, подумал...

Я не могу записать стек в geotiff

 writeRaster(predictors2_eco, filename="cropped_predictors2_eco.tif", options="INTERLEAVE=BAND", overwrite=TRUE)

 Error in .checkLevels(levs[[j]], value[[j]]) : 
 new raster attributes (factor values) should be in a data.frame (inside a list)

person Thai    schedule 11.08.2017    source источник
comment
Чтобы записать растровый стек, удалите options="INTERLEAVE=BAND" и используйте bylayer = F   -  person aldo_tapia    schedule 14.08.2017
comment
@aldo_tapia, спасибо за подсказку, bylayer = F имеет смысл!   -  person Thai    schedule 15.08.2017


Ответы (1)


Я думаю, у вас проблемы, потому что вы работаете с растрами разного пространственного разрешения. Таким образом, когда вы обрезаете оба растра до одинакового размера, из-за этого они будут иметь несколько разные фактические размеры. Поэтому, если вы хотите сложить растры, вам нужно сделать их одного разрешения. Либо вы дезагрегируете растр с более грубым разрешением (т. е. увеличиваете разрешение путем передискретизации или другими методами), либо агрегируете растр с более высоким разрешением (т. е. уменьшаете разрешение, например, взяв среднее значение по n пикселю).

Обратите внимание, что если вы измените экстент или разрешение с помощью setExtent(x), extent(x) <-, res(x) <- или подобных, это НЕ будет работать, поскольку вы просто меняете слоты в растровом объекте, а не фактические базовые данные.

Итак, чтобы привести растры к общему разрешению, нужно изменить данные. Для этой цели вы можете использовать функции (среди прочего) aggregate, disaggregate и resample. Но поскольку вы меняете данные, вам нужно четко понимать, что вы делаете и что делает функция, которую вы используете.

Наиболее удобным способом для вас должен быть resample, где вы можете преобразовать растр в другой растр, чтобы они совпадали по экстенту и разрешению. Это будет сделано с использованием определенного метода. По умолчанию он использует nearest neighbor для вычисления новых значений. Если вы работаете с непрерывными данными, такими как высота над уровнем моря, вы можете выбрать bilinear, который является билинейной интерполяцией. В этом случае вы фактически создаете «новые измерения», о чем нужно знать.

Если ваши два разрешения кратны друг другу, вы можете посмотреть на aggregate и disaggregate. В случае disaggregate вы должны разделить растровую ячейку на коэффициент, чтобы получить более высокое разрешение (например, если ваше первое разрешение составляет 10 градусов, а желаемое разрешение составляет 0,05 градуса, вы можете disaggregate с коэффициентом 200, что даст вам 200 ячеек по 0,05 градуса. на каждую 10-градусную ячейку). Этот метод позволит избежать интерполяции.

Вот небольшой рабочий пример:

library(raster)
library(rgeos)

shp <- getData(country='AUT',level=0)

# get centroid for downloading eco and dem data
centroid <- coordinates(gCentroid(shp))

# download 10 degree tmin
ecovar <- getData('worldclim', var='tmin', res=10, lon=centroid[,1], lat=centroid[,2])
ecovar_crop <- crop(ecovar,shp)

# output
> ecovar_crop
class       : RasterBrick 
dimensions  : 16, 46, 736, 12  (nrow, ncol, ncell, nlayers)
resolution  : 0.1666667, 0.1666667  (x, y)
extent      : 9.5, 17.16667, 46.33333, 49  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
data source : in memory
names       : tmin1, tmin2, tmin3, tmin4, tmin5, tmin6, tmin7, tmin8, tmin9, tmin10, tmin11, tmin12 
min values  :  -126,  -125,  -102,   -77,   -33,    -2,    19,    20,     5,    -30,    -74,   -107 
max values  :   -31,   -21,     9,    51,    94,   131,   144,   137,   106,     60,     18,    -17 


# download SRTM elevation - 90m resolution at eqt
elev <- getData('SRTM',lon=centroid[,1], lat=centroid[,2])
elev_crop <- crop(elev, shp)

# output

> elev_crop
class       : RasterLayer 
dimensions  : 3171, 6001, 19029171  (nrow, ncol, ncell)
resolution  : 0.0008333333, 0.0008333333  (x, y)
extent      : 9.999584, 15.00042, 46.37458, 49.01708  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
data source : in memory
names       : srtm_39_03 
values      : 198, 3865  (min, max)

# won't work because of different resolutions (stack is equal to addLayer)
ecoelev <- stack(ecovar_crop,elev_crop)

# resample
elev_crop_RS <- resample(elev_crop,ecovar_crop,method = 'bilinear')

# works now
ecoelev <- stack(ecovar_crop,elev_crop_RS)

# output
> ecoelev
class       : RasterStack 
dimensions  : 16, 46, 736, 13  (nrow, ncol, ncell, nlayers)
resolution  : 0.1666667, 0.1666667  (x, y)
extent      : 9.5, 17.16667, 46.33333, 49  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
names       :     tmin1,     tmin2,     tmin3,     tmin4,     tmin5,     tmin6,     tmin7,     tmin8,     tmin9,    tmin10,    tmin11,    tmin12, srtm_39_03 
min values  : -126.0000, -125.0000, -102.0000,  -77.0000,  -33.0000,   -2.0000,   19.0000,   20.0000,    5.0000,  -30.0000,  -74.0000, -107.0000,   311.7438 
max values  :   -31.000,   -21.000,     9.000,    51.000,    94.000,   131.000,   144.000,   137.000,   106.000,    60.000,    18.000,   -17.000,   3006.011 
person Val    schedule 12.08.2017
comment
большое спасибо! Это сработало, и я многому научился!!! Поскольку мой растр высот действительно был фактором других (разрешение в 20 раз лучше), я использовал aggregate вместо повторной выборки, чтобы избежать изменения данных и интерполяции... Я правильно понял то, что вы объяснили? Это лучший подход в данном случае, верно? - person Thai; 12.08.2017
comment
У меня теперь другая проблема, подумал: я не могу написать свой новый полный стек: > writeRaster(predictors2_eco, filename="cropped_predictors2_eco.tif", options="INTERLEAVE=BAND", overwrite=TRUE) Error in .checkLevels(levs[[j]], value[[j]]) : new raster attributes (factor values) should be in a data.frame (inside a list) ... Не могли бы вы дать мне совет и здесь? - person Thai; 12.08.2017
comment
@Thai Да, я согласен, что aggregate - лучший подход. Как правило, всегда желательно оставаться с исходными данными. Что касается вашей ошибки, я никогда не видел эту ошибку, поэтому я не уверен, в чем ее причина. Вы сложили слои с addLayer или stack? Обоснованное предположение будет заключаться в том, что вы сложили категориальные и непрерывные слои вместе, и это вызывает проблемы. Но я не уверен, что это может быть проблемой - person Val; 12.08.2017
comment
Спасибо, @Val ... Я использовал addLayer и вместо этого попробую использовать стек. - person Thai; 12.08.2017