Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Interactive Mapping & Visualization

Introduction

Learning Objectives

Creating Interactive Maps with Leafmap

Your First Map

import leafmap

m = leafmap.Map(center=[36.1617, -115.1524], zoom=11, height="600px")
m

Adding Basemaps

m = leafmap.Map()
m.add_basemap("Esri.WorldImagery")
m
basemaps = list(leafmap.basemaps.keys())
print(f"Total basemaps: {len(basemaps)}")
print("First 10:", basemaps[:10])
m = leafmap.Map()
m.add_basemap("Esri.WorldImagery")
m.add_basemap("OpenTopoMap")
m

Working with Raster Data on Maps

Adding GeoTIFF Layers

import geoai
naip_url = "https://data.source.coop/opengeos/geoai/las-vegas-train-naip.tif"
hag_url = "https://data.source.coop/opengeos/geoai/las-vegas-train-hag.tif"
buildings_url = (
    "https://data.source.coop/opengeos/geoai/las-vegas-buildings-train.geojson"
)
buildings_mask_url = (
    "https://data.source.coop/opengeos/geoai/las-vegas-buildings-mask.tif"
)
naip_path = geoai.download_file(naip_url)
hag_path = geoai.download_file(hag_url)
buildings_path = geoai.download_file(buildings_url)
mask_path = geoai.download_file(buildings_mask_url)
m = leafmap.Map()
m.add_raster(naip_path, layer_name="NAIP Image")
m
m.add_raster(
    hag_path, vmin=0, vmax=10, colormap="terrain", layer_name="Height Above Ground"
)

Cloud-Optimized GeoTIFF (COG)

m = leafmap.Map()
m.add_cog_layer(naip_url, name="Las Vegas NAIP")
m

Band Combinations

m = leafmap.Map()
m.add_raster(naip_path, indexes=[4, 1, 2], layer_name="False Color")
m

Visualizing Data from Planetary Computer

Browsing Available Collections

collections = geoai.pc_collection_list()
print(f"Total collections: {len(collections)}")
collections.head(10)

Searching for STAC Items

naip_items = geoai.pc_stac_search(
    collection="naip",
    bbox=[-76.6657, 39.2648, -76.6478, 39.2724],
    time_range="2013-01-01/2014-12-31",
)
naip_items
geoai.pc_item_asset_list(naip_items[0])

Visualizing NAIP Imagery

geoai.view_pc_item(item=naip_items[0])

Visualizing Land Cover Data

lc_items = geoai.pc_stac_search(
    collection="chesapeake-lc-13",
    bbox=[-76.6657, 39.2648, -76.6478, 39.2724],
    time_range="2013-01-01/2014-12-31",
    max_items=10,
)
lc_items
geoai.view_pc_item(item=lc_items[0], colormap_name="tab10", basemap="SATELLITE")

Visualizing Landsat Imagery

landsat_items = geoai.pc_stac_search(
    collection="landsat-c2-l2",
    bbox=[-76.6657, 39.2648, -76.6478, 39.2724],
    time_range="2024-10-27/2024-12-31",
    query={"eo:cloud_cover": {"lt": 1}},
    max_items=10,
)
landsat_items
geoai.pc_item_asset_list(landsat_items[0])
geoai.view_pc_item(item=landsat_items[0], assets=["red", "green", "blue"])
geoai.view_pc_item(item=landsat_items[0], assets=["nir08", "red", "green"])
geoai.view_pc_item(
    item=landsat_items[0],
    expression="(nir08-red)/(nir08+red)",
    rescale="-1,1",
    colormap_name="greens",
    name="NDVI",
)

Downloading Data from Planetary Computer

geoai.pc_stac_download(naip_items, output_dir="data", assets=["image", "thumbnail"])
ds = geoai.read_pc_item_asset(lc_items[0], asset="data")
ds

Working with Vector Data on Maps

Adding GeoJSON and GeoDataFrame

import geopandas as gpd

gdf = gpd.read_file(buildings_path)
print(f"Features: {len(gdf)}")
gdf.head()
m = leafmap.Map()
m.add_raster(naip_path)
m.add_gdf(gdf, layer_name="Building Footprints", zoom_to_layer=True)
m
m = leafmap.Map()
m.add_raster(naip_path)
m.add_geojson(buildings_url, layer_name="Buildings", zoom_to_layer=True)
m

Styling Vector Layers

style = {
    "color": "red",
    "weight": 2,
    "fillColor": "yellow",
    "fillOpacity": 0.3,
}
m = leafmap.Map()
m.add_raster(naip_path)
m.add_gdf(gdf, layer_name="Styled Buildings", style=style, zoom_to_layer=True)
m

Adding Markers and Points

m = leafmap.Map(center=[36.1617, -115.1524], zoom=11)
m.add_marker(location=[36.1617, -115.1524])
m

Split-Panel Maps for Comparison

Side-by-Side Comparison

m = leafmap.Map()
m.split_map(
    left_layer=naip_path,
    right_layer=hag_path,
    left_args={"indexes": [4, 1, 2]},
    right_args={"vmin": 0, "vmax": 10, "cmap": "terrain"},
    left_label="NAIP",
    right_label="HAG",
)
m

Visualizing Model Results

Overlaying Predictions

m = leafmap.Map()
m.add_raster(naip_path, layer_name="NAIP Imagery")
m.add_raster(mask_path, opacity=0.8, nodata=0, layer_name="Building Mask")
m

Comparing Labels with Source Imagery

import leafmap

m = leafmap.Map()
m.split_map(
    left_layer=buildings_path,
    right_layer=naip_path,
    left_args={"style": {"color": "red", "fillOpacity": 0.2}},
)
m
geoai.create_split_map(
    left_layer=buildings_path,
    right_layer=naip_path,
    left_args={"style": {"color": "red", "fillOpacity": 0.2}},
    basemap=naip_path,
)

Best Practices for GeoAI Visualization

Key Takeaways

Exercises

Exercise 1: Create a Custom Basemap Map

Exercise 2: Visualize a Raster with Multiple Colormaps

Exercise 3: Style and Explore Vector Data

Exercise 4: Build a Split-Panel Comparison

Exercise 5: Overlay and Compare Building Layers