탐색 건너뛰기

Harmonized Landsat Sentinel-2

SatelliteImagery EarthObservation AIforEarth NASA ESA

북아메리카 Landsat-8 및 Sentinel-2 위성의 위성 이미지입니다.

HLS(Harmonized Landsat Sentinel-2) 제품에는 Landsat의 경우 2013년부터 현재까지, Sentinel-2의 경우 2015년부터 현재까지 30m 해상도로 일반적인 타일링 시스템에 맞춰 조정된 Landsat-8 및 Sentinel-2 위성의 데이터가 포함됩니다. HLS는 NASA(미국 항공 우주국)에서 관리합니다.

이 데이터 세트는 Ag-Analytics®에서 유지 관리합니다. 또한 Ag-Analytics®는 AOI(관심 영역) 다각형, 날짜 범위 및 기타 옵션을 허용하는 API를 제공하며 Normalized Difference Vegetation Index 및 기타 메트릭뿐만 아니라 개별 MSI 밴드에 대해 처리된 이미지와 클라우드 필터링 모자이크를 반환합니다.

이 데이터 세트는 매주 업데이트됩니다.

스토리지 리소스

데이터는 미국 동부 2 데이터 센터에 있는 다음 Blob 컨테이너의 Blob에 저장됩니다.

https://hlssa.blob.core.windows.net/hls

해당 컨테이너 내에서 데이터는 다음에 따라 정리됩니다.

<folder>/HLS.<product>.T<tileid>.<daynum>.<version>_<subdataset>.tif

  • folder는 Landsat의 경우 L309이고 Sentinel-2의 경우 S309입니다.
  • product는 Landsat의 경우 L30이고 Sentinel-2의 경우 S30입니다.
  • tileidSentinel-2 타일링 시스템의 4자 타일 코드입니다.
  • daynum은 4자리 연도와 1년 중의 3자리 날 수(001~365)입니다. 예를 들어 2019001은 2019년 1월 1일을 나타냅니다.
  • version는 항상 v1.4입니다.
  • subdataset는 2자이며, 1로 인덱싱된 문자열은 하위 데이터 세트를 나타냅니다(아래 참조).

위도/경도에서 타일 ID로의 매핑은 여기에서 확인할 수 있습니다. “데이터 액세스” 아래에서 제공되는 Notebook은 이 표를 사용하여 위도/경도별로 타일 ID를 조회하는 방법을 보여 줍니다. 타일 ID는 Ag-Analytics® API를 사용하여 찾을 수도 있습니다.

데이터는 다음과 같은 기본 타일에 대해 제공됩니다.

[‘10 U’,‘11 U’,‘12 U’,‘13 U’,‘14 U’,‘15 U’,‘16 U’,‘10 T’,‘11 T’,‘12 T’,‘13 T’,‘14 T’,‘15 T’,‘16 T’,‘17 T’,‘18 T’,‘19 T’,‘10 S’,‘11 S’,‘12 S’,‘13 S’,‘14 S’,‘15 S’,‘16 S’,‘17 S’,‘18 S’,‘12 R’,‘13 R’,‘14 R’,‘15 R’,‘16 R’,‘17 R’]

밴드는 다음과 같습니다.

밴드 이름 OLI 밴드 번호 MSI 밴드 번호 L30 subdatasetnumber S30 subdatasetnumber
해안선 1 1 01 01
파랑 2 2 02 02
녹색 3 3 03 03
빨간색 4 4 04 04
빨간색 가장자리 1 5 05
빨간색 가장자리 2 6 06
빨간색 가장자리 3 7 07
넓은 NIR 8 08
좁은 NIR 5 8A 05 09
SWIR 1 6 11 06 10
SWIR 2 7 12 07 11
수증기 9 12
권운 9 10 08 13
열적외선 1 10 09
열적외선 2 11 10
QA 11 14

예를 들어 HLS.S30.T16TDL.2019206.v1.4_01.tif 파일 이름은 https://hlssa.blob.core.windows.net/hls/S309/HLS.S30.T16TDL.2019206.v1.4_03.tif 에 있으며, 2019년 206번째 날에 대한 데이터 세트 밴드 03(MSI 밴드 3, 녹색)에 대해 타일 16TDL(기본 타일 16T, 하위 타일 DL)의 Sentinel-2(S30) HLS 데이터를 나타냅니다.

또한 Blob 컨테이너를 드라이브로 탑재할 수 있게 해주는 BlobFuse 등을 통해 HLS 데이터에 액세스할 수 있는 읽기 전용 SAS(공유 액세스 서명) 토큰을 제공합니다.

st=2019-08-07T14%3A54%3A43Z&se=2050-08-08T14%3A54%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=EYNJCexDl5yxb1TxNH%2FzILznc3TiAnJq%2FPvCumkuV5U%3D

Linux용 탑재 지침은 여기에 있습니다.

HLS 데이터는 수백 테라바이트를 소비할 수 있으므로 대규모 처리는 이미지가 저장된 미국 동부 2 Azure 데이터 센터에서 최상으로 수행됩니다. 환경 과학 응용 분야에 HLS 데이터를 사용 중인 경우 컴퓨팅 요구 사항을 지원하려면 지구환경 AI(AI for Earth) 보조금 신청을 고려해 보세요.

