Query a spatial mosaic from the Google Earth Engine¶
- Last Modified: 3-12-2024
- Author: Gonzalo Mateo-García
This tutorial shows how to use the georeaders.readers.ee_image
module to download an spatial composite with Sentinel-2 or Landsat.
from shapely.geometry import shape, mapping
from datetime import datetime, timedelta
import ee
ee.Authenticate()
ee.Initialize()
footprint = shape({'type': 'Polygon',
'coordinates': (((58.21132510761841, 40.391771861041725),
(58.205632677871314, 40.07155762141618),
(58.649475248490724, 40.06608738064447),
(58.65726127535553, 40.38623968067468),
(58.21132510761841, 40.391771861041725)),)})
date_search = datetime.fromisoformat("2024-10-09T06:54:26+00:00")
date_search
Earth Engine code adapted from This blog post.
s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED')
ROI = ee.Geometry(mapping(footprint))
# ROI = ee.Geometry.Point(-119.9087, 37.4159)
QA_BAND = 'cs'
CLEAR_THRESHOLD = 0.60
date_search_min = date_search - timedelta(days=30)
date_search_max = date_search + timedelta(days=30)
composite = s2.filterBounds(ROI)\
.filterDate(date_search_min.strftime('%Y-%m-%d'), date_search_max.strftime('%Y-%m-%d'))\
.linkCollection(csPlus, [QA_BAND])\
.map(lambda img: img.updateMask(img.select(QA_BAND).gte(CLEAR_THRESHOLD)))\
.median()
composite
from georeader import get_utm_epsg
from georeader import window_utils
crs_utm = get_utm_epsg(footprint)
footprint_utm = window_utils.polygon_to_crs(footprint, "EPSG:4326", crs_utm)
transform = window_utils.figure_out_transform(bounds=footprint_utm.bounds, resolution_dst=30)
transform
%%time
from georeader.readers import ee_image
import numpy as np
mosaic = ee_image.export_image(composite, footprint, transform=transform, crs=crs_utm,
bands_gee=["B4","B3","B2"])
mosaic
from georeader import plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1, figsize=(8,8))
mosaic = mosaic.pad({"x": (5,5), "y": (5,5)})
mosaic_rgb = (mosaic / 5_500).clip(0,1)
plot.show(mosaic_rgb, ax=ax)
plot.add_shape_to_plot(footprint, ax=ax, crs_plot=mosaic_rgb.crs, polygon_no_fill=True, crs_shape="EPSG:4326",
kwargs_geopandas_plot={"color":"red"})
Composite for Landsat-8 and 9¶
Earth Engine code adapted from This blog post.
# https://medium.com/@nst11/annual-landsat-cloud-free-composite-in-google-earth-engine-c623b69749f7
def maskL8KH(image):
# Bits 3 and 5 are cloud shadow and cloud, respectively.
cloudShadowBitMask = (1 << 3)
cloudsBitMask = (1 << 5)
# Get the pixel QA band.
qa = image.select('QA_PIXEL')
# Both flags should be set to zero, indicating clear conditions.
mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0).And(qa.bitwiseAnd(cloudsBitMask).eq(0))
return image.updateMask(mask)
cols = ["LANDSAT/LC09/C02/T1_TOA", "LANDSAT/LC08/C02/T1_RT_TOA", "LANDSAT/LC08/C02/T2_TOA","LANDSAT/LC09/C02/T2_TOA"]
l89col = ee.ImageCollection(cols[0])
for c in cols[1:]:
l89col.merge(ee.ImageCollection(c))
ROI = ee.Geometry(mapping(footprint))
# ROI = ee.Geometry.Point(-119.9087, 37.4159)
date_search_min = date_search - timedelta(days=30)
date_search_max = date_search + timedelta(days=30)
composite_l8 = l89col.filterBounds(ROI)\
.filterDate(date_search_min.strftime('%Y-%m-%d'), date_search_max.strftime('%Y-%m-%d'))\
.map(lambda img: maskL8KH(img))\
.median()
composite_l8
%%time
mosaic_l8 = ee_image.export_image(composite, footprint, transform=transform, crs=crs_utm,
bands_gee=["B4","B3","B2"])
mosaic_l8
fig, ax = plt.subplots(1,1, figsize=(8,8))
mosaic_l8 = mosaic_l8.pad({"x": (5,5), "y": (5,5)})
mosaic_l8_rgb = (mosaic_l8 / 5_500).clip(0,1)
plot.show(mosaic_l8_rgb, ax=ax)
plot.add_shape_to_plot(footprint, ax=ax, crs_plot=mosaic_l8_rgb.crs, polygon_no_fill=True, crs_shape="EPSG:4326",
kwargs_geopandas_plot={"color":"red"})