Navigáció kihagyása

MODIS

SatelliteImagery EarthObservation AIforEarth NASA USGS

A Közepes Felbontású Képalkotó Spektroradiométer (MODIS) műholdas felvételei.

A MODIS 1999-től napjainkig közli a Föld megfigyeléséből származó többspektrumú adatokat. A MODIS műholdjai naponta vagy kétnaponta készítenek felvételeket a Földről, bár egyes termékekhez a MODIS ritkább időközöket is alkalmazhat. A MODIS rendszert a Nemzeti Repülési és Űrhajózási Hivatal (NASA) és az USA Geológiai Felmérési Hivatala (USGS) működteti. Jelenleg az Azure-on a MCD43A4 (500 m-es felbontású globális napi felszíntükröződés) terméket tükrözzük 2000-ig visszamenően, és a jövőben további válogatott MODIS-termékek felvételét is tervezzük.

Azure Storage-erőforrások

Az adatok tárolása blobokban, az USA keleti részén található adatközpontban, a következő blobtárolóban történik:

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

Ebben a tárolóban az adatok a következők szerint vannak rendszerezve:

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

A product a MODIS termékének neve; jelenleg az MCD43A4 érhető el az Azure-ban.

A htile és a vtile a MODIS szinuszos rácsrendszer csempeszámaira utal. A “Data Access” alatt elérhető jegyzetfüzet a hosszúság és a szélesség leképezésének egy módját szemlélteti ebben a rácsrendszerben.

A daynum egy négy számjegyből álló évszámot és egy három számjegyből álló napszámot tartalmaz (001-től 365-ig), a 2019001 például a 2019 január 1. dátumot jelenti.

…például a következő mappa:

MCD43A4/00/08/2019010

…a 2019. jan. 10. dátumú képeket tartalmazza.

A képek GeoTIFF formátumban vannak tárolva, MODIS-csatornánként egy képpel. A csatornák spektrális sávokhoz társítása termékfüggő; a MCD43A4 termékhez tartozó társítások itt érhetők el.

Mivel ennél a dokumentumnál az 1. spektrális sáv a MCD43A4 termék 7. csatornájának felel meg, a fenti címtárban a következő fájl:

MCD43A4.A2019001.h00v08.006.2019010201703.hdf_07.tiff

…az 1. spektrális sávból tartalmaz információkat.

Az egy MODIS-kép elérését és ábrázolását bemutató teljes Python-példa áll rendelkezésre az “adatelérés” szakaszban található jegyzetfüzetben.

Egy csak olvasható SAS-tokent is biztosítunk, amellyel például a BlobFuse szolgáltatáson keresztül hozzáférhet a MODIS-adatokhoz, és a blobtárolókat meghajtókként is csatlakoztathatja:

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

A csatlakoztatási útmutatót Linux rendszerhez itt olvashatja.

A MODIS-adatok több száz terabájtnyi helyet foglalhatnak el, ezért érdemes a nagyobb adatfeldolgozásokat az USA keleti részén található Azure-adatközpontban végezni, ahol a képek találhatók. Ha a MODIS-adatokat környezettudományi alkalmazásokhoz használja, igényeljen AI for Earth engedélyt számítógépes igényei támogatása érdekében.

Szép kép


Chicago környékét ábrázoló, 2019. május 15-én készült kép

Kapcsolattartó

Az ezzel az adatkészlettel kapcsolatos kérdéseket elküldheti az aiforearthdatasets@microsoft.com címre.

Értesítések

A MICROSOFT JELEN ÁLLAPOTUKBAN SZOLGÁLTATJA AZ AZURE NYÍLT ADATKÉSZLETEIT. A MICROSOFT NEM VÁLLAL SEMMINEMŰ KIFEJEZETT VAGY HALLGATÓLAGOS JÓTÁLLÁST AZ ADATKÉSZLETEK HASZNÁLATÁRA VONATKOZÓAN. A HELYI TÖRVÉNYEK ÁLTAL ENGEDETT MÉRTÉKBEN A MICROSOFT ELHÁRÍT MINDEN FELELŐSSÉGET AZ ADATKÉSZLETEK HASZNÁLATÁBÓL ADÓDÓ ESETLEGES KÁROKÉRT VAGY VESZTESÉGEKÉRT, BELEÉRTVE A KÖZVETLEN, KÖVETKEZMÉNYES, KÜLÖNLEGES, KÖZVETETT, VÉLETLEN VAGY BÜNTETÉSBŐL EREDŐ KÁROKAT.

Az adatkészletet a Microsoft forrásadataihoz tartozó eredeti feltételek szerint szolgáltatjuk. A készlet tartalmazhat Microsofttól származó adatokat.

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)