Reputation: 417
I have had land coverage map in TIF
format that presumably used to calculate an area-weighted yearly mean temperature for Germany. I downloaded this land coverage map data from here (direct download link of land coverage map for Europe). In particular, I intend to extract data of land/soil coverage for the city, agricultural area and vice-versa. In my first step, I imported this land coverage data with raster
package. Here is my R script down below:
library(raster)
library(R.utils)
library(maptools)
url = "https://cidportal.jrc.ec.europa.eu/ftp/jrc-opendata/LUISA/PrimaryOutput/Europe/REF-2014/JRC_LUISA_Input_Corine_land_cover_2006_r_ref_2014.zip"
download.file(url, basename(url))
gunzip(basename(url))
rname <- list.files(getwd(), "tif$")
land_cover = raster::brick("~/LUISA_CLC_land_coverage/clc06_r.tif")
so far I am able to import original land coverage map in RasterBrick
object in R. Note that original map was covered the whole europe, so I
have to crop the regions that I am only interested in. To do so, I used maptools
and raster
package for clipping the map. Here is the R script down below:
data(wrld_simpl)
germany <- wrld_simpl[wrld_simpl@data$NAME == "Germany",]
germany <- spTransform(germany, CRSobj = land_cover@crs)
germany_land <- crop(land_cover, germany)
However, I assume that this cropped land coverage map in RasterBrick
object better to be in grid shapefile
with very high degree resolution, but how is it doable? Any idea?
The main point of raising this question is I need to retrieve all data of land/soil coverage for the city, agricultural area, and match this information to respective Germany NUTS-s level shapefile (download link of Germany level 3 shapefile).
I really don't have a solid idea how to utilize the data in this land coverage map for the sake of calculating area-weighted yearly mean temperature. Perhaps, a possible approach could be to retrieve land/soil coverage for the city, agricultural area data, then find match from Germany NUTS-3 level shapefile.
Here is how to get Germany' NUTS-3 shapefile( R script how to get Germany' NUTS-3 regions' shapefile in R):
library(maptools)
library(rgdal)
library(R.utils)
url = "http://ec.europa.eu/eurostat/cache/GISCO/distribution/v2/nuts/download/ref-nuts-2013-03m.shp.zip"
download.file(url, basename(url))
gunzip(basename(url))
getwd()
setwd("~/ref-nuts-2013-03m.shp/")
list.files(pattern = 'NUTS_RG_03M_2013.*.shp$')
eu <- readOGR(dsn = getwd(), layer ="NUTS_RG_03M_2013_4326_LEVL_2")
Germany_NUTS3 <- eu[eu@data$CNTR_CODE == "DE",]
So using this Gernamny' NUTS-3 shapefile, Germany_NUTS3
, I want to extract all data of land/soil coverage for the city, agricultural area and vice-versa.
If such extraction of data from land coverage map in RasterBrick
, how can I make this happen in R? Is that doable? Any efficient workaround to get this done? Any idea?
Upvotes: 1
Views: 252
Reputation: 7023
As we discussed in the comments and in chat, this would be a quick and dirty method (the JRC approach, amongst others, would be certainly a better way to do it but also much more effort)
So you have your landcover land_cover
and your NUTS regions over Germany Germany_NUTS3
:
# you can take the raster function since it's only one layer
land_cover <- raster::raster("~/LUISA_CLC_land_coverage/clc06_r.tif")
eu <- readOGR(dsn = getwd(), layer ="NUTS_RG_03M_2013_4326_LEVL_2")
Germany_NUTS3 <- eu[eu@data$CNTR_CODE == "DE",]
# you can use Germany_NUTS straight for cropping the landcover, so we'll project it to the raster's coordinate system
Germany_NUTS3_projected <- spTransform(Germany_NUTS3, CRSobj = land_cover@crs)
land_cover_germany <- crop(land_cover, Germany_NUTS3_projected)
Now you can extract the landcover pixels for the NUTS region using extract
from the raster package.
BE AWARE: This can take some time, especially if the area or the raster is big or you have many polygons. If you need to do this repeatedly, you might want to use a different approach.
As an example, I'll do it for one of the NUTS regions:
pixel_extract <- raster::extract(land_cover_germany,Germany_NUTS3_projected[2,])
If you use more polygons at once, pixel_extract
will be a list of vectors with pixel values with each element representing a different polygon.
In this exemplary case, there's only one element, showing the landcover class values for the pixels within this polygon:
> head(pixel_extract)
[[1]]
[1] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
[24] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
[47] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
[70] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
[93] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
[116] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 23 23 24 24 24 24 24 24 24
[139] 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 4 ...
Now, to derive the area covered by your classes of interest, you need to count the pixels and then multiply them with the area of a single pixel. Since the resolution of a single pixel is 100 by 100 meters, the area is 10000 m2.
To identify the land cover values of your desired classes, we can take a look into the LUISA_legend.xls
file which comes with the raster:
GRID_CODE CLC_CODE LABEL 1 111 Artificial surfaces 2 112 Artificial surfaces 3 121 Artificial surfaces 4 122 Artificial surfaces 5 123 Artificial surfaces 6 124 Artificial surfaces 7 131 Artificial surfaces 8 132 Artificial surfaces 9 133 Artificial surfaces 10 141 Artificial surfaces 11 142 Artificial surfaces 12 211 Agricultural areas 13 212 Agricultural areas 14 213 Agricultural areas 15 221 Agricultural areas 16 222 Agricultural areas 17 223 Agricultural areas 18 231 Agricultural areas 19 241 Agricultural areas 20 242 Agricultural areas 21 243 Agricultural areas 22 244 Agricultural areas
So to count the pixels, we just see which values are between 1 and 11 for artificial surfaces, and between 12 and 22 for agriculture. To get an area "estimate" we can calculate the number of pixels with the area of a single pixel.
areas <-data.frame(ARTIFICIAL_AREA=sum(pixel_extract[[1]]>=1 & pixel_extract[[1]]<=11) * (100*100),
AGRICULTURE_AREA=sum(pixel_extract[[1]]>=12 & pixel_extract[[1]]<=22) * (100*100))
This gives you an area estimate in square meters:
> areas
ARTIFICIAL_AREA AGRICULTURE_AREA
1 954030000 9282970000
If pixel_extract
is a list with an element per polygon (that is if you used the full shapefile), you can calculate the areas with lappy
and use do.call(rbind,
to create a single dataframe:
areas <- lapply(pixel_extract, function(x) data.frame(ARTIFICIAL_AREA=sum(x >=1 & x <=11) * (100*100),
AGRICULTURE_AREA=sum(x>=12 & x<=22) * (100*100))
areas_df <- do.call(rbind,areas)
Upvotes: 4