fix(draw): show a 9,999.6 m² area as 1.0 ha, not 10000 m²

The draw hint picked m², ha or km² from the raw area and then rounded,
so 9,999.5 m² up to a hectare read "10000 m²" and about 999,500 m² up
to a square kilometre read "100.0 ha". It now rounds first, as the line
measure already does.
This commit is contained in:
Aditya committed 2026-10-28 15:25:08 +05:30
1 parent a4d3701c3c
commit d1bbfdbca5
3 files changed
+34 -3

No files matched your search

+6 -3
View File
@@ -215,9 +215,12 @@ export function formatMeasure(session) {
}
if (session.shape === 'area') {
const m2 = ringAreaM2(session.vertices);
if (m2 >= 1e6) return `${(m2 / 1e6).toFixed(2)} km²`;
if (m2 >= 1e4) return `${(m2 / 1e4).toFixed(1)} ha`;
return `${Math.round(m2)} m²`;
// Round before each unit cut, as for a line. 9,999.6 m² was "10000 m²".
const whole = Math.round(m2);
const ha = (m2 / 1e4).toFixed(1);
if (whole < 1e4) return `${whole} m²`;
if (Number(ha) < 100) return `${ha} ha`;
return `${(m2 / 1e6).toFixed(2)} km²`;
}
return '';
}
+27
View File
@@ -345,3 +345,30 @@ test('a line that rounds up to a kilometre reads 1.0 km, not 1000 m', () => {
assert.equal(formatMeasure(line), '1.0 km');
assert.match(drawHint(line), /^1\.0 km · /);
});
test('an area that rounds up to the next unit reads in that unit', () => {
// A square on the equator whose shoelace area is about `m2`.
const square = (m2) => {
const side = Math.sqrt(m2) / 111320;
const area = createDrawSession('area');
for (const [lon, lat] of [
[0, 0],
[side, 0],
[side, side],
[0, side],
])
addVertex(area, { lon, lat });
return area;
};
const almostHectare = square(9999.6);
const metres = ringAreaM2(almostHectare.vertices);
assert.ok(
metres >= 9999.5 && metres < 1e4,
`area should round to 10000 m², got ${metres}`,
);
assert.equal(formatMeasure(almostHectare), '1.0 ha');
assert.match(drawHint(almostHectare), /^1\.0 ha · /);
assert.equal(formatMeasure(square(9999.4)), '9999 m²');
assert.equal(formatMeasure(square(999_960)), '1.00 km²');
assert.equal(formatMeasure(square(999_400)), '99.9 ha');
});