SUNDIAL a Developing Today project

SUNDIAL

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
Precision floor
10−10 m
resolves a 0.1 nm separation within 5% of Karney numerical resolution of the solver under the benchmark's probe, not positional accuracy of a WGS84 coordinate or a survey measurement
Benchmark
RANK 1 100.0 / 100 · of 7
house entry · the full board

Demos

Every button draws on the map. Keep an eye on it.

Geodesy

Distances and areas come from GeographicLib's Karney solver on the WGS84 ellipsoid, the same mathematics the benchmark checks every library against.

True curves

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.

Labels

Sundial rasterizes its own signed-distance glyphs and declutters with a typed-column collision pass. Ten thousand labels, timed on your machine.

Picking

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.

Camera

A fourteen-second scripted world tour with frame deltas sampled the whole way. Watch the map fly it and read your average.

Quick start

A map
import { SundialMap } from '@devtomorrow/sundial';

const map = new SundialMap({
  container: document.getElementById('map'),
  center: [-103.2497, 44.0525],
  zoom: 16,
});
await map.whenSettled();
Data, labels, picking
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));
Measure & edit
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);
@devtomorrow/sundial
map, layers, geodesy, picking · 25.0 KB gz
…/labels
SDF text + declutter, loaded on first use
…/edit
DCEL topology, snapping, rules, undo; never in the map payload
…/tess-worker
earcut worker for stress-scale fills (3.3 KB gz)

The benchmark

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.

Raw harness (used by the test probes)
Sundial dev
Edit Lab 6 m · Hover to snap · Shift-drag moves a vertex · U/Y undo/redo

          

Private alpha

Sundial installs from a private registry while it hardens. For access (the npm scope, the source, and a hand from the team), write to us and say what you're building.

support@developingtoday.net

Request access