This example demonstrates:
Literature
In [0]:
; Set some variables used throughout the script
cloudfree = ['S2A_L2A_UMV32N_20160902T103228_10m_studyarea.tif','S2A_L2A_UMV32N_20161002T103017_10m_studyarea.tif','S2A_L2A_UMV32N_20160922T103357_10m_studyarea.tif','S2A_L2A_UMV32N_20160823T103332_10m_studyarea.tif','S2A_L2A_UMV32N_20160813T103228_10m_studyarea.tif','S2A_L2A_UMV32N_20160624T103023_10m_studyarea.tif','S2A_L2A_UMV32N_20160505T103027_10m_studyarea.tif','S2A_L2A_UMV32N_20160126T104630_10m_studyarea.tif','S2A_L2A_UMV32N_20151207T103733_10m_studyarea.tif','S2A_L2A_UMV32N_20151227T104738_10m_studyarea.tif']
ref = GET_RELDIR('ROIseries_3D__define',1,['data','sentinel_2a'])
shp = ref+"vector\"+"studyarea.shp"
rasterseries = ref+ "rasters\" + cloudfree
id_col_name = "Id"
In [1]:
;Try to load multiple multispectral images
id ="S2"
db =FILEPATH(id)
RS = ROIseries_3D()
RS = RS.COOKIE_CUTTER(id,db,shp,id_col_name,rasterseries)
retall
This does not work: Providing multiple multispectral images would result in 4 Dimensions (1 spectral, 1 temporal, 2 spatial). This is not supported in ROIseries. It is however possible to either:
In [2]:
id_nir = "NIR"
db_nir = FILEPATH(id_nir,/TMP)
NIR = ROIseries_3D()
NIR.COOKIE_CUTTER(id_nir,db_nir,shp,id_col_name,rasterseries,SPECTRAL_INDEXER_FORMULA="R[3]")
NIR.TIME_FROM_FILENAMES(rasterseries,[15,4],[19,2],[21,2])
NIR.unit = LIST("time","Distribution of NIR Values per object")
id_red = "RED"
db_red = FILEPATH(id_red,/TMP)
RED = ROIseries_3D()
RED.COOKIE_CUTTER(id_red,db_red,shp,id_col_name,rasterseries,SPECTRAL_INDEXER_FORMULA="R[0]")
RED.time = NIR.time
id_blue = "BLUE"
db_blue = FILEPATH(id_blue,/TMP)
BLUE = ROIseries_3D()
BLUE.COOKIE_CUTTER(id_blue,db_blue,shp,id_col_name,rasterseries,SPECTRAL_INDEXER_FORMULA="R[2]")
BLUE.time = NIR.time
BLUE.unit = LIST("time","Distribution of BLUE values per object")
Plot the blue channel for object with ID = 1
In [3]:
BLUE.BOXPLOT(ID=1)
Calculate the EVI
In [4]:
C1 = 6
C2 = 7.5
L = 1
G = 2.5
EVI = (NIR - RED)/(NIR + RED * C1 - BLUE * C2 + L) * G
FIRE, GIRLS, MONEY, 9.1*10^-31 (or whatever makes you read the next lines :)):
Caution has to be exercised when using numbers in such an expression (Like C1, C2, L and G):
They need to be placed as the 'right' argument e. g.:
Correct: NIR * 42
Wrong: 42 * NIR
The reason is that the arithmetic functionality is defined for the ROIseries object, but undefined for a numeric value. For background information check the operator overloading functionality on e. g.: https://www.harrisgeospatial.com/docs/IDL_Object_overloadAsterisk.html
When array arithmetics are applied all metadata is lost since it is unpredictable what metadata would make sense to be kept. One exception is the time attribute which has to be the same for all objects anyway and is checked and handed over internally.
In [5]:
EVI.id = "EVI"
EVI.db = FILEPATH("EVI",/TMP)
EVI.unit = LIST("time","Distribution of EVI Values per object")
EVI.boxplot(ID=3)
It is possible to use the objects to calculate any arbitrary indices like the NDVI
In [6]:
NDVI = (NIR-RED)/(NIR+RED)
NDVI.id = "NDVI"
NDVI.db = FILEPATH("NDVI",/TMP)
NDVI.unit = LIST("time","Distribution of NDVI Values per object")
NDVI.boxplot(ID=3)
In [7]:
EVI_2 = ROIseries_3D()
EVI_2.COOKIE_CUTTER("EVI_2",FILEPATH("EVI_2",/TMP),shp,id_col_name,rasterseries,SPECTRAL_INDEXER_FORMULA="(R[3] - R[0])/(R[3] + R[0] * 6 - R[2] * 7.5 + 1) * 2.5")
EVI_2.time = NIR.time
EVI_2.unit = LIST("time","Distribution of EVI Values per object")
EVI_2.boxplot(ID=3)
Comparing the output from EVI_2.boxplot() and EVI.boxplot() you should notice that both ways lead to the same result. However they provide different levels of interactivity: