Geometric Length Takeoff: Drawing the Line Between AI Measurement and Ground Truth
Our previous accuracy research focused on counting — how many symbols appear on a drawing page. But a real tender bill of quantities doesn't just ask "how many valves?" It asks "how many metres of 150mm cast-iron pipe?" That's a fundamentally different problem: the AI can't just point at a symbol and count — it has to trace the drawn centerline of a pipe run across the page, read the drawing scale, and convert paper distance to real-world metres. We call this geometric length takeoff, and until this week, it was silently broken in seven different ways.
The ground truth: what the answer key actually demands
We ran a systematic audit against the Peak training project — a real Hong Kong P&D (plumbing & drainage) tender with a complete, human-priced SOR. The P&D sheet alone has 44 line items with unit "m", totalling 5,886 metres of pipe across 33 distinct pipe-type-by-diameter combinations. These fall into 4 pipe families: cast iron (C.I.), uPVC, condensate drainage, and refrigerant piping. Page extraction (counting symbols) produces zero coverage for these rows — they're fundamentally different items that need geometry, not counting.
Seven silent bugs we found and fixed
- N.T.S. gate: pages marked "Not to Scale" were silently defaulting to 1:100, producing wildly wrong metre values. Now flagged with confidence ≤ 0.2 instead of fabricating a number.
- Discipline routing: takeoff items were hardcoded to "P&D" regardless of the actual drawing. MVAC pipe runs were polluting the plumbing schedule.
- SOR context for AI: Gemini was tracing pipes blind — no knowledge of what the SOR actually needs. Now the top 20 length items are passed as grounded targets.
- Auto-trigger: length takeoff never ran automatically after page extraction. Users had to click a separate button they might not know existed. Now it fires automatically when the discipline's SOR has metre-unit rows.
- Unit normalization gaps: "Run", "lm", "l.m." were not mapped to metres — real SOR formats from Hong Kong bills.
- Missing pipe families: P&D pipe types (C.I., uPVC, D.I., copper, concrete) had no family classification. The system couldn't aggregate pipe runs by diameter within each material for SOR comparison.
- Chinese unit blindness (discovered during cross-project verification): "米" (Chinese for metre), "套" (set), "個" (number), "項" (item) — standard units in Macau tender documents — were completely invisible to the system. Every Macau-format bill of quantities was silently dropped from length analysis.
Cross-project verification: the Macau discovery
After fixing the first six bugs on the Peak project, we ran the same analysis pipeline against real Macau university construction tender documents — 澳門大學 S33 (staff quarters) and 澳門理工學院 (library complex). This is where fix #7 came from: none of their 94 length rows (totalling 27,873 metres) were being detected, because the unit column said "米" instead of "m". The bilingual format "米 / m" used by the Polytechnic project was equally invisible.
A system that can't read "米" as "metres" is useless for half the market it's supposed to serve. This wasn't a subtle bug — it was total blindness, and we only caught it by testing against real documents from a different jurisdiction.
Benchmark results: what changed
After all 7 fixes, we ran a ground-truth analysis across four projects (Peak, Kwai On Factory Estate, 澳門大學 S33, 澳門理工學院). The results measure infrastructure coverage — how many SOR length items the system can now see and classify — rather than making up accuracy percentages for metre values that require live API calls to verify:
- Peak P&D: 44 length rows, 5,886m total — 100% classified into pipe families (ci_pipe, upvc_pipe, condensate_pipe, refrigerant_pipe). All 33 pipe-type × diameter combinations recognized.
- Kwai On Factory Estate: 199 length rows, 80,725m total — previously 100% visible (English units), now with proper SOR hint injection and pipe family classification.
- 澳門大學 S33: 72 length rows, 22,560m — went from 0% detected (invisible Chinese units) to 100% detected. Most rows are architectural finishes (skirting, tile edges) rather than pipes — honest classification as "other" rather than forcing a wrong pipe family.
- 澳門理工學院: 22 length rows, 5,313m — went from 0% to 100% detected. Includes real pipe items (Ø50mm–Ø100mm BS5255 pipes) now properly classified.
Honest limitations and what's next
These fixes are infrastructure — they make the pipeline capable of doing the right thing. Whether the AI actually traces a polyline accurately enough on a specific drawing still depends on the drawing's clarity, the scale's legibility, and whether the pipe run is a clean straight segment versus a branching network. We deliberately don't claim a metre-accuracy percentage here because we haven't run enough live API-based comparisons to make one that would be honest.
Follow-up research areas we've identified:
- Live API benchmark: run runPageLengthTakeoff on Peak P&D pages 1–5 and compare AI-computed metres against the 44 SOR ground-truth rows, per pipe type and diameter. This is the real accuracy measurement we can't make offline.
- Pipe family classifier refinement: the current classifier over-generalizes "refrigerant_pipe" for items that are actually drainage or water supply. BS standard references (BS 437, BS 5255, BS EN 598) should drive classification, not regex on "mm dia" alone.
- Chinese-language drawing extraction: now that we can read Chinese BQs, the next question is whether Gemini can trace pipes on Chinese-annotated Macau drawings as well as it does on English HK drawings.
- Branching pipe detection: current polyline tracing treats each run as independent segments. Real drainage networks branch (a main run with T-junctions), and the total length of a branching network is longer than the sum of individual visible segments.
- Architectural finishes in length: Macau BQs put skirting, tile edges, and marble bases in metre units. These aren't pipes but are legitimate length-takeoff items that need their own family classification and tracing strategy.
The core lesson from this round: testing against a second jurisdiction (Macau) immediately caught a bug that testing against Hong Kong data alone never would have surfaced. Cross-market validation isn't optional — it's the only way to find the assumptions you didn't know you were making.
Related articles
Phase 28 — Coverage Ladder 5/21 Held; Count CP Still 3/63, Not 80/80
Phase 28 is the execute-close of the same qty_3d coverage + S33 count-CP families: inner COVERAGE_LADDER_PASS, five training_data graphs kept (S33, N23, Kwai On, S27, N22), fabricatedGeometry false. Extra S33 plan pages 12/14/16/19 raised world elements to 41 on the same slug — not a sixth coverage credit. Count CP stayed evaluated at 3/63 on S33 BQ sheet E (detection 5/63; N=63 held; reasonCode null). Frozen loop RSI_PLATEAU. Live 圖則.pdf is a residual, not a coverage credit. Not Peak P&D 3D 80/80. Not corpus 80–90%.
14 min readPhase 27 — Coverage Ladder 5/21; Count CP 3/63, Still Not 80/80
Phase 27 is the execute-close of the coverage-ladder 3→5 + S33 count-CP pack: COVERAGE_LADDER_PASS, five training_data graphs (S33, N23, and Kwai On preserved; S27 and N22 new), fabricatedGeometry false. Count CP is evaluated at 3/63 on S33 BQ sheet E — unblocked, not IDENTITY_ONLY_NO_GT, and not an accuracy win. S27 geometric takeoff was empty (NO_PLAN_POLYLINES); fittings-only still qualified. Live 圖則.pdf is a residual, not a coverage credit. Not Peak P&D 3D 80/80. Not corpus 80–90%.
12 min read