try:
import google.colab
IN_COLAB = True
except:
IN_COLAB = False
if IN_COLAB:
!pip --quiet install earthengine-api
import ee
ee.Authenticate()
ee.Initialize()
Coming from the programming in Earth Engine through the Code Editor, you will need to slightly adapt your scripts to be able to run in Python. For the bulk of your code, you will be using Earth Engine API's server-side objects and functions - which will be exactly the same in Python. You only need to make a few syntactical changes.
Here's the full list of differences. Most important ones are elaborated below
Python code doesn't use the 'var' keyword
var city = 'San Fransico'
var state = 'California'
print(city, state)
var population = 881549
print(population)
city = 'San Fransico'
state = 'California'
print(city, state)
population = 881549
print(population)
Python doesn't use semi-colon for line ending. To indicate line-continuation you need to use \ character
var s2 = ee.ImageCollection('COPERNICUS/S2');
var filtered = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
.filter(ee.Filter.date('2019-01-01', '2019-12-31'));
s2 = ee.ImageCollection('COPERNICUS/S2')
filtered = s2 \
.filter(ee.Filter.date('2019-01-01', '2019-12-31'))
Instead of function
keyword, Python uses def
keyword. Also in-line functions are defined using lambda
anonymous functions.
In the example below, also now the and
operator - which is capitalized as And
in Python version to avoid conflict with the built-in and
operator. The same applies to Or
and Not
operators. true
, false
, null
in Python are also spelled as True
, False
and None
.
function maskS2clouds(image) {
var qa = image.select('QA60')
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask)//.divide(10000)
.select("B.*")
.copyProperties(image, ["system:time_start"])
}
def maskS2clouds(image):
qa = image.select('QA60')
cloudBitMask = 1 << 10
cirrusBitMask = 1 << 11
mask = qa.bitwiseAnd(cloudBitMask).eq(0).And(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask) \
.select("B.*") \
.copyProperties(image, ["system:time_start"])
Named arguments to Earth Engine functions need to be in quotes. Also when passing the named arguments as a dictionary, it needs to be passed using the **
keyword.
var gaul = ee.FeatureCollection("FAO/GAUL/2015/level1");
var gfsad = ee.Image("USGS/GFSAD1000_V0");
var wheatrice = gfsad.select('landcover').eq(1)
var uttarpradesh = gaul.filter(ee.Filter.eq('ADM1_NAME', 'Uttar Pradesh'))
var points = wheatrice.selfMask().stratifiedSample(
{numPoints:100, region:uttarpradesh, geometries: true})
gaul = ee.FeatureCollection("FAO/GAUL/2015/level1")
gfsad = ee.Image("USGS/GFSAD1000_V0")
wheatrice = gfsad.select('landcover').eq(1)
uttarpradesh = gaul.filter(ee.Filter.eq('ADM1_NAME', 'Uttar Pradesh'))
points = wheatrice.selfMask().stratifiedSample(**
{'numPoints':100, 'region':uttarpradesh, 'geometries': True})
The syntax for defining in-line functions is also slightly different. You need to use the lambda
keyword
var points = points.map(function(feature) {
return ee.Feature(feature.geometry(), {'id': feature.id()})
})
points = points.map(lambda feature: ee.Feature(feature.geometry(), {'id': feature.id()} ))
The print()
function syntax is the same. But you must remember that in the Code Editor when you cann print
, the value of the server object is fetched and then printed. You must do that explicitely by calling getInfo()
on any server-side object.
print(points.first()
print(points.first().getInfo())
The automatic conversion works great, but it is not perfect. You may have to tweak the output a bit. An important filter that is missing from the Python API is the ee.Filter.bounds()
. You can use an alternative ee.Filter.intersects('.geo', geometry)
instead.
if IN_COLAB:
!pip --quiet install geemap
import geemap
javascript_code = """
var geometry = ee.Geometry.Point([107.61303468448624, 12.130969369851766]);
Map.centerObject(geometry, 12)
var s2 = ee.ImageCollection("COPERNICUS/S2")
var rgbVis = {
min: 0.0,
max: 3000,
bands: ['B4', 'B3', 'B2'],
};
// Write a function for Cloud masking
function maskS2clouds(image) {
var qa = image.select('QA60')
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask)
.select("B.*")
.copyProperties(image, ["system:time_start"])
}
var filtered = s2
.filter(ee.Filter.date('2019-01-01', '2019-12-31'))
.filter(ee.Filter.bounds(geometry))
.map(maskS2clouds)
// Write a function that computes NDVI for an image and adds it as a band
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('ndvi');
return image.addBands(ndvi);
}
var withNdvi = filtered.map(addNDVI);
var composite = withNdvi.median()
palette = [
'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718',
'74A901', '66A000', '529400', '3E8601', '207401', '056201',
'004C00', '023B01', '012E01', '011D01', '011301'];
ndviVis = {min:0, max:0.5, palette: palette }
Map.addLayer(withNdvi, ndviVis, 'NDVI Composite')
"""
geemap.js_snippet_to_py(javascript_code)
import ee
import geemap
if IN_COLAB:
import geemap.eefolium as emap
Map = emap.Map()
else:
Map = geemap.Map()
ee.Initialize()
geometry = ee.Geometry.Point([107.61303468448624, 12.130969369851766])
Map.centerObject(geometry, 12)
s2 = ee.ImageCollection("COPERNICUS/S2")
rgbVis = {
'min': 0.0,
'max': 3000,
'bands': ['B4', 'B3', 'B2'],
}
# Write a function for Cloud masking
def maskS2clouds(image):
qa = image.select('QA60')
cloudBitMask = 1 << 10
cirrusBitMask = 1 << 11
mask = qa.bitwiseAnd(cloudBitMask).eq(0).And(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask) \
.select("B.*") \
.copyProperties(image, ["system:time_start"])
filtered = s2 \
.filter(ee.Filter.date('2019-01-01', '2019-12-31')) \
.filter(ee.Filter.intersects('.geo', geometry)) \
.map(maskS2clouds)
# Write a function that computes NDVI for an image and adds it as a band
def addNDVI(image):
ndvi = image.normalizedDifference(['B5', 'B4']).rename('ndvi')
return image.addBands(ndvi)
withNdvi = filtered.map(addNDVI)
composite = withNdvi.median()
palette = [
'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718',
'74A901', '66A000', '529400', '3E8601', '207401', '056201',
'004C00', '023B01', '012E01', '011D01', '011301'];
ndviVis = {'min':0, 'max':0.5, 'palette': palette }
Map.addLayer(composite.select('ndvi'), ndviVis, 'Layer')
Map
Take the following code and convert it to Python. You may do it manually or use the geemap
package
var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var hydrosheds = ee.FeatureCollection("WWF/HydroSHEDS/v1/Basins/hybas_9");
var watershed = hydrosheds.filter(ee.Filter.eq('HYBAS_ID', 4090726490))
var waterExtent = gsw.select('max_extent');
var areaImage = waterExtent.multiply(ee.Image.pixelArea())
var area = areaImage.reduceRegion({
reducer: ee.Reducer.sum(),
geometry: watershed,
scale: 10,
maxPixels: 1e9
});
var waterArea = ee.Number(area.get('max_extent')).divide(1e6)
print(waterArea)