Reads survey points from CSV or text files, counts them by description group, and writes them back as a PNEZD file.
How the precision is kept
Coordinates are converted from text with Number(), which gives the nearest 64-bit value to the decimal typed. The writer rounds northing, easting and elevation to a fixed number of decimals, 3 by default.
Calculations under this policy
3 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.
Takes the northing, easting and elevation of one line of a point file.
The three fields are checked with isNum and converted with Number(), the nearest 64-bit value to the decimal text. An empty elevation is stored as null, not 0. A duplicate point number is refused and counted.
points.js
lines 84 to 94
CivilCraft 0.8.1
const N = c[iN], E = c[iE], Z = c[iZ];
if (!isNum(N) || !isNum(E)) { bad(r, t('pts.bad.ne')); continue; }
if (Z !== undefined && Z !== '' && !isNum(Z)) { bad(r, t('pts.bad.z')); continue; }
if (out.latlon && (Math.abs(Number(N)) > 90 || Math.abs(Number(E)) > 180)) { bad(r, t('pts.bad.latlon')); continue; }
let n = iP >= 0 ? String(c[iP] ?? '').trim() : '';
if (iP >= 0 && !n) { bad(r, t('pts.bad.nonum')); continue; }
if (iP < 0) { do n = String(++auto); while (seen.has(n)); }
if (seen.has(n)) { out.duplicates++; bad(r, t('pts.bad.twice', { num: n })); continue; }
seen.add(n);
const z = Z === undefined || Z === '' ? null : Number(Z);
out.points.push({ n, x: Number(E), y: Number(N), z, d: iD >= 0 ? cleanText(c[iD] ?? '') : '' });
Points written as a PNEZD file
64-bit
Writes point number, northing, easting, elevation and description, comma separated.
N, E and Z written with dec decimals (3 by default)
Each coordinate is written with toFixed(dec). With the default, a coordinate with seven digits before the decimal point is written with 10 significant digits, fewer than the 64-bit value holds.
points.js
lines 182 to 186
CivilCraft 0.8.1
/** A PNEZD comma file of the points (descriptions quoted when they hold a comma or quote). */
export function writePoints(points, dec = 3) {
const q = (s) => (/[",]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s);
return points.map((p) => [q(String(p.n)), p.y.toFixed(dec), p.x.toFixed(dec), p.z === null ? '' : p.z.toFixed(dec), q(p.d || '')].join(',')).join('\r\n') + '\r\n';
}
Point count per group
Exact
Counts the points of each description group.
Whole-number counts kept in a Map, one increment per point, then sorted by group name.
points.js
lines 159 to 163
CivilCraft 0.8.1
export function pointGroups(points, keyOf = null) { // keyOf(point) → group (0.4 V16: description keys); default the first word
const m = new Map();
for (const p of points) { const k = keyOf ? keyOf(p) : groupKey(p.d); m.set(k, (m.get(k) || 0) + 1); }
return [...m].map(([key, count]) => ({ key, count })).sort((a, b) => a.key.localeCompare(b.key));
}
In detail
Method
Rows are split on the detected delimiter and mapped to columns by the format (PNEZD and its variants); numbers are converted with Number().
Number types
64-bit numbers; whole-number counts.
Limits
writePoints writes 3 decimals unless the caller asks for more. Latitude and longitude rows outside ±90° and ±180° are 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.