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.

Lonboard map

Geospatial DX: a lonboard Map with manywidgets controls. A LayerToggle shows/hides the layer, a RangeSlider + FilterBinder filters points by value (kernel-free, via the layer’s DataFilterExtension), and a MapFlyer animates the camera between presets — all interactive on the static site.

import geopandas as gpd
import numpy as np
from shapely.geometry import Point
from lonboard import Map, ScatterplotLayer
from lonboard.layer_extension import DataFilterExtension

from manywidgets import RangeSlider, Column, Text
from manywidgets.lonboard import LayerToggle, FilterBinder, MapFlyer
# A handful of points around San Francisco, each carrying a filterable value.
n = 12
vals = np.arange(n, dtype="float64")
pts = [Point(-122.45 + 0.012 * i, 37.74 + 0.008 * i) for i in range(n)]
gdf = gpd.GeoDataFrame(geometry=pts, crs="EPSG:4326")

layer = ScatterplotLayer.from_geopandas(
    gdf,
    get_radius=300, radius_units="meters", get_fill_color=[30, 90, 230],
    extensions=[DataFilterExtension(filter_size=1)],
    get_filter_value=vals, filter_range=(0, n - 1),
)
m = Map(layer, view_state={"longitude": -122.4, "latitude": 37.77, "zoom": 11}, height=420)
toggle = LayerToggle(layer, label="Points", value=True)
value_range = RangeSlider(label="Value range", min=0, max=n - 1, low=0, high=n - 1, step=1)
fb = FilterBinder(value_range, layer)  # value_range.low/high -> layer.filter_range

flyer = MapFlyer(m, locations=[
    {"label": "San Francisco", "longitude": -122.42, "latitude": 37.77, "zoom": 12},
    {"label": "New York", "longitude": -74.0, "latitude": 40.70, "zoom": 11},
    {"label": "London", "longitude": -0.12, "latitude": 51.50, "zoom": 10},
], duration=3000)

Column(
    Text(value="### Map controls", markdown=True),
    toggle, value_range, fb, flyer, m,
    gap="10px",
)