NBLidar — New Brunswick as a Walkable Block World

Turns New Brunswick's open LiDAR surveys (laser measurements of the ground) into a 1-metre block world you can orbit, fly over or walk through in a browser, in English and French.

Turning a province's laser survey into a world you can walk on a phone

24,460lines of code
140files
532commits
129automated checks
8data models

The hard part

New Brunswick has been laser-scanned from the air, and the data is free to download but hard to use. Each corridor is tens of gigabytes of point clouds in formats only mapping software opens, behind a download site that turns automated requests away. Making it something a person can walk through on a phone means solving storage, processing and delivery together, with no server to pay for.

Every 1 km tile is a self-contained job on a fleet of machines: download it from NRCan's public bucket, convert it into 1 m columns, build the mesh, cut it into 200 m web chunks, then delete the source. The browser draws 12-byte instanced quads, a quarter of the memory of an ordinary vertex format, streamed under a governor that protects the frame rate. The world is served from nine Cloudflare Pages sites that share one map. GeoNB's own site sits behind a bot challenge, so the build uses NRCan's official bulk copy of the same surveys rather than trying to get past it.

5,139 km² and 263 of 2,057 named communities built; 35 to 60 s per tile on a fleet machine; 48.7 GB of source for one corridor that never lands on the main workstation.

What the measurements mean

Only what is unusual for this project. Every sentence names the field it came from; nothing here is asserted that cannot be checked against the data.

How it works

The province's LiDAR is open data: GeoNB's surveys, republished by NRCan's CanElevation on a public bucket made for bulk access. NBLidar reads those points and turns them into 1-metre columns of blocks, inferring water, bridges, buildings and trees from the class each point carries. The source data is large, so each 1 km tile is a self-contained job on my machine fleet: one machine downloads the tile's data, builds it and deletes the source. That keeps the 48.7 GB of source data for one corridor off the main workstation, and a tile takes 35 to 60 seconds on a fleet machine. Much of it is reused from VoxelBlox: the mesher, the column layout, the vertex format, and the way that game exports to the browser. Everything is prepared in Python ahead of time, and a WebGL2 viewer with no dependencies streams 200 m chunks while keeping to a frame-time budget. It has orbit, fly and walk modes, phone controls, place search, and English and French throughout. Regions are spread across nine Cloudflare Pages sites that share one region list, so the menu on any site opens any region.

What it is built from

Each bar is one of this project's own modules, sized by how many times the rest of the project imports it. The counts are measured, not estimated, and the module at the top is the one the rest of the project leans on most.

Module mapInternal modules by how often they are imported: nblidar 53 times, qa_page 19 times, shotcheck 8 times, mp_test 6 timesnblidar53qa_page19shotcheck8mp_test6imports of each internal module, counted across the project

What kind of engineering this is

Six signals counted from the source: files that run models locally, that act without being asked each time, that check their own output, that survive failure, that touch parsers and protocols, and that were measured then improved. Every axis carries its file count.

Depth profileDepth signals: Local inference 0 files, Autonomy 0 files, Verification 8 files, Resilience 41 files, Low level 13 files, Iteration 0 filesLocal inference0 filesAutonomy0 filesVerification8 filesResilience41 filesLow level13 filesIteration0 files

What it is written in

Share of code bytes. Vendored bundles and generated output are set aside before this is computed, which is why it differs from a simple file count.

Language mixPython 62.3%, JavaScript 25.6%, HTML 11.1%, XML 0.7%, Shell 0.3%, SQL 0%Python 62.3%JavaScript 25.6%HTML 11.1%

What stands out

Capabilities

Grade

Every check names the field it measured. Checks that cannot apply are excluded, never counted as failures.

B
85.3% over 18 of 18 checks100% coverage

Not met

Architecture

Directories carrying real modules, largest first.

Data model

Typed structures and tables found in the source.

Vocabulary

Parsed 129 of 130 Python file(s). 1 file(s) could not be parsed and are excluded rather than counted as empty. Counts are exact; the names below are a sample.

750functions
79methods
28classes
128documented modules

Classes

Functions

Command line

Depth

Signals counted from the code, not asserted.

506 commits across 19 separate working days over 1 months, 24 of them revising existing behaviour

Built from scratch

Proves itself

Survives failure

Systems

Model operations

Networking

Environment engineering

Languages

Built with

Recurring themes in the commit history

Evidence

Taken from the code itself: a module docstring or the opening of the README.

The block palette: ids are uint8 (the world needs ~20 kinds, so half the memory of VoxelBlox's uint16). Colours are linear-ish sRGB 0-1; the desktop and web shaders both read this table (the web pack carries it in meta.json), so a colour changed here changes both.

At a glance

Status
active
Primary language
Python
First commit
2026-10-26
Last activity
2026-11-13
Domain
Games & graphics
Agent docs
.claude