Examples
Simple Example Exporting a Single ee.Image
This example shows the a simple use case of EEDL. First, you must load in some data from Earth Engine. Next, create an eedl.image Image object, passing in the Earth Engine Data. Next, export the image(s). Finally, provide a path to download the results to.
import ee
from ee import ImageCollection
import eedl
from eedl.image import EEDLImage
def test_simple() -> None:
geometry = ee.FeatureCollection("users/nrsantos/vw_extraction_mask").geometry()
s2_image = ImageCollection("COPERNICUS/S2_SR_HARMONIZED").filterBounds(geometry).filterDate("2022-07-01", "2022-07-14").first().select(["B8", ])
# Adam, make sure to set the drive root folder for your own testing - we'll need to fix this, and in the future,
# we can use a Google Cloud bucket for most testing this is clunky - we should make the instantiation of the image be able to take a kwarg that sets the value of image, I think.
image = EEDLImage()
image.export(s2_image, "valley_water_s2_test_image", export_type="Drive", clip=geometry, drive_root_folder=r"G:\My Drive")
# We need to make it check and report whether the export on the EE side was successful. This test "passed" because Earth Engine failed and there wasn't anything to download (oops)
# Adam, make sure to set the folder you want results to be downloaded to
eedl.image.main_task_registry.wait_for_images(r"D:\ee_export_test", sleep_time=60, callback="mosaic")
Example Exporting Multiple Images
This example demonstrates a more complicated use case. In this example stuff happens.
import os
from typing import Iterable
import ee
from ee import ImageCollection
from eedl.image import EEDLImage
import eedl
ee.Initialize()
def scv_data_download_for_year(year: str, openet_collection: str = r"OpenET/ENSEMBLE/CONUS/GRIDMET/MONTHLY/v2_0", band: str = "et_ensemble_mad") -> Iterable[EEDLImage, EEDLImage]:
geometry = ee.FeatureCollection("users/nrsantos/vw_extraction_mask").geometry()
# so, we need two images per year - one is for all months, the other is for just the winter months
annual_collection = ImageCollection(openet_collection).filterBounds(geometry).filterDate(f"{year}-01-01", f"{year}-12-31").select(band)
# for the winter image, we need two date ranges within the same year - Jan-Mar and December. Do that by getting two separate collections and merging them
winter_collection = ImageCollection(openet_collection).filterBounds(geometry).filterDate(f"{year}-01-01", f"{year}-03-31") \
.merge(ImageCollection(openet_collection).filterBounds(geometry).filterDate(f"{year}-12-01", f"{year}-12-31")) \
.select(band)
# Earth Engine errors out if we try to sum the collections without converting the images into Doubles first, which is too bad because they'd be very efficient otherwise
annual_collection_doubles = annual_collection.map(lambda image: image.toDouble())
winter_collection_doubles = winter_collection.map(lambda image: image.toDouble())
# The docs note that the ET in this collection is "total ET by month as an equivalent depth of water in millimeters."
# so it's the mean of the models' depths for the whole month. We can sum those safely to get annual totals.
# now we need to flatten the collections into images we can export, so we'll sum the whole collections
annual_image = annual_collection_doubles.sum()
winter_image = winter_collection_doubles.sum()
# export the annual image and queue it for download
annual_export_image = EEDLImage(crs="EPSG:4326")
annual_export_image.export(annual_image,
filename_suffix=f"valley_water_ensemble_total_et_mm_{year}",
export_type="Drive",
drive_root_folder=r"G:\My Drive",
clip=geometry,
folder="vw_et_update_2023"
)
winter_export_image = EEDLImage(crs="EPSG:4326")
winter_export_image.export(winter_image,
filename_suffix=f"valley_water_ensemble_winter_et_mm_{year}",
export_type="Drive",
drive_root_folder=r"G:\My Drive",
clip=geometry,
folder="vw_et_update_2023"
)
return annual_export_image, winter_export_image
# return (annual_export_image, )
folder_path = os.path.dirname(os.path.abspath(__file__))
field_boundaries_by_year = {
"2018": os.path.join(folder_path, r"data\liq_field_centroids_by_year.gpkg\fields_liq_centroids_2018_wgs84"),
"2019": os.path.join(folder_path, r"data\liq_field_centroids_by_year.gpkg\fields_liq_centroids_2019_wgs84"),
"2020": os.path.join(folder_path, r"data\liq_field_centroids_by_year.gpkg\fields_liq_centroids_2020_wgs84")
}
def download_updated_vw_et_images_by_year(download_folder: str = r"D:\vw_et_update_2023",
field_boundaries: dict[str: str] = field_boundaries_by_year) -> None:
exports_by_year = {}
print("Running exports")
for year in ("2018", "2019", "2020"):
results = scv_data_download_for_year(year)
exports_by_year[year] = results
print("Waiting for downloads and mosaicking")
eedl.image.main_task_registry.wait_for_images(download_folder, sleep_time=60, callback="mosaic")
# now we need to run the zonal stats
print("Running Zonal Stats")
for year in exports_by_year:
for image in exports_by_year[year]:
image.zonal_stats(field_boundaries[year], keep_fields=("UniqueID", "CLASS2", "ACRES"), stats=(), use_points=True)
if __name__ == "__main__":
download_updated_vw_et_images_by_year()