연락처

이 데이터 세트에 대한 질문이 있는 경우 aiforearthdatasets@microsoft.com으로 문의하세요.

알림

Microsoft는 Azure Open Datasets를 “있는 그대로” 제공합니다. Microsoft는 귀하의 데이터 세트 사용과 관련하여 어떠한 명시적이거나 묵시적인 보증, 보장 또는 조건을 제공하지 않습니다. 귀하가 거주하는 지역의 법규가 허용하는 범위 내에서 Microsoft는 귀하의 데이터 세트 사용으로 인해 발생하는 일체의 직접적, 결과적, 특별, 간접적, 부수적 또는 징벌적 손해 또는 손실을 비롯한 모든 손해 또는 손실에 대한 모든 책임을 부인합니다.

이 데이터 세트는 Microsoft가 원본 데이터를 받은 원래 사용 약관에 따라 제공됩니다. 데이터 세트에는 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 HLS data on Azure

This notebook provides an example of accessing HLS (Harmonized Landsat Sentinel-2) data from blob storage on Azure, extracting image metadata using GDAL, and displaying an image using GDAL and rasterio.

HLS data are stored in the East US 2 data center, so this notebook will run more efficiently on the Azure compute located in East US 2. You don't want to download hundreds of terabytes to your laptop! If you are using HLS data for environmental science applications, consider applying for an AI for Earth grant to support your compute requirements.

HLS data on Azure are managed by Ag-Analytics. Ag-Analytics also provides an API which allows the caller to query to perform spatial queries over the HLS archive, as well as querying for additional data such as cloud cover and Normalized Difference Vegetation Index (NDVI). Ag-Analytics also provides an API to retrieve tile IDs matching spatial queries.

Imports and environment

In [2]:
# Standard-ish packages
import requests
import re
import numpy as np
import urllib
import io
import matplotlib.pyplot as plt
import pandas as pd

# Less standard, but all of the following are pip- or conda-installable
import rasterio

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

from osgeo import gdal,osr

# Storage locations are documented at http://aka.ms/ai4edata-hls
hls_container_name = 'hls'
hls_account_name = 'hlssa'
hls_account_url = 'https://' + hls_account_name + '.blob.core.windows.net/'
hls_blob_root = hls_account_url + hls_container_name

# This file is provided by NASA; it indicates the lat/lon extents of each
# hls tile.
#
# The file originally comes from:
#
# https://hls.gsfc.nasa.gov/wp-content/uploads/2016/10/S2_TilingSystem2-1.txt
#
# ...but as of 8/2019, there is a bug with the column names in the original file, so we
# access a copy with corrected column names.
hls_tile_extents_url = 'https://ai4edatasetspublicassets.blob.core.windows.net/assets/S2_TilingSystem2-1.txt?st=2019-08-23T03%3A25%3A57Z&se=2028-08-24T03%3A25%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=KHNZHIJuVG2KqwpnlsJ8truIT5saih8KrVj3f45ABKY%3D'

# Load this file into a table, where each row is:
#
# Tile ID, Xstart, Ystart, UZ, EPSG, MinLon, MaxLon, MinLon, MaxLon
print('Reading tile extents...')
s = requests.get(hls_tile_extents_url).content
hls_tile_extents = pd.read_csv(io.StringIO(s.decode('utf-8')),delimiter=r'\s+')
print('Read tile extents for {} tiles'.format(len(hls_tile_extents)))

# Read-only shared access signature (SAS) URL for the hls container
hls_sas_token = 'st=2019-08-07T14%3A54%3A43Z&se=2050-08-08T14%3A54%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=EYNJCexDl5yxb1TxNH%2FzILznc3TiAnJq%2FPvCumkuV5U%3D'

hls_container_client = ContainerClient(account_url=hls_account_url, 
                                         container_name=hls_container_name,
                                         credential=None)
                                

%matplotlib inline
Reading tile extents...
Read tile extents for 56686 tiles

Functions

In [3]:
def get_hls_tile(blob_url):
    """
    Given a URL pointing to an HLS image in blob storage, load that image via GDAL
    and return both data and metadata.
    """    
    
    formatted_gdal_bloburl='/{}/{}'.format('vsicurl',blob_url)
    
    tile_open = gdal.Open(formatted_gdal_bloburl)
    data = tile_open.GetRasterBand(1)
    ndv,xsize,ysize = data.GetNoDataValue(),tile_open.RasterXSize,tile_open.RasterYSize
    
    projection = osr.SpatialReference()
    projection.ImportFromWkt(tile_open.GetProjectionRef())
    
    datatype = data.DataType
    datatype = gdal.GetDataTypeName(datatype)  
    data_array = data.ReadAsArray()

    return ndv,xsize,ysize,projection,data_array


