Unit 24 - MODIS

The Moderate Resolution Imaging Spectroradiometer (MODIS) is a 36-channel from visible to thermal-infrared sensor that was launched as part of the Terra satellite payload in December 1999 and Aqua satellite in May 2002. The Terra satellite passes twice a day (at 10:30am and 22:30pm local time), the Aqua satellite also passes twice a day (at 01:30am and 13:30pm local time). (source: GRASS Wiki)

Our area of interest, Germany, is covered by two MODIS tiles (see MODLAND grid):

  • h18v03
  • h18v04

MODIS data is provided in 3 projections (Sinusoidal, Lambert Azimuthal Equal-Area, and Geographic). For our purpose, data will be reprojected to ETRS89 / LAEA Europe EPSG:3035.

Create a new GRASS location germany-modis (see Unit 02) using EPSG code (Select CRS from a list by EPSG or description).


Fig. 116 Create a new location based on EPSG code.


Fig. 117 Enter EPSG code.

Enter a new GRASS session (PERMANENT mapset) and install i.modis addons extension (more about installing addons in Unit 17) for downloading and importing MODIS data (note that you have to install also pyMODIS Python Library). Run two commands below in Console tab.

python3 -m pip install setuptools slugify pymodis

g.extension extension=i.modis

GRASS MODIS addon consists of two modules:

Download data


Pre-downloaded MODIS data (year 2019) is available in the sample dataset jena-sample-data-modis.7z (1.0GB) geodata/modis. Readers can continue with importing sample data.

Let’s download desired tiles (h18v03 and h18v04) for year 2021 by i.modis.download.

Land Surface Temperature eight day 1 Km (Terra/Aqua) product will be downloaded.

i.modis.download settings=settings.txt folder=/home/user/geodata/modis/h18v03_04 \
tiles=h18v03,h18v04 \
product=lst_aqua_eight_1000,lst_terra_eight_1000 \
startday=2021-01-01 endday=2021-12-31


Output folder (h18v03_04 in this case) must exists, otherwise the module will fail.

File settings.txt contains two lines: username and password for accessing MODIS download service.

Please read pyModis documentation how to register and set up your account.

Import data

Input MODIS data can be imported and reprojected into target location by i.modis.import.

i.modis.import -mw files=/home/user/geodata/modis/h18v03_04/listfileMOD11A2.006.txt \
spectral='( 1 0 0 0 1 0 0 0 0 0 0 0 )' outfile=tlist-mod.txt

i.modis.import -mw files=/home/user/geodata/modis/h18v03_04/listfileMYD11A2.006.txt \
spectral='( 1 0 0 0 1 0 0 0 0 0 0 0 )' outfile=tlist-myd.txt

If -m flag is given mosaic from input tiles is created automatically, see Fig. 118.


See relevant source code related to spectral option.


Fig. 118 Data mosaic created from h18v03 and h18v04 tiles.


In this section Land Surface Temperature (LST) analysis will be perfmored for Germany.

Let’s start by importing Germany administrative border located in the sample dataset osm/germany_boundary.gpkg.


Administrative border of Germany has been downloaded from OSM database.

/*added by auto repair*/
/*end of auto repair*/
ogr2ogr -f GPKG germany_boundary.gpkg -a_srs EPSG:4326 -t_srs EPSG:3035 /vsicurl_streaming/"\
%22%5D%3B%29%3B%28%2E%5F%3B%3E%3B%29%3Bout%3B%0A" lines

The input file contains national border represented by linestring, see Fig. 119 left part. Mask can be created only from area features (polygons). Input data have to be polygonized. This will be performed by two GRASS operations:

  • change line border to boundary by v.type (in GRASS topological model, an area is composition of boundaries and centroid, see Unit 03)
  • add centroid by v.centroids
v.type input=germany_boundary output=germany_b from_type=line to_type=boundary
v.centroids input=germany_b output=germany

Fig. 119 Germany national boundary as linestring on left and as polygon (area) on right part.

Mask will be created by r.mask. Don’t forget that computational region must be set before creating a mask. Computational region will be defined by Germany vector map and aligned by the input MODIS data by g.region.

g.region vector=germany align=MOD11A2.A2019001_mosaic_LST_Day_1km
r.mask vector=germany

Let’s check range values of our LST data by r.info module:

r.info -r map=MOD11A2.A2019001_mosaic_LST_Day_1km

In order to determine LST from input data, digital values (DN) must be converted into Celsius or Kelvin scale.

\[C = DN * 0.02 - 273.15\]

Conversion to Celsium scale can be done by r.mapcalc (see also Unit 05 - Raster processing). It’s also suitable to replace zero values with no-data value (NULL value in GRASS terminology).

r.mapcalc expression="MOD11A2.A2019001_mosaic_LST_Day_1km_c = \
if(MOD11A2.A2019001_mosaic_LST_Day_1km != 0, \
MOD11A2.A2019001_mosaic_LST_Day_1km * 0.02 - 273.15, null())"

Let’s check range values of new LST data layer.

r.info -r map=MOD11A2.A2019001_mosaic_LST_Day_1km_c

Fig. 120 LST reconstruction for Germany in Celsius scale (color table celsius applied).