Mastering Geospatial Analysis with Geemap and Google Earth Engine
Github Pages link
Introduction
Geemap is a Python bridge to Google Earth Engine (GEE), solving a critical challenge in geospatial analysis. While GEE provides unparalleled access to petabyte-scale satellite imagery and environmental datasets, its native JavaScript API created barriers for Python-centric workflows. Geemap resolves this by:
- Enabling Pythonic access to 50+ million GEE images/collections
- Providing interactive Jupyter notebook integration
- Offering 100+ prebuilt visualization basemaps
- Simplifying complex geospatial operations with intuitive syntax
This tool is particularly valuable for environmental scientists, GIS professionals, and data analysts needing to process large-scale Earth observation data without infrastructure overhead.
Installation Instructions for geemap
1. Install Required Software
Before installing geemap, ensure you have the following installed:
- Python (≥3.7)
You can check your Python version by running:
If Python is not installed, download it from python.org.python --version
- Anaconda (Optional, but Recommended for Jupyter Support)
Download and install Anaconda from anaconda.com or Miniconda (lightweight version) from miniconda.
2. Create a Virtual Environment (Recommended)
To keep dependencies clean, create a virtual environment:
- Using conda:
conda create -n gee_env python=3.9 -y conda activate gee_env
- Using virtualenv (for those not using Anaconda):
python -m venv gee_env source gee_env/bin/activate # Mac/Linux gee_env\Scripts\activate # Windows
3. Install geemap
Once inside the environment, install geemap using either:
- pip (for general users):
pip install geemap
- conda (for Anaconda users):
conda install -c conda-forge geemap
4. Install Google Earth Engine (GEE) API
geemap requires the Earth Engine API, which can be installed using:
pip install earthengine-api
Check if it’s installed correctly by running:
earthengine authenticate
This will open a browser window asking you to authenticate with your Google account. If the authentication is successful, you will receive a verification code to enter in the terminal.
5. Install Jupyter Notebook (Optional but Recommended)
If you plan to use geemap in a Jupyter Notebook, install:
pip install notebook jupyterlab
And to enable geemap in Jupyter:
pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension
Run Jupyter Notebook using:
jupyter notebook
6. Verify the Installation
To check if geemap is working, open a Python shell or Jupyter Notebook and run:
import geemap
import ee
# Initialize Earth Engine
ee.Initialize()
# Create an interactive
Map = geemap.Map()
Map
Key Features
- Interactive mapping with multiple basemaps
- Advanced data visualization tools
- Jupyter notebook integration
- Time series analysis capabilities
- Earth Engine data export functionality
Code Examples
Creating a Map
import ee
import geemap
m = geemap.Map(center=[40, -100], zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
m.add_layer(dem, {"min":0, "max":4000}, "Elevation")
m
Screenshot

Creating a map
Adding Layer Manager
The layer manager provides control over layer visibility and transparency. It enables toggling layers on and off and adjusting transparency with a slider, making it easy to customize map visuals:
m.add("layer_manager")
Working with Datasets
from geemap.datasets import DATA
m = geemap.Map()
dataset = ee.Image(DATA.USGS_GAP_AK_2001)
m.add_layer(dataset, {}, "GAP Alaska")
m.centerObject(dataset, zoom=4)
m
The datasets module contains a lot of data, allowing you to display various datasets on the map.
Retrieving Metadata for a Specific Dataset
from geemap.datasets import get_metadata
metadata = get_metadata(DATA.USGS_GAP_AK_2001)
print(metadata)
This code snippet retrieves the metadata for the selected dataset.
Image Visualization
# Load and display elevation data
image = ee.Image("AHN/AHN2_05M_INT")
vis_params = {
'min': 0,
'max': 4000,
'palette': ['#006633', '#E5FFCC', '#662A00', '#D8D8D8', '#F5F5F5'],
'opacity': 0.8
}
m.add_layer(image, vis_params, "Elevation Map")
m.add_colorbar(vis_params, label="Elevation (m)")
m
Key visualization parameters include band selection, value ranges, color palettes, and opacity controls.
Loading Feature Collections
m = geemap.Map()
fc = ee.FeatureCollection("TIGER/2016/Roads")
m.set_center(-83, 35, 12)
m.add_layer(fc, {}, "Census Roads")
m
The above code snippet loads the feature collection. We use fc = ee.FeatureCollection("TIGER/2016/Roads")
to load the Feature Collection, which contains a collection of images that can be filtered and analyzed.
Screenshot

Using Tiger from collection
Filtering Feature Collections
m = geemap.Map()
states = ee.FeatureCollection("TIGER/2018/States")
fc = states.filter(ee.Filter.eq("NAME", "Tennessee"))
m.add_layer(fc, {}, "Tennessee")
m.center_object(fc, 7)
m
In the above code snippet, fc
is the filtered Feature Collection. The line fc = states.filter(ee.Filter.eq("NAME", "Tennessee"))
filters the collection to include only features where the "NAME" equals "Tennessee". The map is then centered on this feature collection.
Other filtering options include Filter.neq
(not equal), Filter.lt
(less than), Filter.gt
(greater than), Filter.gte
(greater than or equal), Filter.or
, Filter.not
, Filter.inList
(if value is in that list), and Filter.StringStartsWith
(checks starting substring).
Screenshot

Filtering Feature collection
Feature Collection Operations
fc.size()
fea = fc.first()
fea.toDictionary()
These three lines of code represent different actions: the first line returns the number of elements in fc
, the second line selects the first feature in the feature collection, and the third line converts that feature to a dictionary.
Converting Feature Collection to Pandas DataFrame
geemap.ee_to_df(fc)
This line converts the feature collection into a pandas DataFrame, which can be used for data analysis. Note that this operation may take time as it converts a server-side object into a client-side object.
Styling the Map Using Style
m = geemap.Map(center=[40, -100], zoom=4)
states = ee.FeatureCollection("TIGER/2018/States")
style = {"color": "0000ffff", "width": 2, "lineType": "solid", "fillColor": "FF000080"}
m.add_layer(states.style(**style), {}, "US States")
m
The above snippet styles the map with specified parameters: color
for the boundary color, width
for the boundary width, linestyle
for the style of the boundary, and fillcolor
for the color filled inside the boundaries. The **style
syntax unpacks the dictionary.
Styling Using a Color Palette
m = geemap.Map(center=[40, -100], zoom=4)
states = ee.FeatureCollection("TIGER/2018/States")
vis_params = {
"color": "000000",
"colorOpacity": 1,
"pointSize": 3,
"pointShape": "circle",
"width": 2,
"lineType": "solid",
"fillColorOpacity": 0.66,
}
palette = ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"]
m.add_styled_vector(
states, column="NAME", palette=palette, layer_name="Styled vector", **vis_params
)
m
This code snippet demonstrates how to style a feature collection using a color palette, allowing for more visually appealing representations based on attribute values.
Clearing All Controls from the Map
To get only the map while clearing all controls available, add the following line:
m.clear_controls()
Clearing Specific Controls
To clear only specific controls, you need to know the names of all the controls. Use the following code:
m = geemap.Map(data_ctrl=False, toolbar_ctrl=False, draw_ctrl=False)
m
Viewing All Controls
To see the names of all the controls, use:
m.controls()
Adding Text to the Map
You can add text to the map and specify its location:
m.add_text(text="Write whatever you want to write here.", position="topright")
You can assign other values like "bottomright", "bottomleft", "topleft" to the location. The text adjusts itself with respect to the controls on the map, ensuring it never overlaps with them.
Adding a Basemap Selector
To add a basemap selector, which helps to change quickly between various basemaps, write the following line:
m.add("basemap_selector")
Map Configuration & Controls
# Advanced map configuration
m = geemap.Map(
center=[40, -100], # Latitude, Longitude
zoom=10, # Higher values = more zoom
height="600px", # Map container height
data_ctrl=False, # Disable data controls
toolbar_ctrl=False, # Hide toolbar
draw_ctrl=False # Remove drawing tools
)
m.clear_controls() # Remove all existing controls
m
The center
parameter takes [latitude, longitude], zoom
controls magnification (4-22 typical range), and height
sets map display size.
Map Customization
# Add interactive elements
m.add_text(
text="Satellite Analysis 2024",
position="topright" # Options: topleft, topright, bottomleft, bottomright
)
m.add("basemap_selector") # Add basemap dropdown
m.add("layer_manager") # Add layer visibility controls
m
Text positioning automatically avoids control overlap. The basemap selector provides quick access to 100+ base layers.
Screenshots


Practical Exercises
To analyze and visualize vegetation health using NDVI from Landsat 8 satellite imagery in Google Earth Engine with Python.
point = ee.Geometry.Point([77.5937, 12.9716])
image = (ee.ImageCollection("LANDSAT/LC08/C02/T1_TOA")
.filterBounds(point)
.filterDate('2022-01-01', '2022-12-31')
.sort('CLOUD_COVER')
.first())
true_color_vis = {
'bands': ['B4', 'B3', 'B2'],
'min': 0, 'max': 0.3
}
ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI')
ndvi_vis = {
'min': 0,
'max': 1,
'palette': ['blue', 'white', 'green']
}
Map = geemap.Map()
Map.centerObject(image, 10)
Map.addLayer(image, true_color_vis, "True Color Image")
Map.addLayer(ndvi, ndvi_vis, "NDVI")
Map
Screenshot

Vegetation health using NDVI from Landsat 8
NDVI Color Interpretation
Color | NDVI Range | Interpretation |
---|---|---|
NDVI ≈ 0 or lower | Water, barren land, or urban areas | |
NDVI ≈ 0.5 | Sparse vegetation or transition zones | |
NDVI ≈ 1 | Dense and healthy vegetation |
Real-Time Flood Detection using GEE & Rainfall Correlation
aoi = ee.Geometry.Rectangle([83.5, 24.5, 88, 27])
pre_flood = (ee.ImageCollection("COPERNICUS/S1_GRD")
.filterBounds(aoi)
.filterDate("2024-05-01", "2024-06-01")
.filter(ee.Filter.listContains("transmitterReceiverPolarisation", "VV"))
.select("VV")
.mean())
post_flood = (ee.ImageCollection("COPERNICUS/S1_GRD")
.filterBounds(aoi)
.filterDate("2024-07-01", "2024-08-01")
.filter(ee.Filter.listContains("transmitterReceiverPolarisation", "VV"))
.select("VV")
.mean())
flood_extent = post_flood.subtract(pre_flood).gt(3)
rainfall = (ee.ImageCollection("UCSB-CHG/CHIRPS/DAILY")
.filterBounds(aoi)
.filterDate("2024-07-01", "2024-08-01")
.mean())
sar_vis_params = {"min": -25, "max": 0, "palette": ["blue", "white", "red"]}
rainfall_vis_params = {"min": 0, "max": 100, "palette": ["yellow", "orange", "red"]}
map_ = geemap.Map()
map_.centerObject(aoi, 7)
map_.addLayer(pre_flood, sar_vis_params, "Pre-Flood (VV)")
map_.addLayer(post_flood, sar_vis_params, "Post-Flood (VV)")
map_.addLayer(flood_extent.selfMask(), {"palette": ["cyan"]}, "Flooded Areas")
map_.addLayer(rainfall, rainfall_vis_params, "Rainfall Intensity")
map_
Screenshot

Real-Time Flood Detection using GEE & Rainfall Correlation
GEE Map Color Legend
Color | Dataset | Meaning |
---|---|---|
CHIRPS Rainfall | Low Rainfall | |
CHIRPS Rainfall | Moderate Rainfall | |
CHIRPS Rainfall | High Rainfall | |
Sentinel-1 SAR | Low backscatter (Possibly water) | |
Sentinel-1 SAR | Mixed land cover | |
Sentinel-1 SAR | High backscatter (Urban, dry land) | |
Flood Extent | Areas that experienced flooding |
Use Cases
- Environmental change detection
- Agricultural monitoring
- Disaster response planning
- Urban development tracking
Conclusion
Geemap revolutionizes geospatial analysis by combining Google Earth Engine's massive data catalog with Python's flexibility. Its intuitive interface and powerful features make it essential for researchers and analysts working with Earth observation data.