AGU 2024
An Introduction to Cloud-Based Geospatial Analysis with Earth Engine and Geemap
- Notebook: https://geemap.org/workshops/AGU_2024
- Earth Engine: https://earthengine.google.com
- Geemap: https://geemap.org
Introduction¶
This notebook is for the workshop presented at the AGU Annual Meeting 2024.
Participants will dive into Google Earth Engine and Geemap to create interactive maps and analyze large-scale geospatial datasets. Topics include:
- Building interactive maps
- Visualizing and analyzing Earth Engine datasets
- Exploring Earth Engine Data Catalogs
- Exporting data for further use
- Creating interactive charts from Earth Engine datasets
- Creating stunning timelapse animations
Prerequisites¶
To use geemap and the Earth Engine Python API, you must register for an Earth Engine account and follow the instructions here to create a Cloud Project. Earth Engine is free for noncommercial and research use. To test whether you can use authenticate the Earth Engine Python API, please run this notebook on Google Colab.
It is recommended that attendees have a basic understanding of Python and Jupyter Notebook.
Familiarity with the Earth Engine JavaScript API is not required but will be helpful.
Attendees can use Google Colab to follow this workshop without installing anything on their computer.
Introduction to Google Earth Engine¶
Google Earth Engine Overview¶
Google Earth Engine is a cloud-computing platform that enables scientific analysis and visualization of large-scale geospatial datasets. It provides a rich data catalog and processing capabilities, allowing users to analyze satellite imagery and geospatial data at planetary scale.
Earth Engine is free for noncommercial and research use. Nonprofit organizations, research institutions, educators, Indigenous governments, and government researchers can continue using Earth Engine for free, as they have for more than a decade. However, commercial users may require a paid license.
Installing Geemap¶
The geemap package simplifies the use of Google Earth Engine in Python, offering an intuitive API for visualization and analysis in Jupyter notebooks. In Google Colab, geemap is pre-installed, but you may need to install additional dependencies for certain features. To install the latest version with optional dependencies, use the following command:
%pip install -U "geemap[workshop]" pycrs mapclassify localtileserver fiona geojson
Import Libraries¶
To start, import the necessary libraries for working with Google Earth Engine (GEE) and geemap.
import ee
import geemap
Authenticate and Initialize Earth Engine¶
To authenticate and initialize your Earth Engine environment, you’ll need to create a Google Cloud Project and enable the Earth Engine API for the project if you have not done so already. You can find detailed setup instructions here.
ee.Authenticate()
Replace YOUR-PROJECT-ID
with your actual Google Cloud Project ID. You can get the project ID from the Earth Engine JavaScript Code Editor.
ee.Initialize(project="YOUR-PROJECT-ID")
Creating Interactive Maps¶
Let’s create an interactive map using the ipyleaflet
plotting backend. The geemap.Map
class inherits from the ipyleaflet.Map
class, so the syntax is similar to creating an interactive map with ipyleaflet.Map
.
m = geemap.Map()
To display the map in a Jupyter notebook, simply enter the map object:
m
To customize the map’s display, you can set various keyword arguments, such as center
(latitude and longitude), zoom
, width
, and height
. By default, the width
is 100%
, filling the entire width of the Jupyter notebook cell. The height
parameter can be a number (in pixels) or a string with a pixel format, e.g., 600px
.
Example Maps¶
Map of the Contiguous United States
To center the map on the contiguous United States, use:
m = geemap.Map(center=[40, -100], zoom=4, height="600px")
m
Map of the state of Tennessee
m = geemap.Map(center=[35.746512, -86.209818], zoom=8)
m
Map of the city of Knoxville, TN
m = geemap.Map(center=[35.959111, -83.909463], zoom=13)
m
To hide specific map controls, set the corresponding control argument to False
, such as draw_ctrl=False
to hide the drawing control.
m = geemap.Map(data_ctrl=False, toolbar_ctrl=False, draw_ctrl=False)
m
Adding Basemaps¶
There are several ways to add basemaps to a map in geemap. You can specify a basemap in the basemap
keyword argument when creating the map, or you can add additional basemap layers using the add_basemap
method. Geemap
provides access to hundreds of built-in basemaps, making it easy to add layers to a map with a single line of code.
To create a map with a specific basemap, use the basemap
argument as shown below. For example, Esri.WorldImagery
provides an Esri world imagery basemap.
m = geemap.Map(basemap="Esri.WorldImagery")
m
Adding Multiple Basemaps¶
You can add multiple basemaps to a map by calling add_basemap
multiple times. For example, the following code adds the Esri.WorldTopoMap
and OpenTopoMap
basemaps to the existing map:
m.add_basemap("Esri.WorldTopoMap")
m.add_basemap("OpenTopoMap")
Listing Available Basemaps¶
To view the first 10 available basemaps, use:
basemaps = list(geemap.basemaps.keys())
len(geemap.basemaps)
basemaps[:10]
Google Basemaps¶
Due to licensing restrictions, Google basemaps are not included in geemap by default. However, users can add Google basemaps manually at their own discretion using the following URLs:
ROADMAP: https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}
SATELLITE: https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}
TERRAIN: https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}
HYBRID: https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}
For example, to add Google Satellite as a tile layer:
m = geemap.Map()
url = "https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}"
m.add_tile_layer(url, name="Google Satellite", attribution="Google")
m
You can also add text to the map using the add_text
method. The text will be displayed at the specified location on the map.
m.add_text(text="Hello from Earth Engine", position="bottomright")
m = geemap.Map()
m.add("basemap_selector")
m
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 = geemap.Map(center=(40, -100), zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
states = ee.FeatureCollection("TIGER/2018/States")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(dem, vis_params, "SRTM DEM")
m.add_layer(states, {}, "US States")
m.add("layer_manager")
m
Inspector Tool¶
The inspector tool allows you to click on the map to query Earth Engine data at specific locations. This is helpful for examining the properties of datasets directly on the map.
m = geemap.Map(center=(40, -100), zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003")
states = ee.FeatureCollection("TIGER/2018/States")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(dem, vis_params, "SRTM DEM")
m.add_layer(
landsat7,
{"bands": ["B4", "B3", "B2"], "min": 20, "max": 200, "gamma": 2.0},
"Landsat 7",
)
m.add_layer(states, {}, "US States")
m.add("inspector")
m
m = geemap.Map(center=(40, -100), zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(dem, vis_params, "SRTM DEM")
m.add("layer_editor", layer_dict=m.ee_layers["SRTM DEM"])
m
Multi-Band image¶
m = geemap.Map(center=(40, -100), zoom=4)
landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003")
m.add_layer(
landsat7,
{"bands": ["B4", "B3", "B2"], "min": 20, "max": 200, "gamma": 2.0},
"Landsat 7",
)
m.add("layer_editor", layer_dict=m.ee_layers["Landsat 7"])
m
Feature Collection¶
m = geemap.Map(center=(40, -100), zoom=4)
states = ee.FeatureCollection("TIGER/2018/States")
m.add_layer(states, {}, "US States")
m.add("layer_editor", layer_dict=m.ee_layers["US States"])
m
Draw Control¶
The draw control feature allows you to draw shapes directly on the map, converting them automatically into Earth Engine objects. Access the drawn features as follows:
- To return the last drawn feature as an
ee.Geometry()
, usem.user_roi
- To return all drawn features as an
ee.FeatureCollection()
, usem.user_rois
m = geemap.Map(center=(40, -100), zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
vis_params = {
"min": 0,
"max": 4000,
"palette": "terrain",
}
m.add_layer(dem, vis_params, "SRTM DEM")
m.add("layer_manager")
m
if m.user_roi is not None:
image = dem.clip(m.user_roi)
m.layers[1].visible = False
m.add_layer(image, vis_params, "Clipped DEM")
The Earth Engine Data Catalog¶
The Earth Engine Data Catalog hosts an extensive collection of geospatial datasets. Currently, he catalog includes over 1,000 datasets with a combined size exceeding 100 petabytes. Notable datasets include Landsat, Sentinel, MODIS, and NAIP. For a comprehensive list of datasets in CSV or JSON format, refer to the Earth Engine Datasets List.
Searching Datasets on the Earth Engine Website¶
To browse datasets directly on the Earth Engine website:
- View the full catalog: https://developers.google.com/earth-engine/datasets/catalog
- Search by tags: https://developers.google.com/earth-engine/datasets/tags
Searching Datasets Within Geemap¶
The Earth Engine Data Catalog can also be searched directly from geemap
. Use keywords to filter datasets by name, tag, or description. For instance, searching for "elevation" will display only datasets containing "elevation" in their metadata, returning 52 datasets. You can scroll through the results to locate the NASA SRTM Digital Elevation 30m dataset.
m = geemap.Map()
m
Each dataset page contains detailed information such as availability, provider, Earth Engine snippet, tags, description, and example code. The Image, ImageCollection, or FeatureCollection ID is essential for accessing the dataset in Earth Engine’s JavaScript or Python APIs.
Using the Datasets Module in Geemap¶
Geemap offers a built-in datasets
module to access specific datasets programmatically. For example, to access the USGS GAP Alaska dataset:
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
To retrieve metadata for a specific dataset, use the get_metadata
function:
from geemap.datasets import get_metadata
get_metadata(DATA.USGS_GAP_AK_2001)
Earth Engine Data Types¶
Earth Engine objects are server-side entities, meaning they are stored and processed on Earth Engine’s servers rather than locally. This setup is comparable to streaming services (e.g., YouTube or Netflix) where the data remains on the provider’s servers, allowing us to access and process geospatial data in real time without downloading it to our local devices.
- Image: The core raster data type in Earth Engine, representing single images or scenes.
- ImageCollection: A collection or sequence of images, often used for time series analysis.
- Geometry: The fundamental vector data type, including shapes like points, lines, and polygons.
- Feature: A Geometry with associated attributes, used to add descriptive data to vector shapes.
- FeatureCollection: A collection of Features, similar to a shapefile with attribute data.
Earth Engine Raster Data¶
Image¶
In Earth Engine, raster data is represented as Image objects. Each Image is composed of bands, with each band having its own name, data type, scale, mask, and projection. Metadata for each image is stored as a set of properties.
Loading Earth Engine Images¶
To load images, use the Earth Engine asset ID within the ee.Image
constructor. Asset IDs can be found in the Earth Engine Data Catalog. For example, to load the NASA SRTM Digital Elevation dataset:
image = ee.Image("USGS/SRTMGL1_003")
image
Visualizing Earth Engine Images¶
To visualize an image, you can specify visualization parameters such as minimum and maximum values and color palettes.
m = geemap.Map(center=[21.79, 70.87], zoom=3)
image = ee.Image("USGS/SRTMGL1_003")
vis_params = {
"min": 0,
"max": 6000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"], # 'terrain'
}
m.add_layer(image, vis_params, "SRTM")
m
ImageCollection¶
An ImageCollection represents a sequence of images, often used for temporal data like satellite image time series. ImageCollections are created by passing an Earth Engine asset ID into the ImageCollection
constructor. Asset IDs are available in the Earth Engine Data Catalog.
Loading Image Collections¶
To load an ImageCollection, such as the Sentinel-2 surface reflectance collection:
collection = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
Filtering Image Collections¶
You can filter ImageCollections by location and time. For example, to filter images covering a specific location with low cloud cover:
geometry = ee.Geometry.Point([-83.909463, 35.959111])
images = collection.filterBounds(geometry)
images.size()
images.first()
images = (
collection.filterBounds(geometry)
.filterDate("2024-07-01", "2024-10-01")
.filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE", 5))
)
images.size()
To view the filtered collection on a map:
m = geemap.Map()
image = images.first()
vis = {
"min": 0.0,
"max": 3000,
"bands": ["B4", "B3", "B2"],
}
m.add_layer(image, vis, "Sentinel-2")
m.centerObject(image, 8)
m
Visualizing Image Collections¶
To visualize an ImageCollection as a single composite image, you need to aggregate the collection. For example, using the collection.median()
method creates an image representing the median value across the collection.
m = geemap.Map()
image = images.median()
vis = {
"min": 0.0,
"max": 3000,
"bands": ["B8", "B4", "B3"],
}
m.add_layer(image, vis, "Sentinel-2")
m.centerObject(geometry, 8)
m
Earth Engine Vector Data¶
A FeatureCollection is a collection of Features. It functions similarly to a GeoJSON FeatureCollection, where features include associated properties or attributes. For example, a shapefile’s data can be represented as a FeatureCollection.
Loading Feature Collections¶
The Earth Engine Data Catalog includes various vector datasets, such as U.S. Census data and country boundaries, as feature collections. Feature Collection IDs are accessible by searching the data catalog. For example, to load the TIGER roads data by the U.S. Census Bureau:
m = geemap.Map()
fc = ee.FeatureCollection("TIGER/2016/Roads")
m.set_center(-83.909463, 35.959111, 12)
m.add_layer(fc, {}, "Census roads")
m
Filtering Feature Collections¶
The filter
method allows you to filter a FeatureCollection based on certain attribute values. For instance, we can filter for specific states using the eq
filter to select "Tennessee":
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
To retrieve properties of the first feature in the collection, use:
feat = fc.first()
feat.toDictionary()
You can also convert a FeatureCollection to a Pandas DataFrame for easier analysis with:
geemap.ee_to_df(fc)
m = geemap.Map()
states = ee.FeatureCollection("TIGER/2018/States")
fc = states.filter(ee.Filter.inList("NAME", ["California", "Oregon", "Washington"]))
m.add_layer(fc, {}, "West Coast")
m.center_object(fc, 5)
m
region = m.user_roi
if region is None:
region = ee.Geometry.BBox(-88.40, 29.88, -77.90, 35.39)
fc = ee.FeatureCollection("TIGER/2018/States").filterBounds(region)
m.add_layer(fc, {}, "Southeastern U.S.")
m.center_object(fc, 6)
A FeatureCollection can be used to clip an image. The clipToCollection
method clips an image to the geometry of a feature collection. For example, to clip a Landsat image to the boundary of France:
m = geemap.Map(center=(40, -100), zoom=4)
landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003")
countries = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level0")
fc = countries.filter(ee.Filter.eq("ADM0_NAME", "Germany"))
image = landsat7.clipToCollection(fc)
m.add_layer(
image,
{"bands": ["B4", "B3", "B2"], "min": 20, "max": 200, "gamma": 2.0},
"Landsat 7",
)
m.center_object(fc, 6)
m
Visualizing Feature Collections¶
Once loaded, feature collections can be visualized on an interactive map. For example, visualizing U.S. state boundaries from the census data:
m = geemap.Map(center=[40, -100], zoom=4)
states = ee.FeatureCollection("TIGER/2018/States")
m.add_layer(states, {}, "US States")
m
Feature collections can also be styled with additional parameters. To apply a custom style, specify options like color and line width:
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
Using add_styled_vector
, you can apply a color palette to style different features by attribute:
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
More Tools for Visualizing Earth Engine Data¶
Using the Plotting Tool¶
The plotting tool in geemap enables visualization of Earth Engine data layers. In this example, Landsat 7 and Hyperion data are added with specific visualization parameters, allowing for comparison of these datasets. The plot GUI is then added to facilitate detailed exploration of the data.
m = geemap.Map(center=[40, -100], zoom=4)
landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003").select(
["B1", "B2", "B3", "B4", "B5", "B7"]
)
landsat_vis = {"bands": ["B4", "B3", "B2"], "gamma": 1.4}
m.add_layer(landsat7, landsat_vis, "Landsat")
hyperion = ee.ImageCollection("EO1/HYPERION").filter(
ee.Filter.date("2016-01-01", "2017-03-01")
)
hyperion_vis = {
"min": 1000.0,
"max": 14000.0,
"gamma": 2.5,
}
m.add_layer(hyperion, hyperion_vis, "Hyperion")
m.add_plot_gui()
m
Set the plotting options for Landsat to add marker clusters and overlays, enhancing the interactivity of plotted data on the map.
m.set_plot_options(add_marker_cluster=True, overlay=True)
Adjust the plotting options for Hyperion data by setting a bar plot type with marker clusters, suitable for visualizing Hyperion’s data values in bar format.
m.set_plot_options(add_marker_cluster=True, plot_type="bar")
from geemap.legends import builtin_legends
Print out all available built-in legends, which can be used with various data layers to enhance map readability.
for legend in builtin_legends:
print(legend)
Add an NLCD WMS layer along with its corresponding legend, which appears as an overlay, providing users with an informative legend display.
m = geemap.Map(center=[40, -100], zoom=4)
m.add_basemap("Esri.WorldImagery")
m.add_basemap("NLCD 2021 CONUS Land Cover")
m.add_legend(builtin_legend="NLCD", max_width="100px", height="455px")
m
Add an Earth Engine layer for NLCD land cover and display its legend, specifying title, legend type, and dimensions for user convenience.
m = geemap.Map(center=[40, -100], zoom=4)
m.add_basemap("Esri.WorldImagery")
nlcd = ee.Image("USGS/NLCD_RELEASES/2021_REL/NLCD/2021")
landcover = nlcd.select("landcover")
m.add_layer(landcover, {}, "NLCD Land Cover 2021")
m.add_legend(
title="NLCD Land Cover Classification", builtin_legend="NLCD", height="455px"
)
m
Custom Legends¶
Create a custom legend by defining unique labels and colors for each class, allowing for flexible map customization. This example uses a color palette for labeling several map categories.
m = geemap.Map(add_google_map=False)
keys = ["One", "Two", "Three", "Four", "etc"]
# colors can be defined using either hex code or RGB (0-255, 0-255, 0-255)
colors = ["#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#80B1D3"]
# legend_colors = [(255, 0, 0), (127, 255, 0), (127, 18, 25), (36, 70, 180), (96, 68 123)]
m.add_legend(keys=keys, colors=colors, position="bottomright")
m
Define a custom legend using a dictionary that links specific colors to labels. This approach provides flexibility to represent specific categories in the data, such as various land cover types.
m = geemap.Map(center=[40, -100], zoom=4)
m.add_basemap("Esri.WorldImagery")
legend_dict = {
"11 Open Water": "466b9f",
"12 Perennial Ice/Snow": "d1def8",
"21 Developed, Open Space": "dec5c5",
"22 Developed, Low Intensity": "d99282",
"23 Developed, Medium Intensity": "eb0000",
"24 Developed High Intensity": "ab0000",
"31 Barren Land (Rock/Sand/Clay)": "b3ac9f",
"41 Deciduous Forest": "68ab5f",
"42 Evergreen Forest": "1c5f2c",
"43 Mixed Forest": "b5c58f",
"51 Dwarf Scrub": "af963c",
"52 Shrub/Scrub": "ccb879",
"71 Grassland/Herbaceous": "dfdfc2",
"72 Sedge/Herbaceous": "d1d182",
"73 Lichens": "a3cc51",
"74 Moss": "82ba9e",
"81 Pasture/Hay": "dcd939",
"82 Cultivated Crops": "ab6c28",
"90 Woody Wetlands": "b8d9eb",
"95 Emergent Herbaceous Wetlands": "6c9fb8",
}
nlcd = ee.Image("USGS/NLCD_RELEASES/2021_REL/NLCD/2021")
landcover = nlcd.select("landcover")
m.add_layer(landcover, {}, "NLCD Land Cover 2021")
m.add_legend(title="NLCD Land Cover Classification", legend_dict=legend_dict)
m
Color Bars¶
Add a horizontal color bar representing elevation data. This example demonstrates how to add an SRTM elevation layer and overlay a color bar for quick visual reference of elevation values.
m = geemap.Map()
dem = ee.Image("USGS/SRTMGL1_003")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(dem, vis_params, "SRTM DEM")
m.add_colorbar(vis_params, label="Elevation (m)", layer_name="SRTM DEM")
m
Add a vertical color bar for elevation data, adjusting its orientation and dimensions to fit the map layout.
m.add_colorbar(
vis_params,
label="Elevation (m)",
layer_name="SRTM DEM",
orientation="vertical",
max_width="100px",
)
Make the color bar’s background transparent, which improves visual integration with the map when adding color bars for data layers.
m.add_colorbar(
vis_params,
label="Elevation (m)",
layer_name="SRTM DEM",
orientation="vertical",
max_width="100px",
transparent_bg=True,
)
Split-panel Maps¶
Create a split-panel map with basemaps, allowing users to compare two different basemaps side by side.
m = geemap.Map()
m.split_map(left_layer="Esri.WorldTopoMap", right_layer="OpenTopoMap")
m
Use Earth Engine layers in a split-panel map to compare NLCD data from 2001 and 2021. This layout is effective for examining changes between datasets across time.
m = geemap.Map(center=(40, -100), zoom=4, height=600)
nlcd_2001 = ee.Image("USGS/NLCD_RELEASES/2019_REL/NLCD/2001").select("landcover")
nlcd_2021 = ee.Image("USGS/NLCD_RELEASES/2021_REL/NLCD/2021").select("landcover")
left_layer = geemap.ee_tile_layer(nlcd_2001, {}, "NLCD 2001")
right_layer = geemap.ee_tile_layer(nlcd_2021, {}, "NLCD 2021")
m.split_map(left_layer, right_layer)
m
Linked Maps¶
Set up a 2x2 grid of linked maps showing Sentinel-2 imagery in different band combinations, ideal for comparing multiple visual perspectives. Note that this feature may not work in Colab.
image = (
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
.filterDate("2024-07-01", "2024-10-01")
.filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE", 5))
.map(lambda img: img.divide(10000))
.median()
)
vis_params = [
{"bands": ["B4", "B3", "B2"], "min": 0, "max": 0.3, "gamma": 1.3},
{"bands": ["B8", "B11", "B4"], "min": 0, "max": 0.3, "gamma": 1.3},
{"bands": ["B8", "B4", "B3"], "min": 0, "max": 0.3, "gamma": 1.3},
{"bands": ["B12", "B12", "B4"], "min": 0, "max": 0.3, "gamma": 1.3},
]
labels = [
"Natural Color (B4/B3/B2)",
"Land/Water (B8/B11/B4)",
"Color Infrared (B8/B4/B3)",
"Vegetation (B12/B11/B4)",
]
geemap.linked_maps(
rows=2,
cols=2,
height="300px",
center=[35.959111, -83.909463],
zoom=12,
ee_objects=[image],
vis_params=vis_params,
labels=labels,
label_position="topright",
)
Timeseries Inspector¶
Retrieve the available years in the NLCD collection for setting up a timeseries. This step helps confirm available time points for inspecting changes over time.
m = geemap.Map(center=[40, -100], zoom=4)
collection = ee.ImageCollection("USGS/NLCD_RELEASES/2019_REL/NLCD").select("landcover")
vis_params = {"bands": ["landcover"]}
years = collection.aggregate_array("system:index").getInfo()
years
Use a timeseries inspector to compare changes in NLCD data across different years. This tool is ideal for temporal data visualization, showing how land cover changes in an interactive format.
m.ts_inspector(
left_ts=collection,
right_ts=collection,
left_names=years,
right_names=years,
left_vis=vis_params,
right_vis=vis_params,
width="80px",
)
m
Time Slider¶
Create a time slider to explore MODIS vegetation data, setting the slider to visualize NDVI values over a specific period. This feature allows users to track vegetation changes month-by-month.
m = geemap.Map()
collection = (
ee.ImageCollection("MODIS/MCD43A4_006_NDVI")
.filter(ee.Filter.date("2018-06-01", "2018-07-01"))
.select("NDVI")
)
vis_params = {
"min": 0.0,
"max": 1.0,
"palette": "ndvi",
}
m.add_time_slider(collection, vis_params, time_interval=2)
m
Add a time slider for visualizing NOAA weather data over a 24-hour period, using color-coding to show temperature variations. The slider enables temporal exploration of hourly data.
m = geemap.Map()
collection = (
ee.ImageCollection("NOAA/GFS0P25")
.filterDate("2018-12-22", "2018-12-23")
.limit(24)
.select("temperature_2m_above_ground")
)
vis_params = {
"min": -40.0,
"max": 35.0,
"palette": ["blue", "purple", "cyan", "green", "yellow", "red"],
}
labels = [str(n).zfill(2) + ":00" for n in range(0, 24)]
m.add_time_slider(collection, vis_params, labels=labels, time_interval=1, opacity=0.8)
m
Add a time slider to visualize Sentinel-2 imagery with specific bands and cloud cover filtering. This feature enables temporal analysis of imagery data, allowing users to explore seasonal and other changes over time.
m = geemap.Map()
collection = (
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
.filterBounds(ee.Geometry.Point([-83.909463, 35.959111]))
.filterMetadata("CLOUDY_PIXEL_PERCENTAGE", "less_than", 10)
.filter(ee.Filter.calendarRange(6, 8, "month"))
)
vis_params = {"min": 0, "max": 4000, "bands": ["B8", "B4", "B3"]}
m.add_time_slider(collection, vis_params)
m.set_center(-83.909463, 35.959111, 12)
m
in_geojson = "https://github.com/gee-community/geemap/blob/master/examples/data/countries.geojson"
m = geemap.Map()
fc = geemap.geojson_to_ee(in_geojson)
m.add_layer(fc.style(**{"color": "ff0000", "fillColor": "00000000"}), {}, "Countries")
m
From Shapefile¶
Download and load a shapefile of country boundaries. The shapefile is converted to a FeatureCollection for visualization on the map.
url = "https://github.com/gee-community/geemap/blob/master/examples/data/countries.zip"
geemap.download_file(url, overwrite=True)
in_shp = "countries.shp"
fc = geemap.shp_to_ee(in_shp)
m = geemap.Map()
m.add_layer(fc, {}, "Countries")
m
From GeoDataFrame¶
Read a shapefile into a GeoDataFrame using geopandas, then convert the GeoDataFrame to an Earth Engine FeatureCollection for mapping.
import geopandas as gpd
gdf = gpd.read_file(in_shp)
fc = geemap.gdf_to_ee(gdf)
m = geemap.Map()
m.add_layer(fc, {}, "Countries")
m
To GeoJSON¶
Filter U.S. state data to select Tennessee and save it as a GeoJSON file, which can be shared or used in other GIS tools.
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
geemap.ee_to_geojson(fc, filename="Tennessee.geojson")
To Shapefile¶
Export the filtered Tennessee FeatureCollection to a shapefile format for offline use or compatibility with desktop GIS software.
geemap.ee_to_shp(fc, filename="Tennessee.shp")
To GeoDataFrame¶
Convert an Earth Engine FeatureCollection to a GeoDataFrame for further analysis in Python or use in interactive maps.
gdf = geemap.ee_to_gdf(fc)
gdf
gdf.explore()
To DataFrame¶
Transform an Earth Engine FeatureCollection into a pandas DataFrame, which can then be used for data analysis in Python.
df = geemap.ee_to_df(fc)
df
To CSV¶
Export the FeatureCollection data to a CSV file, useful for spreadsheet applications and data reporting.
geemap.ee_to_csv(fc, filename="Indiana.csv")
m = geemap.Map(center=[40, -100], zoom=4)
dem = ee.Image("USGS/SRTMGL1_003")
landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(
landsat7,
{"bands": ["B4", "B3", "B2"], "min": 20, "max": 200, "gamma": 2},
"Landsat 7",
)
m.add_layer(dem, vis_params, "SRTM DEM", True, 1)
m
in_shp = "us_cities.shp"
url = "https://github.com/giswqs/data/raw/main/us/us_cities.zip"
geemap.download_file(url)
in_fc = geemap.shp_to_ee(in_shp)
m.add_layer(in_fc, {}, "Cities")
geemap.extract_values_to_points(in_fc, dem, out_fc="dem.shp", scale=1000)
geemap.shp_to_gdf("dem.shp")
geemap.extract_values_to_points(in_fc, landsat7, "landsat.csv", scale=100)
geemap.csv_to_df("landsat.csv")
Extracting Pixel Values Along a Transect¶
Visualize SRTM DEM with a terrain basemap. Define a line transect, either interactively or manually, and extract elevation values along this line. Display the elevation profile in a line chart, then export it as a CSV file for further analysis.
m = geemap.Map(center=[40, -100], zoom=4)
m.add_basemap("TERRAIN")
image = ee.Image("USGS/SRTMGL1_003")
vis_params = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(image, vis_params, "SRTM DEM", True, 0.5)
m
line = m.user_roi
if line is None:
line = ee.Geometry.LineString(
[[-120.2232, 36.3148], [-118.9269, 36.7121], [-117.2022, 36.7562]]
)
m.add_layer(line, {}, "ROI")
m.centerObject(line)
reducer = "mean"
transect = geemap.extract_transect(
image, line, n_segments=100, reducer=reducer, to_pandas=True
)
transect
geemap.line_chart(
data=transect,
x="distance",
y="mean",
markers=True,
x_label="Distance (m)",
y_label="Elevation (m)",
height=400,
)
transect.to_csv("transect.csv")
Zonal Statistics¶
Zonal Statistics with an Image and a Feature Collection¶
This section demonstrates the use of zonal statistics to calculate the mean elevation values within U.S. state boundaries using NASA’s SRTM DEM data and a 5-year Landsat composite. The geemap.zonal_stats
function exports results to CSV files for analysis.
m = geemap.Map(center=[40, -100], zoom=4)
# Add NASA SRTM
dem = ee.Image("USGS/SRTMGL1_003")
dem_vis = {
"min": 0,
"max": 4000,
"palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"],
}
m.add_layer(dem, dem_vis, "SRTM DEM")
# Add 5-year Landsat TOA composite
landsat = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003")
landsat_vis = {"bands": ["B4", "B3", "B2"], "gamma": 1.4}
m.add_layer(landsat, landsat_vis, "Landsat", False)
# Add US Census States
states = ee.FeatureCollection("TIGER/2018/States")
style = {"fillColor": "00000000"}
m.add_layer(states.style(**style), {}, "US States")
m
out_dem_stats = "dem_stats.csv"
geemap.zonal_stats(
dem, states, out_dem_stats, statistics_type="MEAN", scale=1000, return_fc=False
)
out_landsat_stats = "landsat_stats.csv"
geemap.zonal_stats(
landsat,
states,
out_landsat_stats,
statistics_type="MEAN",
scale=1000,
return_fc=False