eemont

eemont: A Python package that extends Google Earth Engine - Published in JOSS (2021)

https://github.com/davemlz/eemont

Science Score: 100.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 8 DOI reference(s) in README and JOSS metadata
  • Academic publication links
    Links to: joss.theoj.org
  • Committers with academic emails
    1 of 6 committers (16.7%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

earth-engine geographic-information-systems gis google google-earth-engine python python3 raster remote-sensing satellite-imagery satellite-images spectral-indices

Keywords from Contributors

earthengine
Last synced: 4 months ago · JSON representation ·

Repository

A python package that extends Google Earth Engine.

Basic Info
Statistics
  • Stars: 431
  • Watchers: 13
  • Forks: 71
  • Open Issues: 9
  • Releases: 25
Topics
earth-engine geographic-information-systems gis google google-earth-engine python python3 raster remote-sensing satellite-imagery satellite-images spectral-indices
Created about 5 years ago · Last pushed 4 months ago
Metadata Files
Readme Contributing Funding License Citation

README.md

header

A python package that extends Google Earth Engine

PyPI conda-forge License Documentation Status Tests GitHub Sponsors Buy me a coffee Ko-fi GEE Community Twitter JOSS Black isort


GitHub: https://github.com/davemlz/eemont

Documentation: https://eemont.readthedocs.io/

PyPI: https://pypi.org/project/eemont/

Conda-forge: https://anaconda.org/conda-forge/eemont

Tutorials: https://github.com/davemlz/eemont/tree/master/docs/tutorials

Paper: https://joss.theoj.org/papers/10.21105/joss.03168


Overview

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.

Google Earth Engine Community: Developer Resources

The eemont Python package can be found in the Earth Engine Community: Developer Resources together with other awesome resources such as geemap and rgee.

How does it work?

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:

```python 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) .scaleAndOffset() # Extended (pre-processing) .spectralIndices(['NDVI','NDWI','BAIS2'])) # Extended (processing) ```

And just like that, the collection was pre-processed, processed and ready to be analyzed!

Installation

Install the latest version from PyPI:

pip install eemont

Upgrade eemont by running:

pip install -U eemont

Install the latest version from conda-forge:

conda install -c conda-forge eemont

Install the latest dev version from GitHub by running:

pip install git+https://github.com/davemlz/eemont

Features

Let's see some of the main features of eemont and how simple they are compared to the GEE Python API original methods:

Overloaded Operators

The following operators are overloaded: +, -, *\, /, //, %, **\ , <<, >>, &, |\, <, <=, ==, !=, >, >=, -, ~. (and you can avoid the ee.Image.expression() method!)

GEE Python API eemont-style
``` python ds = 'COPERNICUS/S2_SR' S2 = (ee.ImageCollection(ds) .first()) def scaleImage(img): scaling = img.select('B.*') x = scaling.multiply(0.0001) scaling = img.select(['AOT','WVP']) scaling = scaling.multiply(0.001) x = x.addBands(scaling) notScaling = img.select([ 'SCL', 'TCI.*', 'MSK.*', 'QA.*' ])) return x.addBands(notScaling) S2 = scaleImage(S2) exp = '2.5*(N-R)/(N+(6*R)-(7.5*B)+1)' imgDict = { 'N': S2.select('B8'), 'R': S2.select('B4'), 'B': S2.select('B2') } EVI = S2.expression(exp,imgDict) ``` ``` python ds = 'COPERNICUS/S2_SR' S2 = (ee.ImageCollection(ds) .first() .scale()) N = S2.select('B8') R = S2.select('B4') B = S2.select('B2') EVI = 2.5*(N-R)/(N+(6*R)-(7.5*B)+1) ```

Clouds and Shadows Masking

Masking clouds and shadows can be done using eemont with just one method: maskClouds()!

GEE Python API eemont-style
``` python ds = 'LANDSAT/LC08/C01/T1_SR' def maskCloudsShadows(img): c = (1 << 3) s = (1 << 5) qa = 'pixel_qa' qa = img.select(qa) cm = qa.bitwiseAnd(c).eq(0) sm = qa.bitwiseAnd(s).eq(0) mask = cm.And(sm) return img.updateMask(mask) (ee.ImageCollection(ds) .map(maskCloudsShadows)) ``` ``` python ds = 'LANDSAT/LC08/C01/T1_SR' (ee.ImageCollection(ds) .maskClouds()) ```

Image Scaling and Offsetting

Scaling and offsetting can also be done using eemont with just one method: scale()!

GEE Python API eemont-style
``` python def scaleBands(img): scaling = img.select([ 'NDVI', 'EVI', 'sur.*' ]) x = scaling.multiply(0.0001) scaling = img.select('.*th') scaling = scaling.multiply(0.01) x = x.addBands(scaling) notScaling = img.select([ 'DetailedQA', 'DayOfYear', 'SummaryQA' ]) return x.addBands(notScaling) ds = 'MODIS/006/MOD13Q1' (ee.ImageCollection(ds) .map(scaleBands)) ``` ``` python ds = 'MODIS/006/MOD13Q1' (ee.ImageCollection(ds) .scaleAndOffset()) ```

Complete Preprocessing

The complete preprocessing workflow (Masking clouds and shadows, and image scaling and offsetting) can be done using eemont with just one method: preprocess()!

GEE Python API eemont-style
``` python ds = 'LANDSAT/LC08/C01/T1_SR' def maskCloudsShadows(img): c = (1 << 3) s = (1 << 5) qa = 'pixel_qa' qa = img.select(qa) cm = qa.bitwiseAnd(c).eq(0) sm = qa.bitwiseAnd(s).eq(0) mask = cm.And(sm) return img.updateMask(mask) def scaleBands(img): scaling = img.select('B[1-7]') x = scaling.multiply(0.0001) scaling = img.select([ 'B10','B11' ]) scaling = scaling.multiply(0.1) x = x.addBands(scaling) notScaling = img.select([ 'sr_aerosol', 'pixel_qa', 'radsat_qa' ]) return x.addBands(notScaling) (ee.ImageCollection(ds) .map(maskCloudsShadows) .map(scaleBands)) ``` ``` python ds = 'LANDSAT/LC08/C01/T1_SR' (ee.ImageCollection(ds) .preprocess()) ```

Spectral Indices

Do you need to compute several spectral indices? Use the spectralIndices() method! The indices are taken from Awesome Spectral Indices.

GEE Python API eemont-style
``` python ds = 'LANDSAT/LC08/C01/T1_SR' def scaleImage(img): scaling = img.select('B[1-7]') x = scaling.multiply(0.0001) scaling = img.select(['B10','B11']) scaling = scaling.multiply(0.1) x = x.addBands(scaling) notScaling = img.select([ 'sr_aerosol', 'pixel_qa', 'radsat_qa' ])) return x.addBands(notScaling) def addIndices(img): x = ['B5','B4'] a = img.normalizedDifference(x) a = a.rename('NDVI') x = ['B5','B3'] b = img.normalizedDifference(x) b = b.rename('GNDVI') x = ['B3','B6'] c = img.normalizedDifference(x) c = b.rename('NDSI') return img.addBands([a,b,c]) (ee.ImageCollection(ds) .map(scaleImage) .map(addIndices)) ``` ``` python ds = 'LANDSAT/LC08/C01/T1_SR' (ee.ImageCollection(ds) .scaleAndOffset() .spectralIndices([ 'NDVI', 'GNDVI', 'NDSI']) ) ```

The list of available indices can be retrieved by running:

python eemont.listIndices()

Information about the indices can also be checked:

python indices = eemont.indices() indices.BAIS2.formula indices.BAIS2.reference

Closest Image to a Specific Date

Struggling to get the closest image to a specific date? Here is the solution: the closest() method!

GEE Python API eemont-style
``` python ds = 'COPERNICUS/S5P/OFFL/L3_NO2' xy = [-76.21, 3.45] poi = ee.Geometry.Point(xy) date = ee.Date('2020-10-15') date = date.millis() def setTimeDelta(img): prop = 'system:time_start' prop = img.get(prop) prop = ee.Number(prop) delta = prop.subtract(date) delta = delta.abs() return img.set( 'dateDist', delta) (ee.ImageCollection(ds) .filterBounds(poi) .map(setTimeDelta) .sort('dateDist') .first()) ``` ``` python ds = 'COPERNICUS/S5P/OFFL/L3_NO2' xy = [-76.21, 3.45] poi = ee.Geometry.Point(xy) (ee.ImageCollection(ds) .filterBounds(poi) .closest('2020-10-15')) ```

Time Series By Regions

The JavaScript API has a method for time series extraction (included in the ui.Chart module), but this method is missing in the Python API... so, here it is!

PD: Actually, there are two methods that you can use: getTimeSeriesByRegion() and getTimeSeriesByRegions()!

``` python 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() .scaleAndOffset() .spectralIndices(['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) ```

Constructors by Queries

Don't you have the coordinates of a place? You can construct them by using queries!

``` python usr = 'my-eemont-query-example'

seattlebbox = ee.Geometry.BBoxFromQuery('Seattle',useragent = usr) calicoords = ee.Feature.PointFromQuery('Cali, Colombia',useragent = usr) amazonasriver = ee.FeatureCollection.MultiPointFromQuery('Río Amazonas',useragent = usr) ```

JavaScript Modules

This is perhaps the most important feature in eeExtra! What if you could use a JavaScript module (originally just useful for the Code Editor) in python or R? Well, wait no more for it!

JS (Code Editor) Python (eemont) R (rgee+)
``` javascript var usr = 'users/sofiaermida/' var rep = 'landsat_smw_lst:' var fld = 'modules/' var fle = 'Landsat_LST.js' var pth = usr+rep+fld+fle var mod = require(pth) var LST = mod.collection( ee.Geometry.Rectangle([ -8.91, 40.0, -8.3, 40.4 ]), 'L8', '2018-05-15', '2018-05-31', true ) ``` ``` python import ee, eemont ee.Initialize() usr = 'users/sofiaermida/' rep = 'landsat_smw_lst:' fld = 'modules/' fle = 'Landsat_LST.js' pth = usr+rep+fld+fle ee.install(pth) mod = ee.require(pth) LST = mod.collection( ee.Geometry.Rectangle([ -8.91, 40.0, -8.3, 40.4 ]), 'L8', '2018-05-15', '2018-05-31', True ) ``` ``` r library(rgee) library(rgeeExtra) ee_Initialize() usr <- 'users/sofiaermida/' rep <- 'landsat_smw_lst:' fld <- 'modules/' fle <- 'Landsat_LST.js' pth <- paste0(usr,rep,fld,fle) mod <- ee$require(pth) LST = mod$collection( ee$Geometry$Rectangle(c( -8.91, 40.0, -8.3, 40.4 )), 'L8', '2018-05-15', '2018-05-31', TRUE ) ```

License

The project is licensed under the MIT license.

How to cite

Do you like using eemont and think it is useful? Share the love by citing it!:

Montero, D., (2021). eemont: A Python package that extends Google Earth Engine. Journal of Open Source Software, 6(62), 3168, https://doi.org/10.21105/joss.03168

If required, here is the BibTex!:

@article{Montero2021, doi = {10.21105/joss.03168}, url = {https://doi.org/10.21105/joss.03168}, year = {2021}, publisher = {The Open Journal}, volume = {6}, number = {62}, pages = {3168}, author = {David Montero}, title = {eemont: A Python package that extends Google Earth Engine}, journal = {Journal of Open Source Software} }

Artists

  • David Montero Loaiza: Lead Developer of eemont and eeExtra.
  • César Aybar: Lead Developer of rgee and eeExtra.
  • Aaron Zuspan: Plus Codes Constructors and Methods, Panchromatic Sharpening and Histogram Matching Developer.

Credits

Special thanks to Justin Braaten for featuring eemont in tutorials and the GEE Community: Developer Resources Page, to César Aybar for the formidable help with Awesome Spectral Indices and to the JOSS Review Team (Katy Barnhart, Jayaram Hariharan, Qiusheng Wu and Patrick Gray) for the comments, suggestions and contributions!

Owner

  • Name: David Montero Loaiza
  • Login: davemlz
  • Kind: user
  • Location: Leipzig, Germany
  • Company: RSC4Earth | University of Leipzig

PhD Student at UniLeipzig | Research Assistant at RSC4Earth | Creator of #eemont #awesome-spectral-indices #spectral and #spyndex

JOSS Publication

eemont: A Python package that extends Google Earth Engine
Published
June 08, 2021
Volume 6, Issue 62, Page 3168
Authors
David Montero ORCID
Independent Researcher
Editor
Katy Barnhart ORCID
Tags
Google Earth Engine Remote Sensing GIS QGIS R

Citation (CITATION.cff)

cff-version: 1.1.0
message: "Please cite the following works when using this software."
authors:
  - family-names: Montero
    given-names: David
    orcid: 
title: "eemont: A Python package that extends Google Earth Engine."
version: 0.2.5
date-released: 2021-07-26
repository: https://github.com/davemlz/eemont
url: https://eemont.readthedocs.io/
references:
  - type: article
    authors:
      - family-names: Montero
        given-names: David
    title: "eemont: A Python package that extends Google Earth Engine."
    journal: "The Jounal of Open Source Software"
    doi: https://doi.org/10.21105/joss.03168
    year: 2021
    volume: 6
    number-volumes: 62

GitHub Events

Total
  • Create event: 1
  • Release event: 2
  • Issues event: 2
  • Watch event: 16
  • Issue comment event: 3
  • Push event: 40
  • Fork event: 2
Last Year
  • Create event: 1
  • Release event: 2
  • Issues event: 2
  • Watch event: 16
  • Issue comment event: 3
  • Push event: 40
  • Fork event: 2

Committers

Last synced: 5 months ago

All Time
  • Total Commits: 1,033
  • Total Committers: 6
  • Avg Commits per committer: 172.167
  • Development Distribution Score (DDS): 0.468
Past Year
  • Commits: 78
  • Committers: 3
  • Avg Commits per committer: 26.0
  • Development Distribution Score (DDS): 0.103
Top Committers
Name Email Commits
GitHub Action a****n@g****m 550
U-dmlmont-PC\dmlmont d****t@g****m 471
Aaron Zuspan 5****n 5
Qiusheng Wu g****s@g****m 4
Katy Barnhart k****t@u****v 2
Mikhail Moskovchenko 4****e 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 74
  • Total pull requests: 11
  • Average time to close issues: 19 days
  • Average time to close pull requests: 3 days
  • Total issue authors: 25
  • Total pull request authors: 4
  • Average comments per issue: 2.16
  • Average comments per pull request: 1.82
  • Merged pull requests: 10
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 1
  • Pull requests: 1
  • Average time to close issues: 20 days
  • Average time to close pull requests: N/A
  • Issue authors: 1
  • Pull request authors: 1
  • Average comments per issue: 2.0
  • Average comments per pull request: 0.0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • davemlz (28)
  • aazuspan (9)
  • FeiYao-Edinburgh (4)
  • elbeejay (4)
  • Daniel-Trung-Nguyen (4)
  • Ivo-G (3)
  • mariofomacajr (3)
  • masands (2)
  • navidboy70 (1)
  • inter8888 (1)
  • sebimarkgraf (1)
  • pkpnerist (1)
  • Geethen (1)
  • giswqs (1)
  • kaushikCanada (1)
Pull Request Authors
  • aazuspan (5)
  • giswqs (3)
  • kbarnhart (2)
  • simonreise (1)
Top Labels
Issue Labels
enhancement (39) bug (15) question (2) documentation (2) wontfix (2) help wanted (1)
Pull Request Labels

Packages

  • Total packages: 3
  • Total downloads:
    • pypi 4,796 last-month
  • Total dependent packages: 5
    (may contain duplicates)
  • Total dependent repositories: 13
    (may contain duplicates)
  • Total versions: 39
  • Total maintainers: 1
pypi.org: eemont

A Python package that extends Google Earth Engine

  • Versions: 20
  • Dependent Packages: 3
  • Dependent Repositories: 11
  • Downloads: 4,796 Last month
Rankings
Dependent packages count: 2.4%
Stargazers count: 3.3%
Average: 4.0%
Dependent repos count: 4.4%
Downloads: 4.8%
Forks count: 5.2%
Maintainers (1)
Last synced: 4 months ago
proxy.golang.org: github.com/davemlz/eemont
  • Versions: 6
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.4%
Average: 5.6%
Dependent repos count: 5.8%
Last synced: 4 months ago
conda-forge.org: eemont
  • Versions: 13
  • Dependent Packages: 2
  • Dependent Repositories: 2
Rankings
Dependent packages count: 19.6%
Dependent repos count: 20.2%
Average: 21.0%
Stargazers count: 21.4%
Forks count: 22.9%
Last synced: 4 months ago

Dependencies

docs/docs-requirements.txt pypi
  • geemap *
  • google-auth <2.0dev
  • ipykernel *
  • ipython *
  • nbsphinx *
  • protobuf <3.18.0,>=3.12.0
  • pydata-sphinx-theme *
  • recommonmark *
  • sphinx >=1.4,
  • sphinx-copybutton *
  • sphinx-tabs *
  • sphinxcontrib-autoprogram *
requirements.txt pypi
  • beautifulsoup4 *
  • earthengine-api *
  • ee_extra *
  • geopy *
  • numpy *
  • pandas *
  • python-box *
  • requests *
setup.py pypi
  • beautifulsoup4 *
  • earthengine-api *
  • ee_extra >=0.0.14
  • geopy *
  • numpy *
  • pandas *
  • python-box >=6.0.0
  • requests *
.github/workflows/tests.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
.github/workflows/update_awesome_spectral_indices.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
  • ad-m/github-push-action v0.6.0 composite
.github/workflows/update_gee_stac_ids.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
  • ad-m/github-push-action v0.6.0 composite
.github/workflows/update_gee_stac_scale_offset.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
  • ad-m/github-push-action v0.6.0 composite