fix(traffic): keep a TomTom side from pairing with its own pieces

A one_side line that doubles back within 5 m of itself, such as a
turnaround drawn as one line, matched its own return leg and took a
two-way half share with no partner. Flow index pieces now carry their
source line, and a radiusFor of 0 leaves a piece out of nearest(), so
pairing skips the line's own pieces.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
quanticsoul4772andClaude Opus 5.5 committed 2026-11-01 07:43:22 -08:00
1 parent 1cd4dde26d
commit 9caa0947b6
3 files changed
+14 -3

No files matched your search

+4 -2
View File
@@ -139,6 +139,7 @@ export function createFlowSegmentIndex(flowSegments) {
roadType,
level,
closure,
flow,
};
const key = cellKey(
Math.floor((seg.ax + seg.bx) / 2 / CELL_SIZE_M),
@@ -158,7 +159,8 @@ export function createFlowSegmentIndex(flowSegments) {
const radius2 = MATCH_RADIUS_M * MATCH_RADIUS_M;
/**
* Nearest direction-compatible segment within 35 m of a projected point.
* `radiusFor(segment)` may tighten the radius per segment (never widen it).
* `radiusFor(segment)` may tighten the radius per segment (never widen it);
* 0 leaves the segment out.
*/
function nearest(px, py, bearing, radiusFor = null) {
const cx = Math.floor(px / CELL_SIZE_M);
@@ -177,7 +179,7 @@ export function createFlowSegmentIndex(flowSegments) {
candidate = true; // within radius, bearing not yet checked
if (radiusFor) {
const radius = Math.min(MATCH_RADIUS_M, radiusFor(seg));
if (d2 > radius * radius) continue;
if (!(radius > 0) || d2 > radius * radius) continue;
}
const diff = bearingDiffDeg(seg.bearing, bearing);
if (
+2 -1
View File
@@ -126,7 +126,8 @@ function pairedSampleShare(segment, index) {
xs[i - 1] + dx * t,
ys[i - 1] + dy * t,
reverse,
() => PAIRED_SIDE_RADIUS_M,
// A line that doubles back beside itself is not its own pair.
(piece) => (piece.flow === segment ? 0 : PAIRED_SIDE_RADIUS_M),
).best
)
paired++;
+8
View File
@@ -163,6 +163,14 @@ test('a TomTom side paired along only part of its length keeps its share', () =>
assert.equal(weightOfFlow(partner(-97.7434)), 1);
assert.equal(weightOfFlow(partner(-97.7428)), 0.5);
});
test('a TomTom side that doubles back beside itself is not its own pair', () => {
// East along `coordinates`, then back west about 1 m north.
const hairpin = {
...flow,
coords: [...coordinates, [-97.742, 30.26701], [-97.744, 30.26701]],
};
assert.equal(flowSegmentsToRoads([hairpin])[0].densityWeight ?? 1, 1);
});
test('bearing and distance reject nearby crossing and separate OSM roads', () => {
const parallel = {
...main,