Measuring
The 📏 Measure tool rail (shortcut M). Pick a type and click across the point cloud.
| Type | Action | Values shown |
|---|---|---|
| Distance | Click 2 points | Slope distance / horizontal distance / height difference |
| Polyline | Place points, double-click the last to finish | Each segment length and cumulative distance |
| Area | Place points, double-click the last to finish | Horizontally-projected area and perimeter |
"Clear measurement" removes it. On iPad, a double-tap also finishes it.
What the values mean
Everything is in real-coordinate meters. XY is horizontal, Z is vertical (COPC's coordinate system as-is).
- Slope distance — the straight-line distance between two points
- Horizontal distance — distance projected onto the XY plane
- Height difference — the difference in Z (signed, 2nd point − 1st point)
- Area — the area projected horizontally onto the XY plane. Not the actual area of a sloped surface. Correct for concave polygons too, independent of vertex winding order
- Perimeter — the sum of slope distances (not horizontally projected). Once the area is finished, this also includes the edge from the last point back to the first
Area being horizontally projected while perimeter is slope distance is deliberate. It matches inspection practice: deck-slab or road-surface quantities are handled as horizontal projections, while edge lengths are wanted as true lengths.
Which datum for height
Whether Z is elevation (orthometric height) or ellipsoidal height depends on the data. queryCrs returns the EPSG code and vertical datum, so you can check before putting a number in a report. oniyanma only records CRS — it never reprojects.
Coordinates of a clicked point
Separately from measuring, clicking the point cloud shows that point's real coordinates (m) at the bottom left of the screen. You can pick up coordinates from here for a finding's pin or for setCameraReal.
Measuring from a command
measureDistance returns the distance between two real coordinates you pass it. It doesn't change what's on screen (read-only).
await oniyanma.execute('measureDistance', { a: [x1, y1, z1], b: [x2, y2, z2] })
// → { distance: 12.43, horizontal: 12.41, vertical: 0.72 }There are other commands for querying the point cloud's shape as numbers.
| Command | What it does |
|---|---|
queryElevation | Elevation distribution (min / max / mean / count / histogram) |
queryClasses | Classification histogram. Reflects classification overrides from edits too |
queryBoxCount | Point count inside a given box |
queryLayers | Point count and extent per layer |
All of these are resident-based (the LOD sample currently on screen). → reference overview
Deviation analysis (comparison against a design surface)
With a reference surface (TIN) loaded, you can tally and visualize the vertical deviation between the point cloud and it (measured − design). For bridge inspection this is the core analysis — a deviation from the design value is a clue to deformation or settlement.
const { clusters } = await oniyanma.execute('queryDesignDeviation', { surfaceId, thresholdM: 0.05 })
// → { clusters: [{ center: [x,y,z], dz: -0.12, count: 340 }, …] } (sorted by |dz| descending, top 20 by default)dz is signed (measured Z − design Z), and points outside the TIN's extent aren't included. This doesn't change the display (read-only).
To paint deviation directly onto the point cloud as a heatmap, set the color mode to deviation.
await oniyanma.execute('setDeviationSurface', { surfaceId })
await oniyanma.execute('setColorMode', { mode: 'deviation' })
await oniyanma.execute('setDeviationRange', { range: 0.1 }) // color saturates once |dz| reaches this value (m); default 0.1mWhite = no deviation, blue = the cut side, red = the fill side.
To turn areas of large deviation into findings in bulk, use createDesignDeviationFindings. It uses queryDesignDeviation's clusters and type-checks every item before filing any (if even one fails to match the type, none are created), so you need to define a type matching your inspection form beforehand.
Year-over-year comparison is out of scope
The only thing comparable here is deviation from a design surface. Comparing against past years' data (point cloud vs. point cloud from two different times) doesn't exist yet — that's a feature that matters once past-year data has accumulated, for the second inspection cycle onward, so it wasn't prioritized for the initial rollout.
Why measuring alone has such thorough tests
For inspection and surveying, "a number silently goes wrong" is the worst possible failure. If rendering breaks, a person notices. If a value reads 12.4 m when it's actually 13.1 m, no one does.
So the numeric part of measurement is factored out as pure functions, detached from the DOM and GPU, and distance, cumulative distance, horizontally-projected area, and perimeter are all pinned to known answers in regression tests (measure/geometry). Verifiable with pnpm test, no browser required.