Share on: Diaspora*TwitterFacebookLinkedInHackerNewsEmailReddit

Η ανάρτηση αυτή περιλαμβάνει το περιεχόμενο από το workshop στο FOSSCOMM 2019 στην Λαμία. Για περισσότερες λεπτομέρειες ανατρέξτε στο github repository.

Στόχος του εργαστηρίου είναι η εξοικείωση του χρήστη με το πακέτο raster της R το οποίο προσφέρει την δυνατότητα ανάγνωσης ψηφιδωτών δεδομένων (raster) και επεξεργασίας τους (crop, reclassify, reproject, resample κτλ.).

Επιπλέον, θα επικεντρωθούμε στην κλάση raster stack η οποία δημιουργεί συστοιχίες ψηφιδωτών δεδομένων, κατάλληλες για χρονοσειρές και πολυκαναλικές εικόνες.

Η διεξαγωγή του εργαστηρίου θα γίνει μέσω παραδειγμάτων και με την χρήση δεδομένων νυκτερινών φώτων DMSP-OLS Nighttime Lights Time Series (Stable Lights Version 4). Θα προηγηθεί μια σύντομη παρουσίαση των βημάτων και της διαδικασίας ώστε οι χρήστες να αποκτήσουν μια σύντομη αλλά περιεκτική εικόνα του στόχου του εργαστηρίου και των δυνατοτητων που προσφέρει ο προγραμματισμός με την R.

Εγκατάσταση των απαραίτητων βιβλιοθηκών

install.packages(c("raster","ggplot2","rasterVis","rgdal","leaflet"),dependencies=T)

Εισαγωγή των απαραίτητων βιβλιοθηκών

library(raster)
library(ggplot2)
library(rasterVis)
library(rgdal)
library(leaflet)

Ορισμός Working directory

setwd('/home/leonidas/Desktop/rworkshop')

Επιβεβαίωση ποιο είναι το working directory

getwd()

###### [1] "/home/leonidas/Desktop/rworkshop"

Δημιουργία rasterStack Object

myfiles <- list.files(path=file.path("data","dmsp_ols"),  pattern="*.stable_lights.tif$", full.names = TRUE)
s <- raster::stack(myfiles)

Οπτικοποίηση raster stack

plot(s)

Μερικές ιδιότητες του rasterStack

class(s) # ποιάς κλάσης ειναι object?
## [1] "RasterStack"
## attr(,"package")
## [1] "raster"
s@ncols  # πλήθος στηλών 
## [1] 1422
s@nrows  # πλήθος γραμμών
 ## [1] 1122
s@extent # όρια γεωγραφικής έκτασης
## class      : Extent 
## xmin       : 18.50417 
## xmax       : 30.35417 
## ymin       : 33.8625 
## ymax       : 43.2125
names(s)   # όνομα των επιμέρους raster
##  [1] "F101992.v4b_web.stable_lights" "F101993.v4b_web.stable_lights"
##  [3] "F101994.v4b_web.stable_lights" "F121994.v4b_web.stable_lights"
##  [5] "F121995.v4b_web.stable_lights" "F121996.v4b_web.stable_lights"
##  [7] "F121997.v4b_web.stable_lights" "F121998.v4b_web.stable_lights"
##  [9] "F121999.v4b_web.stable_lights" "F141997.v4b_web.stable_lights"
## [11] "F141998.v4b_web.stable_lights" "F141999.v4b_web.stable_lights"
## [13] "F142000.v4b_web.stable_lights" "F142001.v4b_web.stable_lights"
## [15] "F142002.v4b_web.stable_lights" "F142003.v4b_web.stable_lights"
## [17] "F152000.v4b_web.stable_lights" "F152001.v4b_web.stable_lights"
## [19] "F152002.v4b_web.stable_lights" "F152003.v4b_web.stable_lights"
## [21] "F152004.v4b_web.stable_lights" "F152005.v4b_web.stable_lights"
## [23] "F152006.v4b_web.stable_lights" "F152007.v4b_web.stable_lights"
## [25] "F162004.v4b_web.stable_lights" "F162005.v4b_web.stable_lights"
## [27] "F162006.v4b_web.stable_lights" "F162007.v4b_web.stable_lights"
## [29] "F162008.v4b_web.stable_lights" "F162009.v4b_web.stable_lights"
## [31] "F182010.v4d_web.stable_lights" "F182011.v4c_web.stable_lights"
## [33] "F182012.v4c_web.stable_lights" "F182013.v4c_web.stable_lights"
nlayers(s) # πλήθος raster
## [1] 34
res(s) # resolution των raster
## [1] 0.008333333 0.008333333
inMemory(s) # επαληθέουμε αν τα δεδομένα είναι στην μνήμη
## [1] FALSE
fromDisk(s) # επαληθέουμε αν τα δεδομένα είναι στον δίσκο
## [1] TRUE

