Fused Map
Type: fused-map
Interactive map with tile, UDF and SQL layers.
Supports children: No
Interactive map: a Mapbox basemap with every data layer (mvt, raster, geojson, h3, heatmap, arc, scatterplot, deck-geojson, fused-hex) rendered through deck.gl. Layers load data from a UDF directly (`udf`), from a DuckDB query (`sql`), from a tile endpoint (`tileUrl`) or from a Fused server's hex query endpoints (`fused-hex` with `source`). A sidebar lets viewers restyle, filter and re-query layers at runtime.
Example — UDF result (GeoDataFrame)
{
"type": "fused-map",
"props": {
"layers": [{
"id": "buildings",
"type": "geojson",
"udf": "{{my_udf}}",
"tooltip": true,
"style": { "fillColor": { "type": "continuous", "attr": "height", "palette": "Sunset" } }
}]
}
}
Example — UDF as H3 tiles
{
"type": "fused-map",
"props": {
"layers": [{
"id": "hexes",
"type": "h3",
"udf": "{{my_h3_udf}}",
"tile": true,
"style": { "fillColor": { "type": "continuous", "attr": "count", "domain": [0, 500] } }
}]
}
}
Example — MVT tile layer
{
"type": "fused-map",
"props": {
"layers": [{
"id": "counties",
"type": "mvt",
"tileUrl": "https://tiles.fused.io/public/my_tileset/{z}/{x}/{y}",
"style": { "fillColor": [100, 150, 200], "opacity": 0.6 }
}]
}
}
Example — SQL with lat/lng points and a filter
{
"type": "fused-map",
"props": {
"layers": [{
"id": "sites",
"type": "geojson",
"sql": "SELECT name, lat, lng, score FROM {{my_udf}}",
"filters": [{ "attr": "score", "type": "range", "min": 0.5 }],
"style": { "fillColor": [255, 80, 0], "pointRadius": 8 }
}]
}
}
Example — raster tile layer
{
"type": "fused-map",
"props": {
"layers": [{
"id": "seismic",
"type": "raster",
"tileUrl": "https://udf.ai/<token>/run/tiles/{z}/{x}/{y}?format=png",
"style": { "opacity": 0.8 }
}]
}
}
Example — ERA5 / gridMET / indexed H3 data (fused-hex)
{
"type": "fused-map",
"props": {
"layers": [{
"id": "era5-t2m",
"type": "fused-hex",
"source": {
"endpoint": "/retrieve/era5/daily/bbox",
"dateMin": "2024-07-15",
"dateMax": "2024-07-15",
"variables": ["t2m_mean"]
},
"tooltip": ["hex", "date", "t2m_mean"],
"style": { "fillColor": { "type": "continuous", "attr": "t2m_mean", "domain": [270, 310] } }
}]
}
}
Raster layers with a `tileUrl` fetch PNG tiles from a publicly reachable XYZ endpoint; only `opacity` and `visible` apply. `udf` with `tile: true` instead runs the UDF per tile through the workbench (or the canvas share token on a shared page), so no share token is needed and edits to the UDF re-render the layer.
Choosing a source
- `udf` without `tile`: one whole run. Rows become features (geojson, h3, heatmap, arc, scatterplot); an image result becomes one `raster` picture at the bounds the run returned or was sent. Not valid for `mvt` — that needs `tile: true` with `udf`, or a `tileUrl`. - `udf` with `tile: true`: the UDF runs per XYZ tile; use for large or tile-shaped UDFs (`raster` → PNG, `h3` → hexagons, `geojson` → vector features). Tile layers never auto-fit. - `sql`: a DuckDB query over `{{udf}}` results; rows become features via geometryColumn / latColumn+lngColumn / h3Column. - `source` (`fused-hex` only): a Fused server's ERA5, gridMET or `/h3/query` endpoint, queried per XYZ tile; no `udf` or `sql`. - Whole-run results larger than the viewer's "Max amount of data to auto-load" setting (default 50 MB) are not loaded until the viewer confirms, and UDFs marked for manual runs show a Run button instead of running on load. Prefer `tile: true` or a narrowing `sql` for big datasets.
Layer types
- `geojson`: polygons, lines and points from any source. `deck-geojson` is an alias of `geojson` and renders identically — prefer `geojson`. - `h3`: hexagons from `h3Column` (auto-detected from common names like hex, h3 when omitted), styled with `coverage`, `extruded`, `elevationAttr`. - `scatterplot`: point circles; `pointRadius` in pixels (default 5), `lineColor`/`lineWidth` for the outline. - `heatmap`: density of points; weight comes from a continuous `fillColor.attr` (1 per point when fillColor is static), `pointRadius` is the kernel radius in pixels (default 30). Not pickable, no tooltip. - `arc`: one arc per row. Give the endpoints with `startLatColumn`/`startLngColumn` and `endLatColumn`/`endLngColumn` (auto-detected from common names when omitted), or a `source`/`target` property holding [lng, lat], or a LineString whose first and second vertices are the ends. `fillColor` colours the source end, `lineColor` the target end, `lineWidth` the arc width. - `mvt` / `raster`: tiled from `tileUrl`, or from `udf` with `tile: true`. - `fused-hex`: H3 tiles queried from a Fused server; each XYZ tile's bbox is sent to `source.endpoint` (a full URL, or a path on the current server; /h3/query when only `source.path` is set): `/retrieve/era5/daily/bbox`, `/retrieve/era5/hourly/bbox` and `/retrieve/gridmet/bbox` serve fixed resolution 7 datasets and need `dateMin`/`dateMax`; `/h3/query` reads any indexed `source.path` and needs the layer's `h3Column` set to the location's indexed space column (set `source.timeColumn` too so latest/first can order rows). Each hex's rows over the window are reduced to one (`reduce`: latest, first, mean, min, max, sum). Tiles load from zoom 7 for a single day; unless `minZoom` is set the floor rises with the window (about one zoom level per 4x more time steps) so a tile stays within the server's row limit, and nothing draws below it. A tile the server still rejects as too large shows an error: zoom in or narrow the window. It reads `source` instead of `udf`/`sql`, is never auto-detected, never auto-fits and takes no `bounds`.
Colours
`style.fillColor` and `style.lineColor` accept an [r, g, b] or [r, g, b, a] array, a CSS colour string, or a data-driven object:
- Continuous: `{ "type": "continuous", "attr": "<numeric property>", "domain": [min, max], "palette": "Sunset", "steps": 7, "reverse": false, "nullColor": "#b8b8b8" }`. `domain` defaults to the data's min/max, `palette` to "Sunset". Sequential palettes (CARTOColors): Sunset, SunsetDark, Teal, TealGrn, Emrld, BluGrn, BluYl, Mint, DarkMint, Purp, PurpOr, Magenta, Burg, BurgYl, RedOr, OrYel, Peach, PinkYl, BrwnYl. - Categorical: `{ "type": "categorical", "attr": "<property>", "colors": { "<value>": "#hex" }, "palette": "Bold", "nullColor": "rgba(128,128,128,0.5)" }`. Omit `colors` to auto-assign from the palette (default "Bold"). Qualitative palettes: Bold, Vivid, Safe, Prism.
A legend is drawn only for data-driven colours (see `legend` and `showLegend`).
Every widget is defined as { "type": "fused-map", "props": { ... } }. The properties below describe the props object.
Props
Raw schema
Download the full schema file: /widget-schema/fused-map.json