Coverage for cedar/sensors/landsat.py : 32%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Functions for dealing with Landsat data on GEE """
# Renaming stuff 'swir1', 'swir2', 'thermal', 'pixel_qa']
'COMMON': BANDS_COMMON, 'LANDSAT/LT04/C01/T1_SR': BANDS_LT4, 'LANDSAT/LT05/C01/T1_SR': BANDS_LT5, 'LANDSAT/LE07/C01/T1_SR': BANDS_LE7, 'LANDSAT/LC08/C01/T1_SR': BANDS_LC8, }
#: dict[str, Number]: NoDataValues for Landsat collections 'LANDSAT/LT04/C01/T1_SR': -9999, 'LANDSAT/LT05/C01/T1_SR': -9999, 'LANDSAT/LE07/C01/T1_SR': -9999, 'LANDSAT/LC08/C01/T1_SR': -9999, }
'CLOUD_COVER', 'CLOUD_COVER_LAND', 'EARTH_SUN_DISTANCE', 'ESPA_VERSION', 'GEOMETRIC_RMSE_MODEL', 'GEOMETRIC_RMSE_MODEL_X', 'GEOMETRIC_RMSE_MODEL_Y', 'LANDSAT_ID', 'LEVEL1_PRODUCTION_DATE', 'SATELLITE', 'SENSING_TIME', 'SOLAR_AZIMUTH_ANGLE', 'SOLAR_ZENITH_ANGLE', 'SR_APP_VERSION', 'WRS_PATH', 'WRS_ROW', 'system:id', 'system:time_start', 'system:version' ] 'LANDSAT/LT04/C01/T1_SR': _T1_SR_METADATA + _T1_SR_METADATA_LT04, 'LANDSAT/LT05/C01/T1_SR': _T1_SR_METADATA + _T1_SR_METADATA_LT05, 'LANDSAT/LE07/C01/T1_SR': _T1_SR_METADATA + _T1_SR_METADATA_LE07, 'LANDSAT/LC08/C01/T1_SR': _T1_SR_METADATA + _T1_SR_METADATA_LC08, }
validate=False): """ Create an ARD :py:class:`ee.Image`
Parameters ---------- collection : str GEE image collection name tile : stems.gis.grids.Tile STEMS TileGrid tile date_start : dt.datetime Starting period date_end : dt.datetime Ending period filters : Sequence[ee.Filter], optional Additional filters to apply over image collection validate : bool, optional Perform validity checks at cost of submission speed (runs ``.getInfo`` on metadata, requiring us to wait on client-server communication)
Returns ------- ee.Image "ARD" image from collection with all observations within period Sequence[dict] Metadata, one dict per image """ # TODO: convert system:time_start to datetime/strftime assert isinstance(date_start, dt.datetime) assert isinstance(date_end, dt.datetime)
# Get collection if isinstance(collection, ee.ImageCollection): imgcol = collection collection = imgcol.get('system:id').getInfo() else: imgcol = ee.ImageCollection(collection)
if not collection in BANDS.keys(): raise KeyError(f'Image collection "{collection}" is unsupported')
# Find images in tile imgcol = common.filter_collection_tile(imgcol, tile)
# For each unique date of imagery in this image collection covering the tile imgcol = common.filter_collection_time(imgcol, date_start, date_end)
# Apply additional filters if filters: logger.debug(f'Applying {len(filters)} filters over collection') imgcol = imgcol.filter(filters)
# Select and rename bands # TODO: specify what bands get ordered band_names = BANDS['COMMON'] imgcol = imgcol.select(BANDS[collection], band_names)
# Find number of unique observations (or, uniquely dated) imgcol_udates = common.get_collection_uniq_dates(imgcol) n_images = len(imgcol_udates) if n_images == 0: warnings.warn(f'Found 0 images for "{collection}" between ' f'{date_start}-{date_end}')
# Loop over unique dates, making mosaics to eliminate north/south if needed logger.debug(f'Creating ARD for {n_images} images') prepped = [] for udate in sorted(imgcol_udates): # Prepare and get metadata for unique date img, meta = _prep_collection_image(imgcol, collection, udate, validate=validate) # Add image and metadata prepped.append((img, meta))
# Unpack if prepped: images, image_metadata = list(zip(*prepped)) else: images, image_metadata = [], []
# Re-create as collection and turn to bands (n_image x bands_per_image) tile_col = ee.ImageCollection.fromImages(images) tile_bands = tile_col.toBands().toInt16()
# Remove mask nodata = NODATA[collection] tile_bands_unmasked = tile_bands.unmask(nodata)
# Get all image metadata at once (saves time back and forth) images_metadata_ = list(ee.List(image_metadata).getInfo())
# Create overall metadata metadata = { 'bands': band_names, 'nodata': nodata, 'images': images_metadata_ }
return tile_bands_unmasked, metadata
""" Return metadata for Landsat image collection """ def inner(img, previous): meta = common.object_metadata(img, keys) previous_ = ee.List(previous) return ee.List(previous_.add(meta))
meta = imgcol.iterate(inner, ee.List([])) return meta
""" Prepare an image for and ``date`` from an ImageCollection """ # Filter for this date (day <-> day+1) date_end = (date + dt.timedelta(days=1)) imgcol_ = common.filter_collection_time(imgcol, date, date_end)
if validate: # Check to make sure just 1 unique date _ = common.get_collection_uniq_dates(imgcol_) assert len(_) == 1
# Prepare all images in this collection (i.e., 1 or 2, depending on overlap) img = imgcol_.mosaic()
# Get metadata from each image in new, potentially mosaiced ``img`` keys = METADATA[collection] meta = _imgcol_metadata(imgcol_, keys)
return img, meta |