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",
)