Υποσύνολο από layers του stack

sub_s <- subset(s, c(1:5))
plot(sub_s)

sub_s
## class      : RasterStack 
## dimensions : 1122, 1422, 1595484, 5  (nrow, ncol, ncell, nlayers)
## resolution : 0.008333333, 0.008333333  (x, y)
## extent     : 18.50417, 30.35417, 33.8625, 43.2125  (xmin, xmax, ymin, ymax)
## crs        : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
## names      : F101992.v4b_web.stable_lights, F101993.v4b_web.stable_lights, F101994.v4b_web.stable_lights, F121994.v4b_web.stable_lights, F121995.v4b_web.stable_lights 
## min values :                             0,                             0,                             0,                             0,                             0 
## max values :                            63,                            63,                            63,                            63,                            63
rm(sub_s) #διαγραφή object από το περιβάλλον
#sub_s

Αποκοπή του rasterStack στα όρια του Ν. Μαγνησίας

Ανάγνωση διανυσματικών δεδομένων geopackage

pe <- readOGR(file.path("data","per_enot", "pe.gpkg"), "pe")
## OGR data source with driver: GPKG 
## Source: "/home/leonidas/Desktop/rworkshop/data/per_enot/pe.gpkg", layer: "pe"
## with 75 features
## It has 5 fields
# ?readOGR
crs(pe)

## CRS arguments:
##  +proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=0
## +ellps=GRS80 +towgs84=-199.87,74.79,246.62,0,0,0,0 +units=m
## +no_defs
plot(pe)

Reprojection σε WGS’84 και επιλογή του Ν. Μαγνησίας

pe_wgs <- sp::spTransform(pe, CRS("+init=epsg:4326"))
crs(pe_wgs)
## CRS arguments:
##  +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84
## +towgs84=0,0,0
View(pe_wgs@data)
magnisia <- subset(pe_wgs, KALCODE==c(24)) #επιλογή του Ν. Μαγνησίας
plot(magnisia)

print(magnisia)
## class       : SpatialPolygonsDataFrame 
## features    : 1 
## extent      : 22.49044, 23.35152, 38.96959, 39.60304  (xmin, xmax, ymin, ymax)
## crs         : +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
## variables   : 5
## names       : OBJECTID, KALCODE,                        LEKTIKO,    SHAPE_Leng,    SHAPE_Area 
## value       :       24,      24, ΠΕΡΙΦΕΡΕΙΑΚΗ ΕΝΟΤΗΤΑ ΜΑΓΝΗΣΙΑΣ, 553550.759122, 2364238989.84

Ορισμός των ορίων της περιοχής μέσω της δημιουργίας ενός extent object

#ext<-extent(22.61,24.34,37.33,38.69) #Attiki
ext <- raster::extent(magnisia)
str(ext)
## Formal class 'Extent' [package "raster"] with 4 slots
##   ..@ xmin: num 22.5
##   ..@ xmax: num 23.4
##   ..@ ymin: num 39
##   ..@ ymax: num 39.6
plot(pe_wgs)
plot(as(ext, 'SpatialPolygons'),col=rgb(1, 0, 0, alpha=0.5), add=T)

s <-crop(s, ext) # εδώ διατηρεί το αρχικό resolution και προσαρμόζει τα άκρα, επίσης μετατρέπει το stack σε brick

