isard
v1.11.0
Published
A WebGL2 map engine for large, interactive data layers, labels and 3D Tiles over raster or vector basemaps (Rust core in WebAssembly)
Maintainers
Readme
Isard
Maps that recolor at every mouse move.
A WebGL2 map engine for large, interactive data layers, labels and 3D Tiles. Rust core in WebAssembly, a small TypeScript API.
Documentation · Examples · API · Changelog
Why Isard
General-purpose map libraries spend their time on things these maps do not need. Isard is built for maps where millions of features change at every mouse move: accessibility, flooding, flows.
- ⚡ One upload, millions of features. A network of 2 million street pieces recolors from a single texture upload of 4 bytes per node, drawn in the very frame of the mouse move; only the squares in view are drawn.
- 🗺️ Basemaps and relief, worldwide. OpenFreeMap's vector basemaps by default (OpenStreetMap data, no key), any MapLibre style drawn in workers with its labels above your data, raster tiles, a worldwide relief, on a globe that turns into Web Mercator. The Géoplateforme's data for France in one option or call: PLAN.IGN, orthophotos, hillshade, the IGN relief, any WMTS, WMS or WFS layer (Géoplateforme (IGN) data).
- ⛰️ Everything on the relief. Lines, circles, labels and buildings stand on the ground; fills of any size are exact to the pixel over hills and valleys; your own GLSL is drawn over the ground like the basemap.
- 🪐 The Moon, Mars, any body.
body: 'moon','mars'or an ellipsoid of your own: the globe at its radius with its own atmosphere halo (or none), its metres in the camera, the relief and 3D Tiles, NASA's planetary mosaics reprojected in the page from longitudes and latitudes, and their relief:terrain: trueraises Olympus Mons and digs Valles Marineris and the lunar craters from NASA's LOLA and MOLA models. - 🌃 A 3D vector city. Any MapLibre style as geometry (
vectors()): its streets, water and buildings raised from itsfill-extrusionlayers, sharp at any zoom (its tiles cut again past the source's deepest level), 3D trees in its woods, the sun's shadows at any hour, the night with lit windows and glowing streets; indoor data floor by floor (a shopping mall, its shops raised and named). - 🌬️ Wind and currents. Particles carried by a field of velocities (a weather model's wind, an ocean's current), their trails animated on the globe and the relief, colored by speed; the model's hours along a clock, its own GRIB2 or NetCDF files read in workers, and down to a city's streets, round its buildings.
- 🏙️ Buildings and 3D Tiles. Buildings colored by a value or by a network's travel times, photomeshes and city models in 3D Tiles (Draco, meshopt, KTX2).
- ☁️ Point clouds. LiDAR in COPC read by range requests (the IGN's LiDAR HD, reprojected from Lambert-93 onto the relief), 3D Tiles points; colored by RGB, class, altitude or intensity, Eye-Dome Lighting, a point budget, picked.
- 🧊 Your own 3D. glTF models at positions, instanced and picked; custom layers for your WebGL code or a three.js scene, in the map's frame and depth, with camera-relative matrices exact at any zoom.
- 🦀 Small and exact. 278 KB of WebAssembly gzipped (452 KB once a 3D Tiles layer, a model or a point cloud is added), f64 on the CPU and f32 relative to the camera on the GPU (centimetres at any zoom), frames on demand only, strict TypeScript types end to end.
Quick start
bun add isard # or npm install isard<div id="map" style="height: 100vh"></div>import { GeoMap } from 'isard';
const map = await GeoMap.create(document.getElementById('map')!, { center: [2.35, 48.85], zoom: 12 });
map.addFills({
data: { type: 'Feature', properties: {}, geometry: { type: 'Polygon', coordinates: [[[2.33, 48.84], [2.37, 48.84], [2.37, 48.87], [2.33, 48.87], [2.33, 48.84]]] } },
color: '#2f6fd1',
opacity: 0.4,
});That is the whole integration: the map fills its container, follows its size, handles mouse and touch and loads the basemap. With a bundler, see Getting started.
Examples
Live in the documentation, sources in examples/.
What it draws
| Layer | | |
|---|---|---|
| Networks | addNetwork | millions of edges colored by a value per node, worked out per pixel along the edges |
| Lines, circles, fills | addLines, addCircles, addFills | GeoJSON styled per feature: zoom stops, functions, values through a ramp, filters; in any CRS, KML, GPX and TopoJSON parsed |
| Labels | addSymbols | SDF fonts (Noto Sans by default, any glyphs), halos, along lines, collisions shared by all layers |
| Buildings | addExtrusions | tiles or one set, colored by values or by a network's times |
| Ground shaders | addGround | your fragment shader over the ground: water depth, heat maps |
| Rasters | addRaster, addPmtiles | XYZ, WMTS, WMS, PMTiles; in Web Mercator, or reprojected from another grid (longitudes and latitudes, Lambert-93, UTM, any CRS through proj4); or tiles drawn by your code |
| 3D Tiles | addTiles3d | b3dm, pnts, glb, external tilesets, compressed or not |
| glTF models | addModels | a glTF model at many positions, instanced, on the relief, picked |
| Point clouds | addPointCloud | COPC (LiDAR HD) by range requests, pnts and glTF points; by class, altitude, intensity, EDL |
| Flows | addFlow, readGrids | particles carried by a wind or a current, a model's hours along a clock, its GRIB2 and NetCDF files read in workers, the wind through a city's streets (streetWind) |
| Custom layers | addCustomLayer | your WebGL code or a three.js scene in the map's frame, sharing its depth |
Plus markers, popups, controls, picking within a radius, easeTo, flyTo, a sky and fog for tilted views. All in
the API reference.
Local files on a map: bun scripts/viewer.ts data.geojson lidar.copc.laz tiles.pmtiles serves the viewer
(apps/viewer: files dropped or given, a layer list, a bridge any app can drive) on 127.0.0.1
(The viewer).
In QGIS (3.28 and 4): the isard 3D view plugin shows the map canvas and its layers in 3D, in a panel or the browser, the camera, layers and clicks in sync (QGIS plugin).
Fast by design
Geometry uploaded once and only the view drawn, values in textures, the ground composited in one pass, frames on demand, decoding and vector tiles in workers. The details and the measures: Performance.
Develop
Rust (with wasm32-unknown-unknown and wasm-bindgen-cli 0.2.129) and Bun:
bun install
bun run dev # the demo on http://127.0.0.1:5180, the examples on /examples/, the benchmark on /bench/
bun run test # Rust tests
bun run lint # Biome, clippy pedantic (native and wasm)
bun run typecheck # strict TypeScript
bun run docs:dev # the documentation, with the examples liveThe root holds two workspaces side by side: Rust (Cargo.toml) and TypeScript (package.json), and bun run build
drives both. Each crate has its README; crates/README.md guides through them.
crates/geo/ camera, projections, geodesy and geoid, tile selection, label placement, polygons tested natively
crates/tiles3d/ 3D Tiles tree, traversal and decoding tested natively
crates/pointcloud/ COPC point clouds: header, octree hierarchy, traversal, LAZ chunks tested natively
crates/engine/ the WebAssembly core: the engine, the ground, the layers, picking
crates/tess/ the tessellation module: vector tiles made ready for the GPU in the basemap workers
crates/grid/ the grid module: GRIB2 and NetCDF files read into grids, the wind through the streets tested natively
packages/isard/ the npm package isard: GeoMap, layer handles, overlays, workers
apps/ the demo, the viewer (local files, a bridge for other apps) and the benchmark
examples/ one page per example
docs/ the documentation site (VitePress)
scripts/ build, dev server, docs, release
integrations/qgis/ the QGIS plugin (Python), its server tested with python3 -m unittest; integrations/README.md: the bridgeMore in Develop and release.
Roadmap
By priority:
- P1, next: areas and heights in the measure.
- P2, then: rasters draped on the buildings; rasters draped within an area; a clipping volume; a performance report.
- P3, later: objects moving along paths; video in the scene.
- P4, when time allows: the whole MapLibre style drawn as vectors, a 3D vector map to walk through, Panoramax's street-level photos, fluids on the globe, several projections on the globe, smaller items.
See Roadmap.
Licence
MIT, © 2026 Kevin Graff. Basemap data: © OpenStreetMap contributors (OpenFreeMap, OpenMapTiles); IGN data: Licence Ouverte (Géoplateforme).
