Introduction¶
Learning Objectives¶
Sample Datasets¶
Installation and Setup¶
# %pip install -U "leafmap[pmtiles]"import duckdb
import leafmap.maplibregl as leafmapVisualizing Vector Tiles Directly from Files¶
Configuring JupyterHub Access (Optional)¶
# leafmap.configure_jupyterhub("https://your-jupyterhub-domain.com")Visualizing Data from Vector Files¶
url = "https://data.source.coop/giswqs/nwi/wetlands/RI_Wetlands.parquet"
filepath = leafmap.download_file(url)m = leafmap.Map(style="liberty", height="600px")
m.add_basemap("Esri.WorldImagery")
m.add_duckdb_layer(
data=filepath,
layer_name="wetlands",
layer_type="fill",
paint={"fill-color": "#3388ff"},
opacity=0.5,
fit_bounds=True,
use_view=False,
min_zoom=None,
quiet=False,
)
mVisualizing Data from Existing DuckDB Databases¶
url = "https://data.gishub.org/duckdb/nyc_data.db.zip"
leafmap.download_file(url, unzip=True)db_path = "nyc_data.db"
con = duckdb.connect(db_path)con.install_extension("spatial")
con.load_extension("spatial")con.sql("SHOW TABLES;")con.close()m = leafmap.Map(
center=[-73.9031255, 40.7127753], zoom=9, style="positron", height="600px"
)
m.add_basemap("Esri.WorldImagery")
m.add_duckdb_layer(
database_path=db_path,
table_name="nyc_census_blocks",
layer_name="Census Blocks",
layer_type="fill",
paint={"fill-color": "#3388ff", "fill-outline-color": "#ffffff"},
opacity=0.5,
fit_bounds=False,
src_crs="EPSG:26918",
quiet=True,
)
mConverting Vector Data to PMTiles¶
Understanding Coordinate Transformations for PMTiles¶
Exporting a Global Cities Dataset to PMTiles¶
con = duckdb.connect()
con.install_extension("spatial")
con.load_extension("spatial")con.sql(
"""
COPY (
SELECT * EXCLUDE (geometry),
ST_Transform(geometry, 'EPSG:4326', 'EPSG:3857', true) AS geometry
FROM 'https://data.gishub.org/duckdb/cities.parquet'
)
TO 'cities.pmtiles'
WITH (
FORMAT GDAL,
DRIVER 'PMTiles',
LAYER_CREATION_OPTIONS ('MINZOOM=0', 'MAXZOOM=14')
)
"""
)Visualizing PMTiles¶
Visualizing Local PMTiles with Martin Tile Server¶
process = leafmap.start_martin(pmtiles=["cities.pmtiles"])m = leafmap.Map(style="positron")
url = "http://localhost:3000/cities"
paint = {
"circle-color": "#3388ff",
"circle-radius": 4,
"circle-opacity": 0.5,
"circle-stroke-color": "#ffffff",
"circle-stroke-width": 1,
}
m.add_vector_tile(
url, layer_id="cities", layer_type="circle", name="World Cities", paint=paint
)
mleafmap.stop_martin(process)Visualizing Cloud-Hosted PMTiles¶
release = "2025-10-22"
url = f"https://overturemaps-tiles-us-west-2-beta.s3.amazonaws.com/{release}/buildings.pmtiles"
print(url)Creating 3D Building Visualizations¶
m = leafmap.Map(
center=[-74.0095, 40.7046], zoom=15, pitch=60, bearing=-17, style="positron"
)
m.add_basemap("OpenStreetMap.Mapnik")
m.add_basemap("Esri.WorldImagery", visible=False)
value_color_pairs = [0, "lightgray", 200, "royalblue", 400, "lightblue"]
style = {
"layers": [
{
"id": "Building",
"source": "buildings",
"source-layer": "building",
"type": "fill-extrusion",
"filter": [
">",
["get", "height"],
0,
],
"paint": {
"fill-extrusion-color": [
"interpolate",
["linear"],
["get", "height"],
]
+ value_color_pairs,
"fill-extrusion-height": ["*", ["get", "height"], 1],
},
},
{
"id": "Building-part",
"source": "buildings",
"source-layer": "building_part",
"type": "fill-extrusion",
"filter": [
">",
["get", "height"],
0,
],
"paint": {
"fill-extrusion-color": [
"interpolate",
["linear"],
["get", "height"],
]
+ value_color_pairs,
"fill-extrusion-height": ["*", ["get", "height"], 1],
},
},
],
}
m.add_pmtiles(
url,
style=style,
visible=True,
opacity=1.0,
tooltip=True,
fit_bounds=False,
)
mSimplified 3D Building Visualization¶
m = leafmap.Map(
center=[-74.0095, 40.7046], zoom=15, pitch=60, bearing=-17, style="positron"
)
m.add_basemap("OpenStreetMap.Mapnik")
m.add_basemap("Esri.WorldImagery", visible=False)
m.add_overture_3d_buildings(
values=[0, 200, 400], colors=["lightgray", "royalblue", "lightblue"]
)
mVisualizing 2D Building Footprints¶
m = leafmap.Map(center=[-74.0095, 40.7046], zoom=15)
m.add_basemap("OpenStreetMap.Mapnik")
m.add_basemap("Esri.WorldImagery", visible=True)
m.add_overture_data(theme="buildings", opacity=0.8)
mm = leafmap.Map(center=[-74.0095, 40.7046], zoom=16)
m.add_basemap("OpenStreetMap.Mapnik")
m.add_basemap("Esri.WorldImagery", visible=True)
m.add_overture_buildings(type="line", line_color="#ff0000", line_width=2, opacity=0.7)
mVisualizing Overture Transportation Networks¶
m = leafmap.Map(center=[-74.0095, 40.7046], zoom=16)
m.add_basemap("Esri.WorldImagery", visible=True)
m.add_overture_data(theme="transportation", opacity=0.8)
mVisualizing Overture Places¶
m = leafmap.Map(center=[-74.0095, 40.7046], zoom=16)
m.add_basemap("Esri.WorldImagery", visible=True)
m.add_overture_data(theme="places", opacity=0.8)
mKey Takeaways¶
Exercises¶
Exercise 1: Visualizing Local Vector Files with On-the-Fly Tiling¶
Exercise 2: Visualizing Data from DuckDB Database¶
Exercise 3: Converting Spatial Data to PMTiles¶
Exercise 4: Serving and Visualizing Local PMTiles¶
Exercise 5: Exporting NYC Data to PMTiles¶
Exercise 6: Multi-Layer PMTiles Visualization¶
Exercise 7: Visualizing Cloud-Hosted Overture Data¶
Exercise 8: Custom 3D Building Visualization¶
Exercise 9: Overture Transportation Network Analysis¶
Exercise 10: Complete Spatial Analysis to PMTiles Workflow¶