Unit 24 - MODIS

There are two satellites, Aqua and Terra which carry the MODIS sensor as payload. The Moderate Resolution Imaging Spectroradiometer (:wikipedia-en:`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 (May 2002). The Terra satellite passes twice a day (at about 10:30am, and 22:30pm local time), also the Aqua satellite passes twice a day (at about 01:30am, and 13:30pm local time). (source: GRASS Wiki)

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

  • h18v03
  • h18v04

Download and import

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

At first, a new GRASS location need to be created (see Unit 02). It can be easily done by using EPSG code (Select EPSG code of spatial reference system).


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


Fig. 112 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).

pip install pymodis
g.extension extension=i.modis

GRASS MODIS addon consists of two modules:

Let’s download desired tiles (h18v03 and h18v04) for year 2017. We are interested about LST products (both Aqua and Terra satellites).


Already downloaded MODIS can be found in sample dataset (download 7z-archive) in modis/h18v03_04 folder. Or alternatively you can use GRASS location with imported data (grassdata/germany-modis.tar.gz) and continue with LST computation.

i.modis.download settings=settings.txt folder=h18v03_04 tiles=h18v03,h18v04 \
product=lst_aqua_eight_1000,lst_terra_eight_1000 \
startday=2017-01-01 endday=2017-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.

Then we can import data including reprojection into our location.

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

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

If -m flag is given, the import tool creates mosaics from tiles automatically, see Fig. 113.


Fig. 113 Final mosaics created from h18v03 and h18v04 tiles.


In this section we will perform Land Surface Temperature (LST) analysis in Germany region. At first we will import layer with Germany administrative border. This data can be found in sample datasets (download 7z-archive): 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

Let’s import the boundary of Germany into our mapset. The input file contains national border represented by linestring, see Fig. 114 left part. It’s complication since a mask can be set only from areal features (polygons). We need to polygonize input data. 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 output=germany_b from_type=line to_type=boundary
v.centroids input=germany_b output=germany_boundary

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

Now we can create a desired mask (r.mask). Don’t forget that a mask is created in the current computation region. First you set computation extent based on Germany vector map and than align computation grid to input data by g.region.

g.region vector=germany_boundary align=MOD11A2.A2017001_mosaic_LST_Day_1km
r.mask vector=germany_boundary

Let’s check range values of our LST data (by r.info module or from Layer Manager, see Unit 03).

r.info -r map=MOD11A2.A2017001_mosaic_LST_Day_1km

The values do not appear to be temperature. 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 Unit 05 - Perform computation for basic information about map algebra in GRASS). It’s also suitable to replace zero values with no-data value (NULL values in GRASS terminology).

Example (replace tile with real map name):

r.mapcalc expression="tile_c = if(tile != 0, tile * 0.02 - 273.15, null())"

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