MODIS/Aqua+Terra Global Flood Product
In this example, we will download and visualize the MODIS/Aqua+Terra Global Flood Product for the Valencia region (Spain) on the 2d November, 2024.
The data has been also be downloaded from NASA World View. Unfortunately, only the last 7 days are visible on this sites but the download links below are still available. On the NASA World View page, one can click on "Add Layers", cloose "Flood (3-Day Window)" and confirm with "Add Layer". To download the data for a different day, click on "Data" and download the "MODIS/Aqua+Terra Global Flood Product L3 NRT 250m 3-day GeoTIFF" product, set your area of interest and go to "Download Via EarthData Search".
using Dates
using TIFFDatasets
using CairoMakie
using CommonDataModel: @select
using ColorSchemes
using Statistics
The data was originally available at nrt3.modaps.eosdis.nasa.gov:
urls = [
"https://data-assimilation.net/upload/Alex/TIFF/MCDWD_L3_F2_NRT.A2024306.h17v05.061.tif",
"https://data-assimilation.net/upload/Alex/TIFF/MCDWD_L3_F2_NRT.A2024306.h18v05.061.tif",
];
Download the data if necessary
fnames = basename.(urls)
if !all(isfile.(fnames))
download.(urls,fnames)
end
2-element Vector{String}:
"MCDWD_L3_F2_NRT.A2024306.h17v05.061.tif"
"MCDWD_L3_F2_NRT.A2024306.h18v05.061.tif"
Inspect the first geoTIFF file
ds = TIFFDataset(fnames[1],"r")
Dataset: MCDWD_L3_F2_NRT.A2024306.h17v05.061.tif
Group: /
Dimensions
cols = 4800
rows = 4800
Variables
lon (4800 × 4800)
Datatype: Float64 (Float64)
Dimensions: cols × rows
Attributes:
standard_name = longitude
units = degrees_east
lat (4800 × 4800)
Datatype: Float64 (Float64)
Dimensions: cols × rows
Attributes:
standard_name = latitude
units = degrees_north
x (4800)
Datatype: Float64 (Float64)
Dimensions: cols
Attributes:
standard_name = projection_x_coordinate
y (4800)
Datatype: Float64 (Float64)
Dimensions: rows
Attributes:
standard_name = projection_y_coordinate
crs
Attributes:
longitude_of_prime_meridian = 0.0
semi_major_axis = 6.3782064e6
inverse_flattening = 294.978698213898
crs_wkt = GEOGCS["Unknown datum based upon the Clarke 1866 ellipsoid",DATUM["Not specified (based on Clarke 1866 spheroid)",SPHEROID["Clarke 1866",6378206.4,294.978698213898,AUTHORITY["EPSG","7008"]]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST]]
GeoTransform = -10.0 0.0020833333333333333 0.0 40.0 0.0 -0.0020833333333333333
band1 (4800 × 4800)
Datatype: Union{Missing, UInt8} (UInt8)
Dimensions: cols × rows
Attributes:
grid_mapping = crs
_FillValue = 255.0
long_name = NRT Combined Terra and Aqua MODIS Flood_2Day_250m
valid_range = UInt8[0x00, 0x03]
Global attributes
Conventions = CF-1.8
ALGORITHMPACKAGEACCEPTANCEDATE = 2019-10-09
ALGORITHMPACKAGEMATURITYCODE = verified
ALGORITHMPACKAGENAME = MCDFLOOD
ALGORITHMPACKAGEVERSION = 6.1.0
ASSOCIATEDINSTRUMENTSHORTNAME.1 = MODIS
ASSOCIATEDPLATFORMSHORTNAME.1 = AMPM
ASSOCIATEDSENSORSHORTNAME.1 = MODIS
AUTOMATICQUALITYFLAG.1 = Passed
AUTOMATICQUALITYFLAGEXPLANATION.1 = Always Passed.
DAYNIGHTFLAG = Day
description = 2 day flood pixels detected from Terra and Aqua
no clouds removed
terrain shadow pixels masked
HAND pixels masked
threshold from table, minimum of 2
Flag values:
255 : Insufficient data
0 : No water
1 : Water (matches standard reference water)
2 : Recurring flood (expected seasonal flood)
3 : Flood (unusual)
DESCRREVISION = 6.1.4
EASTBOUNDINGCOORDINATE = 0.000000
EQUATORCROSSINGDATE.1 = 0
EQUATORCROSSINGLONGITUDE.1 = 0
EQUATORCROSSINGTIME.1 = 0
EXCLUSIONGRINGFLAG = N
GRINGPOINTLATITUDE = 40, 40, 30, 30
GRINGPOINTLONGITUDE = -10, 0, 0, -10
GRINGPOINTSEQUENCENO = 1, 2, 3, 4
HDFEOSVersion = HDFEOS_V2.20
HORIZONTALTILENUMBER = 17
identifier_product_doi = 10.5067/MODIS/MCDWD_L3_NRT.061
identifier_product_doi_authority = http://dx.doi.org
INPUTPOINTER = MCDWD_IHMA.A2023001.h17v05.001.img,MCDWD_IRWMA.A2023001.h17v05.001.img,MCDWD_L3_NRT.A2024305.h17v05.061.2024306060718.hdf,MODWDLGA_NRT.A2024306.0905.h17v05.061.2024306103428.hdf,MODWDLGA_NRT.A2024306.1040.h17v05.061.2024306115011.hdf,MODWDLGA_NRT.A2024306.1045.h17v05.061.2024306114951.hdf,MODWD_ITSM.A2010022.h17v05.001.img,MYDWDLGA_NRT.A2024306.1415.h17v05.061.2024306152549.hdf,MYDWDLGA_NRT.A2024306.1420.h17v05.061.2024306152510.hdf,MYDWD_ITSM.A2010022.h17v05.001.img
INSTRUMENTNAME = Moderate-Resolution Imaging SpectroRadiometer
LOCALGRANULEID = MCDWD_L3_NRT.A2024306.h17v05.061.2024307013418.hdf
LOCALVERSIONID = 6.1.4
LONGNAME = MODIS/Aqua+Terra Flood Map Daily L3 Global 250m LLL Grid NRT
NORTHBOUNDINGCOORDINATE = 40.000000
ORBITNUMBER.1 = 0
PGEVERSION = 6.1.4
PROCESSINGCENTER = MODAPS
PROCESSINGENVIRONMENT = Linux minion20312 5.4.0-1099-fips #109-Ubuntu SMP Tue Apr 30 14:07:22 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
PRODUCTIONDATETIME = 2024-11-02T01:34:18
PRODUCTIONHISTORY = PGE159N:6.1.4;
QAPERCENTCLOUDCOVER = 0
QAPERCENTCLOUDSHADOW = 0
QAPERCENTMISSINGDATA = 0
QAPERCENTOUTOFBOUNDSDATA = 0
RANGEBEGINNINGDATE = 2024-11-01
RANGEBEGINNINGTIME = 00:00:00
RANGEENDINGDATE = 2024-11-02
RANGEENDINGTIME = 00:00:00
REPROCESSINGACTUAL = Near Real Time
REPROCESSINGPLANNED = further update is anticipated
SCIENCEQUALITYFLAG.1 = Not Investigated
SCIENCEQUALITYFLAGEXPLANATION.1 = 0
SHORTNAME = MCDWD_L3_NRT
SOUTHBOUNDINGCOORDINATE = 30.000000
TileID = 61017005
units = none
VERSIONID = 61
VERTICALTILENUMBER = 05
WESTBOUNDINGCOORDINATE = -10.000000
AREA_OR_POINT = Area
The size of the data array band1
:
size(ds["band1"])
(4800, 4800)
Concatenate two geoTIFF files along the cols
dimension (columns)
ds = TIFFDataset(fnames,aggdim = "cols");
The band1 array is now twice as large:
size(ds["band1"])
(9600, 4800)
Make a virtual subset based on coordinate values using longitude (x) and latitude (y)
ds2 = @select(ds,-1 <= x <= 0.3 && 38.1 <= y <= 39.53);
Load all the data
band1 = ds2["band1"][:,:];
lon = ds2["lon"][:,:];
lat = ds2["lat"][:,:];
Extract the attribute "production date time" for the metadata
datetime = DateTime(ds.attrib["PRODUCTIONDATETIME"])
2024-11-02T01:34:18
Make a plot
title = "surface water " * Dates.format(datetime,"yyyy-mm-dd")
fig = Figure(size=(800,500));
ga = Axis(fig[1, 1]; title = title,
xlabel = "longitude",
ylabel = "latitude",
aspect = AxisAspect(1/cosd(mean(lat))))
xlims!(ga,extrema(lon))
ylims!(ga,extrema(lat))
s = surface!(ga,lon,lat,band1,
shading = NoShading,
colormap = cgrad(ColorScheme([colorant"sandybrown",
colorant"lightblue",
colorant"darkred",
colorant"red"]),
4, categorical = true),
colorrange = (-0.5, 3.5))
Colorbar(fig[1,2],s,ticks = 0:3)
fig
Load the "description"
attribute
println(ds.attrib["description"])
2 day flood pixels detected from Terra and Aqua
no clouds removed
terrain shadow pixels masked
HAND pixels masked
threshold from table, minimum of 2
Flag values:
255 : Insufficient data
0 : No water
1 : Water (matches standard reference water)
2 : Recurring flood (expected seasonal flood)
3 : Flood (unusual)