Hoppa över navigering

MODIS

SatelliteImagery EarthObservation AIforEarth NASA USGS

Satellitbild från Moderate Resolution Imaging Spectroradiometer (MODIS).

MODIS skickar observationsdata till jorden i ett brett spektra, från 1999 fram till nutid. MODIS-satelliterna tar en bild på jorden varje eller varannan dag, även om separata produkter som härleds från MODIS-data kan ha lägre tidsmässig upplösning. MODIS administreras av National Aeronautics and Space Administration (NASA) och US Geological Survey (USGS). Vi speglar just nu MCD43A4 (500 m upplösning av global daglig ytreflektion) i Azure sedan 2000 och vi kommer att vara med när ytterligare MODIS-produkter ska väljas.

Lagringsresurser

Data lagras i blobbar i datacentret Östra USA, i följande blobcontainer:

https://modissa.blob.core.windows.net/modis

I containern organiseras datan efter:

[product]/[htile]/[vtile]/[daynum]/[filename]

product är MODIS-produktnamnet; för närvarande är MCD43A4 tillgängligt i Azure.

htile och vtile avser panelnummer i MODIS:s sinusformade rutnätssystem. I anteckningsboken under “Data Access” ser du hur du kan mappa latitud och longitud i rutnätssystemet.

daynum är ett 4-siffrigt årtal plus en 3-siffrig dag på året (från 001 till 365). 2019001 representerar exempelvis den 1 januari 2019.

…exempelvis innehåller mappen:

MCD43A4/00/08/2019010

…bilder från 10 januari 2019.

Bilderna lagras i GeoTIFF-format, med en bild per MODIS-kanal. Mappningen från kanaler till spektralband är produktspecifik. För MCD43A4 finns mappningarna här.

Enligt dokumentet motsvarar spektralband 1 kanal 7 för MCD43A4, så i ovanstående katalog kommer filen:

MCD43A4.A2019001.h00v08.006.2019010201703.hdf_07.tiff

…att innehålla information från spektralband 1.

Ett komplett Python-exempel som visar hur du kommer åt och ritar ut en MODIS-bild finns i anteckningsboken under “Data Access”.

Vi tillhandahåller också en skrivskyddad SAS-token (signatur för delad åtkomst) som ger åtkomst till MODIS-data via exempelvis BlobFuse, vilket innebär att du kan montera blobcontainrar som enheter:

st=2019-07-26T22%3A24%3A15Z&se=2032-07-27T22%3A24%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=ENT24qUY%2BlxL93XMykFQwfq4ctHDPLmYPDaaAn7YI3Q%3D

Monteringsanvisningarna för Linux finns här.

MODIS-data kan förbruka hundratals terabyte, så bearbetning i stor skala utförs bäst i Azures datacenter Östra USA där bilderna lagras. Om du använder MODIS-data i miljövetenskapsprogram, kan du ansöka om AI for Earth Grant som kan vara till hjälp vid dina beräkningar.

Fin bild


Bild av Chicagoområdet den 15 maj 2019.

Kontakt

Om du har frågor om den här datamängden är du välkommen att kontakta aiforearthdatasets@microsoft.com.

Meddelanden

MICROSOFT TILLHANDAHÅLLER AZURE OPEN DATASETS I BEFINTLIGT SKICK. MICROSOFT UTFÄRDAR INTE NÅGRA GARANTIER ELLER VILLKOR, UTTRYCKLIGA ELLER UNDERFÖRSTÅDDA, AVSEENDE ANVÄNDNINGEN AV DATAMÄNGDERNA. I DEN UTSTRÄCKNING DET ÄR TILLÅTET ENLIGT NATIONELL LAGSTIFTNING, FRISKRIVER MICROSOFT SIG FRÅN ALLT ANSVAR BETRÄFFANDE SKADOR OCH FÖRLUSTER, INKLUSIVE DIREKTA SKADOR, FÖLJDSKADOR, SÄRSKILDA SKADOR, INDIREKTA SKADOR, ELLER OFÖRUTSEDDA SKADOR FRÅN ANVÄNDNINGEN AV DATAMÄNGDERNA.

Datamängden tillhandahålls enligt de ursprungliga villkor som gällde när Microsoft tog emot källdatan. Datamängden kan innehålla data från Microsoft.

Access

Available inWhen to use
Azure Notebooks

Quickly explore the dataset with Jupyter notebooks hosted on Azure or your local machine.

Select your preferred service:

Azure Notebooks

Azure Notebooks

Package: Language: Python

Demo notebook for accessing MODIS data on Azure

This notebook provides an example of accessing MODIS data from blob storage on Azure, including (1) finding the MODIS tile corresponding to a lat/lon coordinate, (2) retrieving that tile from blob storage, and (3) displaying that tile using the rasterio library.

This notebook uses the MODIS surface reflectance product as an example, but data structure and access will be the same for other MODIS products.

MODIS data are stored in the East US data center, so this notebook will run most efficiently on Azure compute located in East US. We recommend that substantial computation depending on MODIS data also be situated in East US. You don't want to download hundreds of terabytes to your laptop! If you are using MODIS data for environmental science applications, consider applying for an AI for Earth grant to support your compute requirements.

Imports and environment

In [1]:
# Standard or standard-ish imports
import os
import tempfile
import numpy as np
import shutil
import urllib
import matplotlib.pyplot as plt

# Less standard, but still pip- or conda-installable
import rasterio

# pip install azure-storage-blob
from azure.storage.blob import ContainerClient

