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:
    python --version
    If Python is not installed, download it from python.org.
  • 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

Geemap interface with layer controls

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

Geemap interface with layer controls

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

Geemap interface with layer controls

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

Geemap interface with layer controls

Geemap interface with layer controls

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

Geemap interface with layer controls

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

Geemap interface with layer controls

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.

References