def list_available_tiles(prefix):
    """
    List all blobs in an Azure blob container matching a prefix.  
    
    We'll use this to query tiles by location and year.
    """
    
    files = []
    generator = hls_container_client.list_blobs(name_starts_with=prefix)
    for blob in generator:
        files.append(blob.name)
    return files

    
def lat_lon_to_hls_tile_id(lat,lon):
    """
    Get the hls tile ID for a given lat/lon coordinate pair
    """  
    
    found_matching_tile = False

    for i_row,row in hls_tile_extents.iterrows():
        found_matching_tile = lat >= row.MinLat and lat <= row.MaxLat \
        and lon >= row.MinLon and lon <= row.MaxLon
        if found_matching_tile:
            break
    
    if not found_matching_tile:
        return None
    else:
        return row.TilID

Find a tile for a given location and date

In [4]:
# Specify a location and year of interest
lat = 47.6101; lon = -122.2015 # Bellevue, WA

year = '2019'
daynum = '109'    # 1-indexed day-of-year
folder = 'S309'   # 'S309' for Sentinel, 'L309' for Landsat
product = 'S30'   # 'S30' for Sentinel, 'L30' for Landsat
year = '2019'

tile_id = lat_lon_to_hls_tile_id(lat,lon)
assert tile_id is not None, 'Invalid lat/lon'
prefix = folder + '/HLS.' + product + '.T' + tile_id + '.' + year

print('Finding tiles with prefix {}'.format(prefix))
matches = list_available_tiles(prefix)
assert len(matches) > 0, 'No matching tiles'

blob_name = matches[0]
print('Found {} matching tiles, using file {}'.format(len(matches),blob_name))
Finding tiles with prefix S309/HLS.S30.T10TET.2019
Found 1918 matching tiles, using file S309/HLS.S30.T10TET.2019001.v1.4_01.tif

...or build a tile path from components

In [5]:
lat = 47.6101; lon = -122.2015 # Bellevue, WA

year    = '2019'
daynum  = '001'   # 1-indexed day-of-year
folder  = 'S309'  # 'S309' for Sentinel, 'L309' for Landsat
product = 'S30'   # 'S30' for Sentinel, 'L30' for Landsat
band    = '01'
tile_id = '10TET' # See hls.gsfc.nasa.gov/wp-content/uploads/2016/10/S2_TilingSystem2-1.txt
version = 'v1.4'  # Currently always v1.4

blob_name = folder + '/HLS.' + product + '.T' + tile_id + '.' + year + daynum + '.' + version \
    + '_' + band + '.tif'

print('Using file {}'.format(blob_name))
Using file S309/HLS.S30.T10TET.2019001.v1.4_01.tif

Access one band of the selected image using GDAL's virtual file system (vsicurl)

In [6]:
gdal.SetConfigOption('GDAL_HTTP_UNSAFESSL', 'YES')
blob_url = hls_blob_root + '/' + blob_name
print('Reading tile from {}'.format(blob_url))
ndv,xsize,ysize,projection,data_array = get_hls_tile(blob_url)

print('No-data value: {}'.format(ndv))
print('\nSize: {},{}'.format(xsize,ysize))
print('\nProjection:\n{}'.format(projection))
Reading tile from https://hlssa.blob.core.windows.net/hls/S309/HLS.S30.T10TET.2019001.v1.4_01.tif
No-data value: -1000.0

Size: 3660,3660

Projection:
PROJCS["UTM Zone 10, Northern Hemisphere",
    GEOGCS["Unknown datum based upon the WGS 84 ellipsoid",
        DATUM["Not_specified_based_on_WGS_84_spheroid",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-123],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]

Display a Sentinel-2 image using rasterio and vsicurl

In [7]:
# Bands 2, 3, and 4 are B, G, and R in Sentinel-2 HLS images

base_url = '/vsicurl/' + hls_blob_root + '/' + blob_name
band2_url = re.sub('_(\d+).tif','_02.tif',base_url)
band3_url = re.sub('_(\d+).tif','_03.tif',base_url)
band4_url = re.sub('_(\d+).tif','_04.tif',base_url)
print('Reading bands from:\n{}\n{}\n{}'.format(band2_url,band3_url,band4_url))

band2 = rasterio.open(band2_url)
band3 = rasterio.open(band3_url)
band4 = rasterio.open(band4_url)

norm_value = 2000
image_data = []
for band in [band4,band3,band2]:
    band_array = band.read(1)
    band_array = band_array / norm_value
    image_data.append(band_array)
    band.close()

rgb = np.dstack((image_data[0],image_data[1],image_data[2]))
np.clip(rgb,0,1,rgb)
plt.imshow(rgb)
Reading bands from:
/vsicurl/https://hlssa.blob.core.windows.net/hls/S309/HLS.S30.T10TET.2019001.v1.4_02.tif
/vsicurl/https://hlssa.blob.core.windows.net/hls/S309/HLS.S30.T10TET.2019001.v1.4_03.tif
/vsicurl/https://hlssa.blob.core.windows.net/hls/S309/HLS.S30.T10TET.2019001.v1.4_04.tif
Out[7]:
<matplotlib.image.AxesImage at 0x2249d8e6f48>