Skip to content

Docs add lonboard tutorial#529

Open
aboydnw wants to merge 3 commits into
microsoft:developfrom
aboydnw:docs-add-lonboard-tutorial
Open

Docs add lonboard tutorial#529
aboydnw wants to merge 3 commits into
microsoft:developfrom
aboydnw:docs-add-lonboard-tutorial

Conversation

@aboydnw
Copy link
Copy Markdown
Contributor

@aboydnw aboydnw commented Jun 2, 2026

Based on the outline here

Related notebook: microsoft/PlanetaryComputerExamples#316

aboydnw and others added 3 commits May 30, 2026 00:11
Adds a tutorial walking through interactive Planetary Computer raster
and vector visualization with Lonboard. Companion notebook lives in
PlanetaryComputerExamples at quickstarts/lonboard.ipynb and is wired
in via external_docs_config.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The tutorial taught lonboard.experimental.RasterLayer.from_stac, which
exists in no released lonboard and made the "no tile server" claim rest
on a nonexistent client-side COG renderer. Repivot to lonboard's shipping
strength — GPU vector rendering — using Microsoft Building Footprints:
read a STAC GeoParquet quadkey partition, render the footprints with
PolygonLayer, and color by meanHeight via apply_continuous_cmap. Geometry
streams as Arrow, so "no tile server" is now literally true. Add the
footprints and height-colored screenshots.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aboydnw aboydnw marked this pull request as ready for review June 2, 2026 20:35
Comment thread docs/overview/lonboard.md
@@ -0,0 +1,126 @@
# Visualizing Planetary Computer data with Lonboard

[Lonboard](https://developmentseed.org/lonboard/) is a Python library for interactive geospatial visualization in Jupyter. It renders large vector datasets on a GPU-accelerated WebGL map directly in the notebook, with no tile server in the loop. Geometry streams to the browser as [Apache Arrow](https://arrow.apache.org/), so hundreds of thousands of features stay interactive. Layers compose: stack footprints, points, and analysis results in a single map.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Lonboard](https://developmentseed.org/lonboard/) is a Python library for interactive geospatial visualization in Jupyter. It renders large vector datasets on a GPU-accelerated WebGL map directly in the notebook, with no tile server in the loop. Geometry streams to the browser as [Apache Arrow](https://arrow.apache.org/), so hundreds of thousands of features stay interactive. Layers compose: stack footprints, points, and analysis results in a single map.
[Lonboard](https://developmentseed.org/lonboard/) is a Python library for interactive geospatial visualization in Jupyter. It renders large vector datasets on a GPU-accelerated WebGL map directly in the notebook, with no tile server in the loop. Geometries stream to the browser as [Apache Arrow](https://arrow.apache.org/), so hundreds of thousands of features stay interactive. Layers compose: stack footprints, points, and analysis results in a single map.

Comment thread docs/overview/lonboard.md
Comment on lines +39 to +47
def quadkey(lat, lon, zoom):
n = 2 ** zoom
x = int((lon + 180.0) / 360.0 * n)
y = int((1.0 - math.asinh(math.tan(math.radians(lat))) / math.pi) / 2.0 * n)
digits = []
for i in range(zoom, 0, -1):
bit = 1 << (i - 1)
digits.append(str((1 if x & bit else 0) + (2 if y & bit else 0)))
return "".join(digits)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty ugly and not user friendly. If I saw this as an intro user I'd be scared away.

Even though it hasn't been updated in a while, I think Mercantile is still the gold standard here.

You can use mercantile.tile to convert a lon/lat pair to a web mercator tile and then use quadkey to convert to a string.

Also you don't want to cast a quadkey to an int. A quadkey can start with a leading 0 and be valid.

Comment thread docs/overview/lonboard.md
return "".join(digits)


qk = quadkey(45.52, -122.66, 9)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above

Suggested change
qk = quadkey(45.52, -122.66, 9)
import mercantile
tile = mercantile.tile(-122.66, 45.52, 9)
quadkey = mercantile.quadkey(*tile)

Comment thread docs/overview/lonboard.md
collections=["ms-buildings"],
query={
"msbuildings:region": {"eq": "UnitedStates"},
"msbuildings:quadkey": {"eq": int(qk)},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"msbuildings:quadkey": {"eq": int(qk)},
"msbuildings:quadkey": {"eq": quadkey},

Comment thread docs/overview/lonboard.md
Comment on lines +61 to +75
## Load the footprints into a GeoDataFrame

The asset is a Delta/Parquet partition on Azure Blob. `dask_geopandas.read_parquet` reads it with the asset's `table:storage_options` (account + SAS), then `.compute()` materializes a GeoDataFrame. Clip to the Portland metro for a focused view:

```python
import dask_geopandas

gdf = dask_geopandas.read_parquet(
asset.href,
storage_options=asset.extra_fields["table:storage_options"],
).compute()
gdf = gdf.cx[-122.85:-122.45, 45.42:45.62]

len(gdf) # a few hundred thousand buildings
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend following the behavior of the existing notebook to load this data. We don't need dask_geopandas (dask is unnecessary for the example) but we should use deltalake to load the data

Comment thread docs/overview/lonboard.md

## Render the footprints

`PolygonLayer.from_geopandas()` uploads the geometry to the GPU as Arrow. Drawing the footprints as outlines keeps every building legible at city scale, and the map stays fully interactive with no tile server in the loop:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`PolygonLayer.from_geopandas()` uploads the geometry to the GPU as Arrow. Drawing the footprints as outlines keeps every building legible at city scale, and the map stays fully interactive with no tile server in the loop:
[`PolygonLayer.from_geopandas()`](https://developmentseed.org/lonboard/latest/api/layers/polygon-layer/#lonboard.PolygonLayer.from_geopandas) uploads the geometry to the GPU as Arrow. Drawing the footprints as outlines keeps every building legible at city scale, and the map stays fully interactive with no tile server in the loop:

@kylebarron
Copy link
Copy Markdown

Thanks! This is a good start!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants