← All projects

Lemira Roof Quote

An embeddable roof painting quote that measures your roof from national survey data. Type an address and it finds the house, reads the roof pitch from aircraft LiDAR, and works out the true surface area. Nobody climbs a ladder.

Web apps, Data pipelines, Integrations

Type
Client work
Status
In development
Year
2026
Built with
TypeScript, React 19, Cloudflare Workers, Cloudflare D1, Cloudflare Pages, Turnstile, Hono, Drizzle, Vite, LINZ LiDAR, Roboflow, Gemini

What does it cost to repaint your roof? The usual answer is a site visit. Lemira's answer takes a few seconds.

Lemira paints and restores roofs around Christchurch. The goal was a real quote straight from their website, without anyone coming out to measure. So the widget does the measuring. You type your address, it finds your house in the national building register, reads the pitch of your roof from aircraft survey data, and works out the true surface area. Then it prices the job exactly the way Hayden does.

Impact

Canterbury roofs measured before anyone asks
433,572
High-confidence pitches confirmed by a second survey, within 3°
94%
Database reads to measure a roof, once the address is found
2
Every outline and pitch in Canterbury
54.5 MB

No AI in the maths

This isn't an AI project, and I'm proud of that. The measurement is geometry on open government data. It's fast, it's cheap to run, and every number can be explained. Two small model steps sit on the edges: one suggests what the roof is made of, the other traces the roof in a Street View photo for the colour preview. The customer can override both.

How it works

Open data from LINZ is processed offline into a compact database on Cloudflare. At quote time, measuring the roof is two database reads, and the customer confirms the result.

Measuring a roof from the sky

LINZ flies aircraft over New Zealand with LiDAR, and publishes a 1 metre grid of surface heights. Put a building outline over that grid and you can read the shape of its roof.

For every square metre inside the outline, I work out the slope from its neighbours. Walls show up as near-vertical cells, so anything over 60° is thrown out. In one Riccarton test, that filter alone took the reading from a nonsense 58.5° to a sensible 20°. The remaining slopes go into a histogram, and the peak is the pitch. Hip and gable faces on a typical Kiwi house share the same pitch, so this beats trying to fit individual planes.

Every roof also gets a confidence rating, based on how many cells were readable and how tightly they agree. High confidence is priced as measured. Medium invites the customer to check it. Low falls back to Hayden's own conservative default, and the customer can always adjust the pitch with a slider.

The true surface area is then just the footprint divided by the cosine of the pitch.

How do I know it's right? Christchurch was flown twice, four years apart. Measured independently, the two surveys agree within 3° on 94% of high-confidence roofs, with a median difference of 0.4°.

Every roof, measured in advance

The clever bit is doing all of that before anyone asks.

An offline pipeline crawled all 473,613 buildings across nine Canterbury districts, downloaded only the LiDAR tiles that actually contain a building, and checked every download. It measures each roof against every survey that covers it and keeps the best reading. Then it loads the results into Cloudflare D1 in one atomic swap, and refuses to swap if the new data comes up short.

Outlines are stored as compact integer deltas at 2 cm precision, which took 142 MB of shapes down to 19 MB. The whole of Canterbury fits in 54.5 MB. So at quote time, measuring a roof is two indexed database reads. The only live lookup left is finding the address itself, and the measurement costs nothing per quote.

The widget, step by step

It lives on Lemira's Webflow site as two lines of HTML. Inside, it's a React app in its own Shadow DOM, so the host site's styles can't break it and it can't break them.

Type an address, picked from the national address register, and it gets to work: match the outline, read the pitch from the aerial survey, work out the true surface.
lemira-widget.pages.dev
Lemira widget: finding your roof
Is this your house? The LINZ outline over the satellite photo, the measured pitch, and the true roof area. This is a public church in Christchurch, measured at 29.3° with high confidence.
lemira-widget.pages.dev
Lemira widget: is this your house? The measured roof

An address point only lands inside its own building about a quarter of the time. So the widget ranks every nearby building and asks the customer to confirm, rather than guessing.

Not your house? Pick from everything on the section, each with its own outline and area.
lemira-widget.pages.dev
Lemira widget: which building is yours?

Next, the customer confirms what the roof is made of. A model suggests it from the satellite photo, and they can change it. Then they leave their details and pick a colour from the Wattyl Solagard roof range, which includes the COLORSTEEL® colours. The quote itself arrives by email.

Seeing your house in a new colour

A swatch is hard to imagine on a roof. So the widget shows your actual roof in the colour you pick.

From above, it needs no AI at all. The LINZ outline already marks exactly where the roof is, so the browser recolours only those pixels and keeps each one's light and shade. Ridges, shadows and texture still read as a real roof. From the street, a Roboflow segmentation model traces the roof in the Street View photo, so the same trick works there too.

The church today.
St Peter's Church from above, as it is today
The same roof in COLORSTEEL® Pioneer Red, from the recolour prototype.
St Peter's Church from above, roof recoloured in COLORSTEEL Pioneer Red

Built on Cloudflare

Prices are only ever worked out on the server and sent by email. The browser never sees them. Hayden prefers it that way, and it means nobody can scrape his rates.

It's tested properly too: over 700 tests, with no mocks. The integration tests run inside Cloudflare's real Workers runtime against real database migrations.

Built on open data from LINZ, used under CC BY 4.0.