Create buffer around point location

import geopandas
import json
import shapely
import shapely.geometry
from shapely.ops import transform
from shapely.geometry import Point
from shapely.geometry import Polygon
import geoviews as gv
from pystac_client import Client  
import xarray
import rasterio as rio
import rioxarray
import os
gv.extension('bokeh', 'matplotlib')
lon = -84.0106
lat = 10.432
buffer = 0.001    # decimal degrees equal to ~222 meters
loc = Point(lon, lat).buffer(buffer)
type(loc)
shapely.geometry.polygon.Polygon
base = gv.tile_sources.EsriImagery.opts(width=650, height=500)
sample_loc = gv.Polygons(loc).opts(line_color='yellow', line_width=10, color=None)
base * sample_loc

Translate the shapely polygon to a GeoJSON Polygon Object, which is what the STAC API expects.

roi = json.loads(geopandas.GeoSeries([loc]).to_json())
roi
{'type': 'FeatureCollection',
 'features': [{'id': '0',
   'type': 'Feature',
   'properties': {},
   'geometry': {'type': 'Polygon',
    'coordinates': [[[-84.00959999999999, 10.432],
      [-84.00960481527332, 10.43190198285967],
      [-84.00961921471959, 10.431804909677984],
      [-84.00964305966427, 10.431709715322746],
      [-84.00967612046749, 10.431617316567635],
      [-84.00971807873565, 10.431528603263175],
      [-84.00976853038769, 10.43144442976698],
      [-84.00982698954664, 10.431365606715836],
      [-84.0098928932188, 10.431292893218814],
      [-84.00996560671584, 10.431226989546637],
      [-84.01004442976698, 10.431168530387698],
      [-84.01012860326317, 10.431118078735652],
      [-84.01021731656763, 10.43107612046749],
      [-84.01030971532275, 10.431043059664269],
      [-84.01040490967799, 10.431019214719598],
      [-84.01050198285967, 10.431004815273328],
      [-84.0106, 10.431000000000001],
      [-84.01069801714033, 10.431004815273328],
      [-84.010795090322, 10.431019214719598],
      [-84.01089028467725, 10.431043059664269],
      [-84.01098268343236, 10.43107612046749],
      [-84.01107139673682, 10.431118078735652],
      [-84.01115557023302, 10.431168530387698],
      [-84.01123439328416, 10.431226989546637],
      [-84.01130710678119, 10.431292893218814],
      [-84.01137301045335, 10.431365606715836],
      [-84.0114314696123, 10.43144442976698],
      [-84.01148192126435, 10.431528603263175],
      [-84.0115238795325, 10.431617316567635],
      [-84.01155694033572, 10.431709715322746],
      [-84.0115807852804, 10.431804909677984],
      [-84.01159518472667, 10.43190198285967],
      [-84.0116, 10.432],
      [-84.01159518472667, 10.43209801714033],
      [-84.0115807852804, 10.432195090322017],
      [-84.01155694033572, 10.432290284677254],
      [-84.0115238795325, 10.432382683432365],
      [-84.01148192126435, 10.432471396736826],
      [-84.0114314696123, 10.43255557023302],
      [-84.01137301045335, 10.432634393284165],
      [-84.01130710678119, 10.432707106781187],
      [-84.01123439328416, 10.432773010453364],
      [-84.01115557023302, 10.432831469612303],
      [-84.01107139673682, 10.432881921264348],
      [-84.01098268343236, 10.432923879532511],
      [-84.01089028467725, 10.432956940335732],
      [-84.010795090322, 10.432980785280403],
      [-84.01069801714033, 10.432995184726673],
      [-84.0106, 10.433],
      [-84.01050198285967, 10.432995184726673],
      [-84.01040490967799, 10.432980785280403],
      [-84.01030971532275, 10.432956940335732],
      [-84.01021731656763, 10.432923879532511],
      [-84.01012860326317, 10.432881921264348],
      [-84.01004442976698, 10.432831469612303],
      [-84.00996560671584, 10.432773010453364],
      [-84.0098928932188, 10.432707106781187],
      [-84.00982698954664, 10.432634393284165],
      [-84.00976853038769, 10.43255557023302],
      [-84.00971807873565, 10.432471396736826],
      [-84.00967612046749, 10.432382683432365],
      [-84.00964305966427, 10.432290284677254],
      [-84.00961921471959, 10.432195090322017],
      [-84.00960481527332, 10.43209801714033],
      [-84.00959999999999, 10.432]]]},
   'bbox': [-84.0116, 10.431000000000001, -84.00959999999999, 10.433]}],
 'bbox': [-84.0116, 10.431000000000001, -84.00959999999999, 10.433]}

