Reads a LiDAR file's header and turns each stored point into x, y, z in the file's coordinates.
How the precision is kept
The LAS format stores each coordinate as a signed 32-bit integer with a 64-bit scale and offset per axis in the header. The reader multiplies and adds in 64-bit arithmetic and rounds nothing, so the coordinates are as fine as the file's own scale. Counts and offsets are whole numbers held in 64-bit numbers.
Calculations under this policy
4 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
x = X × scaleₓ + offsetₓ (and the same for y and z)
X, Y and Z are read as signed 32-bit integers, which a 64-bit number holds exactly. Each is multiplied by the header's 64-bit scale and added to its 64-bit offset: two rounded operations per coordinate, nothing else.
las.js
lines 158 to 165
CadCraft 0.8.2
function decoder(h) {
const [sx, sy, sz] = h.scale, [ox, oy, oz] = h.offset, ext = h.format >= 6;
return (dv, o, onPoint) => {
const x = dv.getInt32(o, true) * sx + ox, y = dv.getInt32(o + 4, true) * sy + oy, z = dv.getInt32(o + 8, true) * sz + oz;
const cls = ext ? dv.getUint8(o + 16) : dv.getUint8(o + 15) & 31;
onPoint(x, y, z, cls);
};
}
Scale, offset and bounds from the header
64-bit
Reads the header's scale, offset, minimum and maximum and refuses a scale that cannot be used.
All twelve values are read as 64-bit doubles and kept as read. A scale of 0, a scale larger than 1e6 in size, or any scale or offset that is not finite stops the import.
Reads an unsigned 64-bit integer (LAS 1.4 point count, extended record positions and lengths).
value = hi × 2³² + lo
Built from two unsigned 32-bit halves in a 64-bit number. The result is exact up to 2⁵³; a larger value would lose its low bits.
las.js
line 38
CadCraft 0.8.2
const u64 = (dv, o) => { const lo = dv.getUint32(o, true), hi = dv.getUint32(o + 4, true); return hi * 4294967296 + lo; };
Points the file really holds
Exact
The number of whole point records between the first point and the end of the point data.
available = ⌊(end − offset to points) ÷ record length⌋, at most the header's count
Whole numbers divided and rounded down. When the result is below the header's count, the smaller number is used and a note says so; for a compressed file the header's count is kept.
las.js
lines 97 to 101
CadCraft 0.8.2
let available = count;
if (!compressed) {
available = Math.floor((end - offsetToPoints) / recordLength);
if (available < count) notes.push(t('las.short', { available: available.toLocaleString('en-US'), count: count.toLocaleString('en-US') }));
else available = count;
In detail
Method
coordinate = stored integer × scale + offset, per axis (LAS 1.0 to 1.4; LAZ points are decoded by the laz-perf library and then read the same way).
Number types
Signed 32-bit integers from the file; 64-bit scale, offset and results.
Limits
The file's scale sets the resolution. A 64-bit count or offset above 2⁵³ would lose its low bits. A scale of 0, above 1e6 in size or not finite is refused.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.