Google Earth Engine (GEE) propose deux interfaces pour le même moteur de calcul : un éditeur web JavaScript hébergé (code.earthengine.google.com) et une bibliothèque Python (`earthengine-api`) utilisable depuis Jupyter, VS Code ou n'importe quel script. Beaucoup de débutants se demandent par laquelle commencer. La réponse honnête, c'est : ça dépend de ce que vous voulez en faire.
Quand JavaScript gagne
- Apprendre les concepts GEE — l'éditeur web a la documentation intégrée, l'auto-complétion, l'inspecteur de carte interactif. C'est la voie royale les 20 premières heures.
- Itérer rapidement sur une visualisation — le panneau carte est immédiat, pas de plumbing.
- Partager un script avec un collègue qui n'a pas Python — un lien suffit, le code tourne dans son navigateur.
Quand Python gagne
- Pipeline reproductible et versionnable (Git) — un notebook ou un .py s'archive proprement.
- Intégration avec geopandas, rasterio, scikit-learn pour le post-traitement local.
- Automatisation : tâches programmées (cron, Airflow), ETL, génération de rapports.
- Travail à plusieurs — pull requests, code review, tests pytest.
- Volumes : exports massifs vers GCS, parallélisation contrôlée.
Notre recommandation pédagogique : commencer par JavaScript pour saisir le modèle mental (lazy evaluation, server-side / client-side, Image vs ImageCollection), puis basculer en Python dès qu'on veut industrialiser. Les concepts sont identiques, l'API quasi miroir.
Le cas pratique : NDVI moyen sur une saison
On va calculer le NDVI moyen sur la zone de Saint-Louis (Sénégal) entre juillet et octobre 2024 (saison des pluies), puis l'exporter en GeoTIFF. Le même résultat, deux fois.
Version JavaScript (Code Editor)
// 1. Région d'intérêt — rectangle approximatif Saint-Louis
var roi = ee.Geometry.Rectangle([-16.55, 15.95, -16.35, 16.10]);
// 2. Collection Sentinel-2 SR, filtrée espace + temps + nuages
var collection = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
.filterBounds(roi)
.filterDate('2024-07-01', '2024-10-31')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30));
// 3. Fonction NDVI = (B8 - B4) / (B8 + B4)
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI');
return image.addBands(ndvi);
}
// 4. Composite : moyenne du NDVI sur la période
var mean = collection.map(addNDVI).select('NDVI').mean().clip(roi);
// 5. Visualisation
Map.centerObject(roi, 10);
Map.addLayer(mean, { min: 0, max: 0.8, palette: ['white', 'darkgreen'] }, 'NDVI moyen');
// 6. Export
Export.image.toDrive({
image: mean,
description: 'ndvi_saintlouis_jaso2024',
scale: 10,
region: roi,
fileFormat: 'GeoTIFF',
maxPixels: 1e9
});On lance via le bouton « Run » de l'éditeur. L'export apparaît dans l'onglet Tasks et part vers Google Drive après confirmation. Compter 2 à 5 minutes pour cette taille de zone.
Version Python (notebook ou script)
import ee
# Authentification — la première fois ouvre un navigateur
ee.Authenticate()
ee.Initialize(project='votre-projet-gcp')
roi = ee.Geometry.Rectangle([-16.55, 15.95, -16.35, 16.10])
collection = (
ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
.filterBounds(roi)
.filterDate('2024-07-01', '2024-10-31')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
)
def add_ndvi(image):
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
return image.addBands(ndvi)
mean = collection.map(add_ndvi).select('NDVI').mean().clip(roi)
task = ee.batch.Export.image.toDrive(
image=mean,
description='ndvi_saintlouis_jaso2024',
scale=10,
region=roi,
fileFormat='GeoTIFF',
maxPixels=int(1e9),
)
task.start()
print('Export lancé:', task.id)Mêmes appels, même résultat. Deux différences pratiques : (a) Python exige un projet GCP et une authentification, plus rigoureux mais plus long la première fois ; (b) on peut suivre le `task.status()` programmatiquement et chaîner avec d'autres traitements.
Pièges classiques quand on débute
- Confondre client-side et server-side — `print(ee.Image(...))` ne montre pas les pixels, mais la description JSON de l'objet. Pour voir, il faut `getInfo()` ou afficher sur la carte.
- Filtrer trop tard — chaque opération non filtrée se déploie sur la collection entière. Toujours `filterBounds` + `filterDate` avant `map`.
- Oublier `.clip(roi)` à la fin — l'image exportée déborde de la zone et le GeoTIFF triple de poids.
- Mauvais système de coordonnées à l'export — par défaut, GEE exporte dans la projection native de l'image. Forcer `crs='EPSG:32628'` pour le Sénégal si on veut des mètres lisibles.
- Quotas — un export de toute la côte ouest-africaine en S2 SR à 10 m, c'est 200 Go. GEE imposera des contraintes. Réduire à `maxPixels=1e10` peut aider, mais souvent il faut découper en tuiles.
Aller plus loin
Une fois ces fondations posées, les vraies questions deviennent : comment traiter une saison sèche ET une saison des pluies dans la même analyse ? Comment masquer les nuages plus finement que `CLOUDY_PIXEL_PERCENTAGE` ? Comment comparer NDVI Sentinel-2 et NDVI Landsat-8 sans biais ? Le module Gojambar « Télédétection avec Google Earth Engine » couvre ces questions sur un projet de fil rouge évalué.