Geodesy
Distances and areas come from GeographicLib's Karney solver on the WGS84 ellipsoid, the same mathematics the benchmark checks every library against.
A WebGL2 GIS library with survey-grade numerics: Karney geodesy on WGS84, true circular arcs, decluttered labels, id-buffer picking, and topology editing that keeps parcel fabrics sealed. 29 KB on the wire.
npm i @devtomorrow/sundial
Every button draws on the map. Keep an eye on it.
Distances and areas come from GeographicLib's Karney solver on the WGS84 ellipsoid, the same mathematics the benchmark checks every library against.
A DCEL fabric where a shared boundary is one edge pair, so gaps cannot form. Snapping, rule enforcement, exact undo. Arm the lab, hold Shift, and drag any shared corner.
The full editing plate: repair and rules from your own layers →
County deeds carry circular-arc boundaries; classic GeoJSON cannot express them. Sundial speaks every open format that can: OGC JSON-FG (the circular-arcs class), SQL/MM WKT as spatial databases emit it, and Esri JSON curveRings. One recorded arc stays one arc in all three, tessellated only for the screen at two centimeters, and exports back out the same way: byte-identical for any arc you have not edited, which the round-trip tests pin.
Sundial rasterizes its own signed-distance glyphs and declutters with a typed-column collision pass. Ten thousand labels, timed on your machine.
An id-buffer renders every feature's identity off-screen; hover reads it back asynchronously through a fence ring. Load the county fabric and point.
A fourteen-second scripted world tour with frame deltas sampled the whole way. Watch the map fly it and read your average.
import { SundialMap } from '@devtomorrow/sundial';
const map = new SundialMap({
container: document.getElementById('map'),
center: [-103.2497, 44.0525],
zoom: 16,
});
await map.whenSettled();
const deeds = map.addGeoJson(parcels, {
fill: { color: '#c9a13b', opacity: 0.2 },
outline: { color: '#c9a13b', widthPx: 1.5 },
});
const { addLabels } =
await import('@devtomorrow/sundial/labels');
addLabels(map, points.map((p, i) =>
({ lngLat: p, text: names[i], priority: 1 })));
map.on('click', (ev) => console.log(ev.feature));
const { whenGeodesyReady } =
await import('@devtomorrow/sundial');
const geo = await whenGeodesyReady();
geo.Inverse(34.05, -118.24, 51.5, -0.13);
const { EditWorkspace, curveFeaturesToInputs } =
await import('@devtomorrow/sundial/edit');
const ws = new EditWorkspace(
curveFeaturesToInputs(deeds), 44.08);
// moving a shared corner moves every deed on it
ws.moveVertex(ws.snap(lngLat, 6).node, target);
Sundial competes on the Frontend GIS Benchmark as a house entry. Every figure above comes from the published methodology: same fixtures, same ladder, and a Karney reference computed live.