Spring over navigation

MODIS

SatelliteImagery EarthObservation AIforEarth NASA USGS

Satellitbilleder fra MODIS (Moderate Resolution Imaging Spectroradiometer).

MODIS leverer observationsdata fra jorden i et bredt spektralområde fra 1999 og frem til i dag. MODIS-satellitterne tager billeder af jorden hver dag eller hver anden dag, selvom de enkelte produkter fra MODIS-data kan have lavere tidsmæssige opløsninger. MODIS administreres af NASA (National Aeronautics and Space Administration) og USGS (US Geological Survey). Vi viser i øjeblikket MCD43A4-produktet (global daglig overfladereflektans i 500-meters opløsning) i Azure tilbage fra 2000, og vi inkluderer snart ekstra udvalgte MODIS-produkter.

Lagringsressourcer

Data lagres i blobs i datacenteret i det østlige USA i den følgende blobobjektbeholder:

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

I denne objektbeholder er dataene organiseret i henhold til:

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

product er MODIS-produktnavnet. I øjeblikket er MCD43A4 tilgængeligt i Azure.

htile og vtile refererer til feltnumrene i MODIS’ sinusformede kvadratnetsystem. Den notesbog, der er tilgængelig under “Dataadgang”, viser en metode til at kortlægge breddegrad og længdegrad i dette kvadratnetsystem.

daynum er et firecifret årstal og et trecifret dagsnummer (fra 001 til 365), 1, 2019001 f.eks. den 1. januar 2019.

Mappen:

MCD43A4/00/08/2019010

… indeholder f.eks. billeder fra den 10. januar 2019.

Billederne er lagret i GeoTIFF-formatet med ét billede pr. MODIS-kanal. Tilknytningen fra kanaler til spektralbånd er produktspecifik. Du kan finde tilknytninger for MCD43A4 her.

I henhold til dette dokument svarer spektralbånd 1 til kanal 7 for MCD43A4. I ovenstående mappe indeholder filen:

MCD43A4.A2019001.h00v08.006.2019010201703.hdf_07.tiff

… derfor oplysninger fra spektralbånd 1.

Et komplet Python-eksempel på adgang til og afbildning af en MODIS-afbildning er tilgængelig i notesbogen under “dataadgang”.

Vi stiller også et skrivebeskyttet SAS-token (token til delt adgang) til rådighed for at give adgang til MODIS-data via f.eks. BlobFuse, som gør det muligt at indsætte blobobjektbeholdere som drev:

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

Du kan få instruktioner i indsættelsen for Linux her.

MODIS-data kan forbruge hundredvis af terabyte, hvorfor behandling i stor skala udføres bedst i datacenteret i det østlige USA, hvor billederne opbevares. Hvis du bruger MODIS-data til miljømæssige videnskabelige formål, kan du overveje at ansøge om et AI for Earth-tilskud som støtte til dine beregningsbehov.

Betagende billede


Afbildning af Chicago-området den 15. maj 2019.

Kontakt

Hvis du har spørgsmål vedrørende dette datasæt, kan du kontakte aiforearthdatasets@microsoft.com.

Meddelelser

MICROSOFT STILLER AZURE OPEN DATASETS TIL RÅDIGHED, SOM DE ER OG FOREFINDES. MICROSOFT FRASKRIVER SIG ETHVERT ANSVAR, UDTRYKKELIGT ELLER STILTIENDE, OG GARANTIER ELLER BETINGELSER MED HENSYN TIL BRUGEN AF DATASÆTTENE. I DET OMFANG DET ER TILLADT I HENHOLD TIL GÆLDENDE LOVGIVNING FRASKRIVER MICROSOFT SIG ETHVERT ANSVAR FOR SKADER ELLER TAB, INKLUSIVE DIREKTE, FØLGESKADER, SÆRLIGE SKADER, INDIREKTE SKADER, HÆNDELIGE SKADER ELLER PONALE SKADER, DER MÅTTE OPSTÅ I FORBINDELSE MED BRUG AF DATASÆTTENE.

Dette datasæt stilles til rådighed under de oprindelige vilkår, som Microsoft modtog kildedataene under. Datasættet kan indeholde data fra 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)