A Python package that extends Google Earth Engine
Google Earth Engine is a cloud-based service for geospatial processing of vector and raster data. The Earth Engine platform has a JavaScript and a Python API with different methods to process geospatial objects. Google Earth Engine also provides a HUGE PETABYTE-SCALE CATALOG of raster and vector data that users can process online (e.g. Landsat Missions Image Collections, Sentinel Missions Image Collections, MODIS Products Image Collections, World Database of Protected Areas, etc.). The eemont package extends the Google Earth Engine Python API with pre-processing and processing tools for the most used satellite platforms by adding utility methods for different Earth Engine Objects that are friendly with the Python method chaining.
The eemont python package extends the following Earth Engine classes:
New utility methods and constructors are added to above-mentioned classes in order to create a more fluid code by being friendly with the Python method chaining. These methods are mandatory for some pre-processing and processing tasks (e.g. clouds masking, shadows masking, image scaling, spectral indices computation, etc.), and they are presented as simple functions that give researchers, students and analysts the chance to analyze data with far fewer lines of code.
Look at this simple example where a Sentinel-2 Surface Reflectance Image Collection is pre-processed and processed in just one step:
import ee, eemont
ee.Authenticate()
ee.Initialize()
point = ee.Geometry.PointFromQuery('Cali, Colombia',user_agent = 'eemont-example') # Extended constructor
S2 = (ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(point)
.closest('2020-10-15') # Extended (pre-processing)
.maskClouds(prob = 70) # Extended (pre-processing)
.scale() # Extended (pre-processing)
.index(['NDVI','NDWI','BAIS2'])) # Extended (processing)
And just like that, the collection was pre-processed, processed and ready to be analyzed!
Install the latest eemont version from PyPI by running:
pip install eemont
The following features are extended through eemont:
point = ee.Geometry.Point([-76.21, 3.45]) # Example ROI
- Overloaded operators (+, -, *, /, //, %, **, <<, >>, &, |, <, <=, ==, !=, >, >=, -, ~):
S2 = (ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(point)
.sort('CLOUDY_PIXEL_PERCENTAGE')
.first()
.maskClouds()
.scale())
N = S2.select('B8')
R = S2.select('B4')
B = S2.select('B2')
EVI = 2.5 * (N - R) / (N + 6.0 * R - 7.5 * B + 1.0) # Overloaded operators
- Clouds and shadows masking:
S2 = (ee.ImageCollection('COPERNICUS/S2_SR')
.maskClouds(prob = 65, cdi = -0.5, buffer = 300) # Clouds and shadows masking
.first())
- Image scaling:
MOD13Q1 = ee.ImageCollection('MODIS/006/MOD13Q1').scale() # Image scaling
- Spectral indices computation (vegetation, burn, water, snow, drought and kernel indices):
L8 = (ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(point)
.maskClouds()
.scale()
.index(['GNDVI','NDWI','BAI','NDSI','kNDVI'])) # Indices computation
indices = eemont.indices()
indices.BAIS2.formula # check info about spectral indices
indices.BAIS2.reference
eemont.listIndices() # Check all available indices
- Closest image to a specific date:
S5NO2 = (ee.ImageCollection('COPERNICUS/S5P/OFFL/L3_NO2')
.filterBounds(point)
.closest('2020-10-15')) # Closest image to a date
- Time series by region (or regions):
f1 = ee.Feature(ee.Geometry.Point([3.984770,48.767221]).buffer(50),{'ID':'A'})
f2 = ee.Feature(ee.Geometry.Point([4.101367,48.748076]).buffer(50),{'ID':'B'})
fc = ee.FeatureCollection([f1,f2])
S2 = (ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(fc)
.filterDate('2020-01-01','2021-01-01')
.maskClouds()
.scale()
.index(['EVI','NDVI']))
# By Region
ts = S2.getTimeSeriesByRegion(reducer = [ee.Reducer.mean(),ee.Reducer.median()],
geometry = fc,
bands = ['EVI','NDVI'],
scale = 10)
# By Regions
ts = S2.getTimeSeriesByRegions(reducer = [ee.Reducer.mean(),ee.Reducer.median()],
collection = fc,
bands = ['EVI','NDVI'],
scale = 10)
- New Geometry, Feature and Feature Collection constructors:
seattle_bbox = ee.Geometry.BBoxFromQuery('Seattle',user_agent = 'my-eemont-query-example')
cali_coords = ee.Feature.PointFromQuery('Cali, Colombia',user_agent = 'my-eemont-query-example')
amazonas_river = ee.FeatureCollection.MultiPointFromQuery('Río Amazonas',user_agent = 'my-eemont-query-example')
The Supported Platforms for each method can be found in the eemont documentation.
- Masking clouds and shadows supports Sentinel Missions (Sentinel-2 SR and Sentinel-3), Landsat Missions (SR products) and some MODIS Products. Check all details in User Guide > Masking Clouds and Shadows > Supported Platforms.
- Image scaling supports Sentinel Missions (Sentinel-2 and Sentinel-3), Landsat Missions and most MODIS Products. Check all details in User Guide > Image Scaling > Supported Platforms.
- Spectral indices computation supports Sentinel-2 and Landsat Missions. Check all details in User Guide > Spectral Indices > Supported Platforms.
- Getting the closest image to a specific date and time series supports all image collections with the
system:time_start
property.
The project is licensed under the MIT license.
Contributions to eemont are welcome! Here you will find how to do it:
If you find a bug, please report it by opening an issue. if possible, please attach the error, code, version, and other details.
If you want to contributte by fixing an issue, please check the eemont issues: contributions are welcome for open issues with labels bug
and help wanted
.
New features and modules are welcome! You can check the eemont issues: contributions are welcome for open issues with labels enhancement
and help wanted
.
You can add examples, notes and references to the eemont documentation by using the NumPy Docstrings of the eemont documentation, or by creating blogs, tutorials or papers.
First, fork the eemont repository and clone it to your local machine. Then, create a development branch:
git checkout -b name-of-dev-branch
eemont is divided according to Earth Engine classes, and you will find a module for each class (e.g. imagecollection.py
). Look for the required class as follows:
- ee.Feature:
feature.py
- ee.FeatureCollection:
featurecollection.py
- ee.Geometry:
geometry.py
- ee.Image:
image.py
- ee.ImageCollection:
imagecollection.py
The common.py
is used for methods that can be used for more than one Earth Engine class.
When creating new features, please start with the self
argument and add the corresponding decorator (e.g. @_extend_eeImageCollection()
). Check this example:
@_extend_eeImage()
def my_new_method(self,other):
'''Returns the addition of and image and a float.
Parameters
----------
self : ee.Image [this]
Image to add.
other : float
Float to add.
Returns
-------
ee.Image
Addition of an ee.Image and a float.
Examples
--------
>>> import ee, eemont
>>> ee.Initialize()
>>> img = ee.Image(0).my_new_method(other = 3.14)
'''
return self.add(other)
By using the @_extend_eeImage()
decorator, the my_new_method()
method is added to the ee.Image
class. Look for the required decorator as follows:
- ee.Feature:
@_extend_eeFeature()
- ee.FeatureCollection:
@_extend_eeFeatureCollection()
- ee.Geometry:
@_extend_eeGeometry()
- ee.Image:
@_extend_eeImage()
- ee.ImageCollection:
@_extend_eeImageCollection()
In order to test additions, you can use pytest
over the tests
folder:
pytest tests
This will autmatically test all modules for the available satellite platforms through eemont. If you have added a new feature, please include it in the tests.
To test across different Python versions, please use tox
.
Now it's time to commit your changes and push your development branch:
git add . git commit -m "Description of your work" git push origin name-of-dev-branch
And finally, submit a pull request.