inMemory(s) # επαληθέουμε αν τα δεδομένα είναι στην μνήμη
## [1] FALSE
fromDisk(s) # επαληθέουμε αν τα δεδομένα είναι στον δίσκο   
## [1] TRUE
s@extent
## class      : Extent 
## xmin       : 22.4875 
## xmax       : 23.35417 
## ymin       : 38.97083 
## ymax       : 39.60417
names(s)
##  [1] "F101992.v4b_web.stable_lights" "F101993.v4b_web.stable_lights"
##  [3] "F101994.v4b_web.stable_lights" "F121994.v4b_web.stable_lights"
##  [5] "F121995.v4b_web.stable_lights" "F121996.v4b_web.stable_lights"
##  [7] "F121997.v4b_web.stable_lights" "F121998.v4b_web.stable_lights"
##  [9] "F121999.v4b_web.stable_lights" "F141997.v4b_web.stable_lights"
## [11] "F141998.v4b_web.stable_lights" "F141999.v4b_web.stable_lights"
## [13] "F142000.v4b_web.stable_lights" "F142001.v4b_web.stable_lights"
## [15] "F142002.v4b_web.stable_lights" "F142003.v4b_web.stable_lights"
## [17] "F152000.v4b_web.stable_lights" "F152001.v4b_web.stable_lights"
## [19] "F152002.v4b_web.stable_lights" "F152003.v4b_web.stable_lights"
## [21] "F152004.v4b_web.stable_lights" "F152005.v4b_web.stable_lights"
## [23] "F152006.v4b_web.stable_lights" "F152007.v4b_web.stable_lights"
## [25] "F162004.v4b_web.stable_lights" "F162005.v4b_web.stable_lights"
## [27] "F162006.v4b_web.stable_lights" "F162007.v4b_web.stable_lights"
## [29] "F162008.v4b_web.stable_lights" "F162009.v4b_web.stable_lights"
## [31] "F182010.v4d_web.stable_lights" "F182011.v4c_web.stable_lights"
## [33] "F182012.v4c_web.stable_lights" "F182013.v4c_web.stable_lights"
res(s)
## [1] 0.008333333 0.008333333
nlayers(s)
## [1] 34

Προβολή στο ΕΓΣΑ’ 87

greekgrid <- "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=-199.87,74.79,246.62,0,0,0,0 +units=m +no_defs"

s <- projectRaster(from=s, res=1000, crs=greekgrid, method="ngb") 
plot(s[[1]])

Προβολή σε χάρτη leaflet

leaflet() %>% 
  addTiles() %>%
  addRasterImage(s[[1]], opacity = 0.6)

Compare rasters


compareRaster(s[[1]], s[[15]], extent=TRUE )
## [1] TRUE
compareRaster(s[[1]], s[[15]], rowcol=TRUE )
## [1] TRUE
compareRaster(s[[1]], s[[15]], crs=TRUE)
## [1] TRUE
compareRaster(s[[1]], s[[15]], res=TRUE)
## [1] TRUE
compareRaster(s[[1]], s[[15]], orig=TRUE)
## [1] TRUE
compareRaster(s[[1]], s[[15]], values=T,stopiffalse = F)
## [1] FALSE

Resample rasters

#Δημιουργία νεόυ raster 
grid <- raster()
extent(grid) <- extent(s)
res(grid)=c(2000,2000)

resampled_s <- resample(s, grid, method = "ngb")
res(s)
## [1] 1000 1000
res(resampled_s)
## [1] 2000 2000

Μέσος όρος ανά έτος με την χρήση stackApply

names(s)
##  [1] "F101992.v4b_web.stable_lights" "F101993.v4b_web.stable_lights"
##  [3] "F101994.v4b_web.stable_lights" "F121994.v4b_web.stable_lights"
##  [5] "F121995.v4b_web.stable_lights" "F121996.v4b_web.stable_lights"
##  [7] "F121997.v4b_web.stable_lights" "F121998.v4b_web.stable_lights"
##  [9] "F121999.v4b_web.stable_lights" "F141997.v4b_web.stable_lights"
## [11] "F141998.v4b_web.stable_lights" "F141999.v4b_web.stable_lights"
## [13] "F142000.v4b_web.stable_lights" "F142001.v4b_web.stable_lights"
## [15] "F142002.v4b_web.stable_lights" "F142003.v4b_web.stable_lights"
## [17] "F152000.v4b_web.stable_lights" "F152001.v4b_web.stable_lights"
## [19] "F152002.v4b_web.stable_lights" "F152003.v4b_web.stable_lights"
## [21] "F152004.v4b_web.stable_lights" "F152005.v4b_web.stable_lights"
## [23] "F152006.v4b_web.stable_lights" "F152007.v4b_web.stable_lights"
## [25] "F162004.v4b_web.stable_lights" "F162005.v4b_web.stable_lights"
## [27] "F162006.v4b_web.stable_lights" "F162007.v4b_web.stable_lights"
## [29] "F162008.v4b_web.stable_lights" "F162009.v4b_web.stable_lights"
## [31] "F182010.v4d_web.stable_lights" "F182011.v4c_web.stable_lights"
## [33] "F182012.v4c_web.stable_lights" "F182013.v4c_web.stable_lights"
years <- substr(names(s),4,7)


