fix: find cables that cross an area between vertices

Cable searches only tested vertices, so a cable crossing an area with no
vertex inside it was missed. Lines now test each segment against the area's
bounds, across the antimeridian too, and against a radius area's great-circle
distance.
This commit is contained in:
Sameh Khamis committed 2026-10-02 15:21:36 -07:00
1 parent 5b73b70d19
commit 6f56c84b0b
4 files changed
+201 -5

No files matched your search

+78 -1
View File
@@ -1,6 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { areaCenter, areaContains, distanceKm, resolveArea } from './area.js';
import {
areaCenter,
areaContains,
distanceKm,
lineTouchesArea,
resolveArea,
} from './area.js';
import { placeFromGeocodeResult } from './places.js';
test('an area needs exactly one form', async () => {
@@ -147,3 +153,74 @@ test('radius areas include every point within the radius, near the poles too', a
assert.ok(areaContains(wide, point), `bearing ${bearing}`);
}
});
test('lines touch an area when a segment crosses it with no vertex inside', async () => {
const box = await resolveArea({ bbox: [-1, -1, 1, 1] });
assert.ok(
lineTouchesArea(
[
[-2, 0],
[2, 0],
],
box,
),
);
assert.ok(
!lineTouchesArea(
[
[-2, 2],
[2, 2],
],
box,
),
);
const circle = await resolveArea({ lat: 0, lon: 0, radius_km: 50 });
assert.ok(
lineTouchesArea(
[
[-2, 0.3],
[2, 0.3],
],
circle,
),
);
// Inside the circle's box but beyond its radius.
assert.ok(
!lineTouchesArea(
[
[0.3, 0.42],
[0.6, 0.42],
],
circle,
),
);
const dateline = await resolveArea({ bbox: [179, -1, -179, 1] });
assert.ok(
lineTouchesArea(
[
[178, 0],
[-178, 0],
],
dateline,
),
);
const nearDateline = await resolveArea({ bbox: [179.5, -1, 179.9, 1] });
assert.ok(
lineTouchesArea(
[
[179, 0],
[-179, 0],
],
nearDateline,
),
);
assert.ok(
!lineTouchesArea(
[
[170, 0],
[175, 0],
],
nearDateline,
),
);
});