An offline lookup library built on the Trifold grid. Thanks to exact aperture-4 nesting, the level-10 grid (~7 km cells) classified against Natural Earth collapses into a 182 KB dataset that answers anywhere on Earth in microseconds, with a confidence value for every answer. Python and JavaScript give identical results. This page runs the real JS library in your browser; the dataset is embedded right in this HTML file.
Try it on the mapLoad sample points or your own file (CSV lon,lat or GeoJSON points), and
every point is classified in your browser by the bundled library, with no server
and no network call per lookup. The lookups-per-second figure is measured tightly around
the classification loop on your machine (map rendering and file parsing excluded),
so it is the real library throughput. Use the 100k-random button for a stable number.
lon,lat[,name] per line (or a header naming
lat/lon columns in either order). GeoJSON: any
FeatureCollection of Points. Files stay on your machine.Click any classified point for its full answer: cell address (computed on the fly for sea points, whose cells are not stored), kind, confidence and land fraction. Note the Natural Earth 1:50m caveats: lakes count as land and islets below its resolution are missing. Switching on the OSM coastal refinement makes OSM authoritative in cells crossed by either source coastline. Try the cities sample with it on and off and compare the answers near coasts.
import { LandCheck } from "./landcheck.mjs";
// Node: bundled file · browser: fetch the 182 KB dataset
const lc = await LandCheck.fromFile(); // Node
const lc = await LandCheck.fromUrl("landsea_L10.tfls"); // browser
lc.isLand(24.7536, 59.437); // true (lon, lat)
lc.check(-0.1276, 51.5072);
// { land: true, kind: 'land', confidence: 1,
// landFraction: 1, cell: 'TFA95BM', refined: false }
from landcheck import LandCheck
lc = LandCheck() # bundled data
lc.is_land(24.7536, 59.4370) # True
lc.check(-0.1276, 51.5072)
# LandResult(land=True, kind='land', confidence=1.0,
# land_fraction=1.0, cell='TFA95BM', refined=False)
# vectorised: ~2.8 µs/point with numpy
lc.is_land_batch(lons, lats)
| kind | meaning | land | confidence |
|---|---|---|---|
| land | cell wholly inside land | true | 1.0 |
| sea | cell absent from the dataset | false | 1.0 |
| coast | mixed cell; bundled land-area fraction decides | fraction ≥ 0.5 | max(f, 1−f) |
| coast + refined | decided by the optional OSM polygon layer | exact | 0.99 |
Measured accuracy: 99.82% agreement with exact polygon containment on
30,000 uniform random points. The land and sea answers were 100%
correct; all residual error lives in coast answers, which self-report lower
confidence.
With the OSM refinement loaded, coastal answers reach 99.95%.
$ python landcheck/python/landcheck.py 24.7536 59.4370
LAND kind=land confidence=1.000 land_fraction=1.0 cell=TFAVKGR refined=False
Any Trifold cell at level ≤ 10 maps to
addr64 >> 39, a 25-bit integer where a level-l cell covers exactly
410−l consecutive indices. The whole classification becomes run-length
intervals.
153,884 runs as
varint(gap), varint(len·2|coastal) + a 4-bit land fraction per coastal
cell, zlib-compressed. Level-agnostic: the same tooling serves an L8 (~30 KB) or
L12 (~3 MB) variant.
Pure-float point location (no dependencies, bit-identical to the SDK) descends 10 subdivision levels, then one binary search over the run starts. ~0.8 µs in Node, ~13 µs in pure Python, ~2.8 µs batched with numpy.
OSM simplified land polygons clipped to every cell crossed by either source coastline, quantized to a cell-local 16-bit grid (~0.1 m), with zigzag-varint rings and the even-odd rule. The OSM polygon test can override Natural Earth land, sea or fraction answers in those cells.
Full documentation, build scripts (build.py,
refine_build.py) and the cross-language test suite live in
landcheck/ on GitHub.
Roadmap: country detection with the same run-length + clipped-border approach, an L12
variant, published pip/npm packages.
Same job for every engine: classify 100,000 sphere-uniform random points against the same OSM simplified land polygons. Median of seven warm runs on an Apple M5 Pro laptop (June 2026); BigQuery ran as a managed on-demand service. In batch mode the OSM-refined Trifold was 3–4× faster than BigQuery and PostGIS and ~30× faster than DuckDB Spatial; called one point at a time it answered ~86,000 lookups per second, 40× the embedded DuckDB rate.
The SQL engines compute exact polygon containment on the loaded OSM snapshot;
Trifold's compact dataset agrees with that result on 99.5% of points (refined). PostGIS singular
includes localhost TCP + Docker transport; DuckDB runs embedded in-process. BigQuery's singular
mode was not run. Full methodology, dataset manifest and caveats:
benchmark.md.