All Projects → davemlz → eemont

davemlz / eemont

Licence: MIT license
A python package that extends Google Earth Engine.

Programming Languages

python
139335 projects - #7 most used programming language
TeX
3793 projects

Projects that are alternatives of or similar to eemont

awesome-spectral-indices
A ready-to-use curated list of Spectral Indices for Remote Sensing applications.
Stars: ✭ 357 (+23.1%)
Mutual labels:  gis, raster, remote-sensing, satellite-imagery, google-earth-engine, earth-engine, geographic-information-systems, spectral-indices
spectral
Awesome Spectral Indices for the Google Earth Engine JavaScript API (Code Editor).
Stars: ✭ 68 (-76.55%)
Mutual labels:  gis, remote-sensing, google-earth-engine, earth-engine, geographic-information-systems, spectral-indices
ee extra
A ninja python package that unifies the Google Earth Engine ecosystem.
Stars: ✭ 42 (-85.52%)
Mutual labels:  gis, remote-sensing, satellite-imagery, google-earth-engine, earth-engine, geographic-information-systems
spyndex
Awesome Spectral Indices in Python.
Stars: ✭ 56 (-80.69%)
Mutual labels:  remote-sensing, satellite-imagery, google-earth-engine, earth-engine, spectral-indices
earthengine-py-examples
A collection of 300+ examples for using Earth Engine and the geemap Python package
Stars: ✭ 76 (-73.79%)
Mutual labels:  gis, remote-sensing, google-earth-engine, earth-engine
earthengine-apps
A collection of Earth Engine Apps created using geemap, voila, and heroku
Stars: ✭ 20 (-93.1%)
Mutual labels:  gis, remote-sensing, google-earth-engine, earth-engine
geoblaze
Blazing Fast JavaScript Raster Processing Engine
Stars: ✭ 80 (-72.41%)
Mutual labels:  gis, raster, remote-sensing, satellite-imagery
CoastSat.slope
Beach-face slope estimation from satellite-derived shorelines, extension of the CoastSat toolbox.
Stars: ✭ 42 (-85.52%)
Mutual labels:  remote-sensing, google-earth-engine, satellite-images, earth-engine
eodag
Earth Observation Data Access Gateway
Stars: ✭ 183 (-36.9%)
Mutual labels:  gis, remote-sensing, satellite-imagery
land-cover-to-land-use-classification
Satellite image processing pipeline to classify land-cover and land-use
Stars: ✭ 64 (-77.93%)
Mutual labels:  gis, remote-sensing, satellite-imagery
open-impact
To help quickstart impact work with Satellogic [hyperspectral] data
Stars: ✭ 21 (-92.76%)
Mutual labels:  gis, remote-sensing, satellite-imagery
georaster-layer-for-leaflet
Display GeoTIFFs and soon other types of raster on your Leaflet Map
Stars: ✭ 168 (-42.07%)
Mutual labels:  gis, raster, satellite-imagery
wxee
A Python interface between Earth Engine and xarray for processing time series data
Stars: ✭ 113 (-61.03%)
Mutual labels:  gis, raster, earth-engine
localtileserver
🌐 dynamic tile server for visualizing rasters in Jupyter with ipyleaflet or folium
Stars: ✭ 190 (-34.48%)
Mutual labels:  gis, raster, satellite-imagery
Geotiff.io
Static website for viewing and analyzing GeoTIFF's in the browser
Stars: ✭ 53 (-81.72%)
Mutual labels:  gis, raster, satellite-imagery
Geospatial Machine Learning
A curated list of resources focused on Machine Learning in Geospatial Data Science.
Stars: ✭ 289 (-0.34%)
Mutual labels:  gis, remote-sensing, satellite-imagery
Felicette
Satellite imagery for dummies.
Stars: ✭ 1,710 (+489.66%)
Mutual labels:  gis, satellite-imagery, satellite-images
GoogleEarthEngine-side-projects
Google Earth Engine side projects and tutorial scripts
Stars: ✭ 23 (-92.07%)
Mutual labels:  remote-sensing, satellite-imagery, google-earth-engine
Start maja
To process a Sentinel-2 time series with MAJA cloud detection and atmospheric correction processor
Stars: ✭ 47 (-83.79%)
Mutual labels:  raster, remote-sensing, satellite-imagery
pylandtemp
Algorithms for computing global land surface temperature and emissivity from NASA's Landsat satellite images with Python.
Stars: ✭ 110 (-62.07%)
Mutual labels:  raster, remote-sensing, satellite-images

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:

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
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)
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
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))
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
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))
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
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))
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
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))
ds = 'LANDSAT/LC08/C01/T1_SR'
          
(ee.ImageCollection(ds)
    .scaleAndOffset()
    .spectralIndices([
        'NDVI',
        'GNDVI',
        'NDSI'])
)

The list of available indices can be retrieved by running:

eemont.listIndices()

Information about the indices can also be checked:

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
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())
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()!

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!

usr = 'my-eemont-query-example'
   
seattle_bbox = ee.Geometry.BBoxFromQuery('Seattle',user_agent = usr)
cali_coords = ee.Feature.PointFromQuery('Cali, Colombia',user_agent = usr)
amazonas_river = ee.FeatureCollection.MultiPointFromQuery('Río Amazonas',user_agent = 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+)
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
)
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
)
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!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].