GeoJSON Polygon Object vertices are expected to be in counterclockwise order. The current object vertices are in clockwise order. Below we reverse the order of the vertices and assign them back to our roi object.

roi['features'][0]['geometry']['coordinates'][0] = roi['features'][0]['geometry']['coordinates'][0][::-1]

Find data using the STAC API

Specify the STAC API endpoint

STAC_URL = 'https://cmr.earthdata.nasa.gov/stac'

Connect to the LPCLOUD catalog using PySTAC Client

catalog = Client.open(f'{STAC_URL}/LPCLOUD/')

Submit a query for: - HLSL30 and HLSS30 - The roi’s geometry - Dates between 05-01-2021 and 06-30-2022

search = catalog.search(
    collections = ['HLSL30.v2.0', 'HLSS30.v2.0'],
    intersects = roi['features'][0]['geometry'],
    datetime = '2021-05/2022-06'
)               
search.matched()
87

Get all the STAC Items/granules

items = search.get_all_items()
len(items)
87

Get the first STAC Item from the list and print off the available assets

items[0].assets
{'B07': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B07.tif>,
 'B01': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B01.tif>,
 'B04': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B04.tif>,
 'B06': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B06.tif>,
 'VZA': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.VZA.tif>,
 'Fmask': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.Fmask.tif>,
 'B02': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B02.tif>,
 'SAA': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.SAA.tif>,
 'B11': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B11.tif>,
 'B03': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B03.tif>,
 'VAA': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.VAA.tif>,
 'B10': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B10.tif>,
 'B05': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B05.tif>,
 'B09': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B09.tif>,
 'SZA': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.SZA.tif>,
 'browse': <Asset href=https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-public/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.jpg>,
 'metadata': <Asset href=https://cmr.earthdata.nasa.gov/search/concepts/G2144745416-LPCLOUD.xml>}

Grab the URL for the B04 asset

data_url = items[0].assets['B04'].href
data_url
'https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/HLSL30.020/HLS.L30.T16PHS.2021133T155359.v2.0/HLS.L30.T16PHS.2021133T155359.v2.0.B04.tif'

NOTE: The above returns the HTTPS URL. For direct S3 access of cloud assets the S3 URL is need. See the following resource on how to generate the S3 URL: https://nasa-openscapes.github.io/2021-Cloud-Hackathon/tutorials/02_Data_Discovery_CMR-STAC_API.html

Read in the URL using rioxarray

NOTE: The example below show how to access the asset via HTTPS. An example for performing direct S3 access can be found here: https://nasa-openscapes.github.io/2021-Cloud-Hackathon/tutorials/05_Data_Access_Direct_S3.html

First we need to set our gdal configs. Make sure a .netrc file has been created in your home directory

rio_env = rio.Env(GDAL_DISABLE_READDIR_ON_OPEN='EMPTY',
                  GDAL_HTTP_COOKIEFILE=os.path.expanduser('~/cookies.txt'),
                  GDAL_HTTP_COOKIEJAR=os.path.expanduser('~/cookies.txt'))
rio_env.__enter__()
<rasterio.env.Env at 0x7f846be57f70>
da = rioxarray.open_rasterio(data_url)
da
<xarray.DataArray (band: 1, y: 3660, x: 3660)>
[13395600 values with dtype=int16]
Coordinates:
  * band         (band) int64 1
  * x            (x) float64 8e+05 8e+05 8.001e+05 ... 9.097e+05 9.098e+05
  * y            (y) float64 1.2e+06 1.2e+06 1.2e+06 ... 1.09e+06 1.09e+06
    spatial_ref  int64 0
Attributes:
    _FillValue:    -9999.0
    scale_factor:  0.0001
    add_offset:    0.0
    long_name:     Red

Drop the ‘band’ coordinate

da.squeeze('band', drop=True)
<xarray.DataArray (y: 3660, x: 3660)>
[13395600 values with dtype=int16]
Coordinates:
  * x            (x) float64 8e+05 8e+05 8.001e+05 ... 9.097e+05 9.098e+05
  * y            (y) float64 1.2e+06 1.2e+06 1.2e+06 ... 1.09e+06 1.09e+06
    spatial_ref  int64 0
Attributes:
    _FillValue:    -9999.0
    scale_factor:  0.0001
    add_offset:    0.0
    long_name:     Red