# Storage locations are documented at http://aka.ms/ai4edata-modis
modis_account_name = 'modissa'
modis_container_name = 'modis'
modis_account_url = 'https://' + modis_account_name + '.blob.core.windows.net/'
modis_blob_root = modis_account_url + modis_container_name

# Temporary folder for data we need during execution of this notebook (we'll clean up
# at the end, we promise)
temp_dir = os.path.join(tempfile.gettempdir(),'modis')
os.makedirs(temp_dir,exist_ok=True)

# This file is provided by NASA; it indicates the lat/lon extents of each
# MODIS tile.
#
# The file originally comes from:
#
# https://modis-land.gsfc.nasa.gov/pdf/sn_bound_10deg.txt
modis_tile_extents_url = modis_blob_root + '/sn_bound_10deg.txt'

# Load this file into a table, where each row is (v,h,lonmin,lonmax,latmin,latmax)
modis_tile_extents = np.genfromtxt(modis_tile_extents_url,
                     skip_header = 7, 
                     skip_footer = 3)

# Read-only shared access signature (SAS) URL for the MODIS container
modis_sas_token = 'st=2019-07-26T17%3A21%3A46Z&se=2029-07-27T17%3A21%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=1NpBV6P8SIibRcelWZyLCpIh4KFiqEzOipjKU5ZIRrQ%3D'

modis_container_client = ContainerClient(account_url=modis_account_url, 
                                         container_name=modis_container_name,
                                         credential=None)
                                
%matplotlib inline

Functions

In [2]:
def lat_lon_to_modis_tile(lat,lon):
    """
    Get the modis tile indices (h,v) for a given lat/lon
    
    https://www.earthdatascience.org/tutorials/convert-modis-tile-to-lat-lon/
    """
    
    found_matching_tile = False
    i = 0
    while(not found_matching_tile):
        found_matching_tile = lat >= modis_tile_extents[i, 4] \
        and lat <= modis_tile_extents[i, 5] \
        and lon >= modis_tile_extents[i, 2] and lon <= modis_tile_extents[i, 3]
        i += 1
        
    v = int(modis_tile_extents[i-1, 0])
    h = int(modis_tile_extents[i-1, 1])
    
    return h,v


def list_blobs_in_folder(container_name,folder_name):
    """
    List all blobs in a virtual folder in an Azure blob container
    """
    
    files = []
    generator = modis_container_client.list_blobs(name_starts_with=folder_name)
    for blob in generator:
        files.append(blob.name)
    return files
        
    
def list_tiff_blobs_in_folder(container_name,folder_name):
    """"
    List .tiff files in a folder
    """
    
    files = list_blobs_in_folder(container_name,folder_name)
    files = [fn for fn in files if fn.endswith('.tiff')]
    return files
             

def download_url(url, destination_filename=None, progress_updater=None, force_download=False):
    """
    Download a URL to a temporary file
    """
    
    # This is not intended to guarantee uniqueness, we just know it happens to guarantee
    # uniqueness for this application.
    if destination_filename is None:
        url_as_filename = url.replace('://', '_').replace('.', '_').replace('/', '_')
        destination_filename = \
            os.path.join(temp_dir,url_as_filename)
    if (not force_download) and (os.path.isfile(destination_filename)):
        print('Bypassing download of already-downloaded file {}'.format(os.path.basename(url)))
        return destination_filename
    print('Downloading file {}'.format(os.path.basename(url)),end='')
    urllib.request.urlretrieve(url, destination_filename, progress_updater)  
    assert(os.path.isfile(destination_filename))
    nBytes = os.path.getsize(destination_filename)
    print('...done, {} bytes.'.format(nBytes))
    return destination_filename

Access and plot a MODIS tile

In [3]:
# Files are stored according to:
#
# http://modissa.blob.core.windows.net/[product]/[htile]/[vtile]/[year][day]/filename

# Surface reflectance
product = 'MCD43A4'

# Let's look at the tile containing Chicago, IL, on May 15, 2019 (day of year 135)
h,v = lat_lon_to_modis_tile(41.881832,-87.623177)
daynum = '2019135'
folder = product + '/' + '{:0>2d}/{:0>2d}'.format(h,v) + '/' + daynum

# Find all .tiff files from this tile on this day, one file per channel
files = list_tiff_blobs_in_folder(modis_container_name,folder)

norm_value = 4000

# Channel 7 in a MCD43A4 file corresponds to MODIS band 1.  
#
# Let's map bands 1, 4, and 3 (channels 7,10,9) to RGB.
channels = [7,10,9]
image_data = []
for ifn in channels:
    remote_fn = files[ifn]
    url = modis_blob_root + '/' + remote_fn
    fn = download_url(url)
    raster = rasterio.open(fn,'r')
    band_array = raster.read(1)
    raster.close()
    band_array = band_array / norm_value
    image_data.append(band_array)
rgb = np.dstack((image_data[0],image_data[1],image_data[2]))
np.clip(rgb,0,1,rgb)
plt.imshow(rgb)
Downloading file MCD43A4.A2019135.h11v04.006.2019149220457.hdf_08.tiff...done, 11546274 bytes.
Downloading file MCD43A4.A2019135.h11v04.006.2019149220457.hdf_11.tiff...done, 11546274 bytes.
Downloading file MCD43A4.A2019135.h11v04.006.2019149220457.hdf_10.tiff...done, 11546274 bytes.
Out[3]:
<matplotlib.image.AxesImage at 0x223970bbc48>

Clean up temporary files

In [ ]:
shutil.rmtree(temp_dir)