#Α' τρόπος
indices <- c(1,2,3,3,4,5,6,7,8,6,7,8,9,10,11,12,9,10,11,12,13,14,15,16,13,14,15,16,17,18,19,20,21,22)

# B' τρόπος
indices <- factor(years)
levels(indices) <-1:length(levels(indices))

nlayers(s)
## [1] 34
s<-stackApply(s, as.integer(indices), fun = mean, na.rm = TRUE)
nlayers(s)
## [1] 22
names(s) <-unique(years)

Reclassify τιμών

Ορίζουμε όσες τιμές στο raster είναι μικρότερες/ίσες του 6 στα raster layers σε NA

1ος τρόπος

rc1 <- s

rc1[rc1<=6] <- NA #δεν ειναι memory safe

2ος τρόπος

s_calc <- raster::calc(s, fun=function(x){x[x<=6]<-NA; return(x)}) 

3ος τρόπος

rc2 <- raster::reclassify(s, c(-Inf,6,NA))

plot(s[[11]]) # plot ενδέκατο raster από το αρχικό stac

plot(s_calc[[11]]) #plot από το αρχικό stack, από το φιλτραρισμένο, εναλλακτικά plot(s_calc$index_1992)

compareRaster(rc1, rc2, values=T)
## [1] TRUE
compareRaster(s_calc,rc2, values=T)
## [1] TRUE
compareRaster(s_calc,s, values=T,stopiffalse = F)
## [1] FALSE

Οπτικοποίηση με το levelplot

rasterVis::levelplot(s_calc) # προσοχή μπορεί να αργήσει αν ειναι πολλά raster

names(s)
##  [1] "X1992" "X1993" "X1994" "X1995" "X1996" "X1997" "X1998" "X1999"
##  [9] "X2000" "X2001" "X2002" "X2003" "X2004" "X2005" "X2006" "X2007"
## [17] "X2008" "X2009" "X2010" "X2011" "X2012" "X2013"
(years <- substring(names(s),2))
##  [1] "1992" "1993" "1994" "1995" "1996" "1997" "1998" "1999" "2000" "2001"
## [11] "2002" "2003" "2004" "2005" "2006" "2007" "2008" "2009" "2010" "2011"
## [21] "2012" "2013"
rasterVis::levelplot(s_calc,main="Raster δεδομενα DMSP/OLS για την Μαγνησία, 1992-2013", 

                     scales=list(y=list(draw=FALSE),
                                 x=list(draw=FALSE)),  
                     names.attr=years,
                     colorkey=NULL)

Υπολογισμός SoL μέσω cellStats

SoL <- cellStats(s_calc, stat='sum', na.rm=TRUE)

df<-data.frame(SoL=SoL, Year=as.integer(years) )#δημιουργία dataframe
write.csv(df,file.path('output','SoL.csv')) # εγγραφή σε csv

Οπτικοποίηση δεδομένων SoL σε γράφημα

Γράφημα με τυπικά εργαλεία plot της R

#jpeg('SoL.jpg')
#dev.off
plot(x=df$Year,
       y=df$SoL, 
       type='l',
       xlab="Year", 
       ylab="Sum of Lights (SoL)",
       main='SoL for Magnesia',xaxt="n")
  axis(1, at=df$Year,cex.axis=0.8, las=2)
points(x=df$Year,y=df$SoL)

Γράφημα με ggplot

ggplot2::ggplot(data=df, aes(x=Year,y=SoL))+
  geom_line()+
  geom_point()+
  ggtitle("Sum of Lights (SoL) for Magnesia")+ 
  scale_x_continuous("Years", labels = as.character(df$Year), breaks = df$Year)+
  theme(plot.title = element_text(hjust = 0.5))+theme(text = element_text(size=14),
                                                      axis.text.x = element_text(angle=90)) 

Αποθήκευση γραφήματος

ggplot2::ggsave(file.path("output",'SoL.png'), plot = last_plot(), device = "png", 
       scale = 1, width = 10, height = 5, units = c("in", "cm", "mm"),
       dpi = 300, limitsize = TRUE)

Αποθήκευση των rasterStack σαν ξεχωριστά αρχεία geotiff

# προσοχή στο data(t)ype όχι data(T)ype
raster::writeRaster(s_calc, filename=file.path("output",years), bylayer=TRUE,datatype="INT1U", options="COMPRESS=LZW", format="GTiff",overwrite=TRUE)

Comments

comments powered by Disqus