mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Merge pull request #1442 from Rohilalala/fix/e-traffic-coverage-rounding
fix(traffic): stop a few matched roads reading as "no matches"
This commit is contained in:
4 files changed
+42
-5
No files matched your search
@@ -0,0 +1,4 @@
|
|||||||
|
- Keep Street Traffic's flow status honest at the edges. A few TomTom-matched
|
||||||
|
dots among hundreds rounded to 0% and read "(no matches)", and a few
|
||||||
|
simulated dots rounded to "100% cov"; coverage now stays within 1–99% while
|
||||||
|
both are shown (Aditya, @Rohilalala, #1442).
|
||||||
@@ -5987,9 +5987,11 @@ easier to meet (detection is now on more often), but does not create it.
|
|||||||
OSM choice), so Hybrid fill is never replayed as OSM roads. Failed flow
|
OSM choice), so Hybrid fill is never replayed as OSM roads. Failed flow
|
||||||
refreshes clear old matches and report simulation. `flowCoveragePct` is the
|
refreshes clear old matches and report simulation. `flowCoveragePct` is the
|
||||||
percentage of shown dots on roads with flow, including all unmatched dots in
|
percentage of shown dots on roads with flow, including all unmatched dots in
|
||||||
the denominator and excluding dots hidden by closures. The OSM keyed status
|
the denominator and excluding dots hidden by closures. It reads 1–99 whenever
|
||||||
reads `LIVE · Roads: OpenStreetMap · Flow: TomTom · N% cov`. Road fetch
|
both matched and simulated dots are shown, so rounding never turns a few
|
||||||
coverage follows a 5×5 ellipsoid sample of the central screen square.
|
matches into `(no matches)` or a few simulated dots into full coverage. The
|
||||||
|
OSM keyed status reads `LIVE · Roads: OpenStreetMap · Flow: TomTom · N% cov`.
|
||||||
|
Road fetch coverage follows a 5×5 ellipsoid sample of the central screen square.
|
||||||
Horizon rays are capped at 10 km from nadir (reduced if necessary to fit
|
Horizon rays are capped at 10 km from nadir (reduced if necessary to fit
|
||||||
16 z12 tiles); polygon-intersecting tiles load nearest first. Up to 16 z14
|
16 z12 tiles); polygon-intersecting tiles load nearest first. Up to 16 z14
|
||||||
tiles provide near detail, with z12 roads beyond them. Cached tiles serve
|
tiles provide near detail, with z12 roads beyond them. Cached tiles serve
|
||||||
|
|||||||
Vendored
+13
-2
@@ -259,7 +259,8 @@ export function createControls({ state: layerState, services, parts, source }) {
|
|||||||
* `error` carries this instant's health, so a live-configured layer whose
|
* `error` carries this instant's health, so a live-configured layer whose
|
||||||
* flow feed went down reads DEGRADED with the reason instead of a stale
|
* flow feed went down reads DEGRADED with the reason instead of a stale
|
||||||
* LIVE coverage number. `flowCoveragePct` is shown dots on matched roads /
|
* LIVE coverage number. `flowCoveragePct` is shown dots on matched roads /
|
||||||
* all shown dots (0–100 int), excluding closures; `tilesFetched` counts flow-tile requests
|
* all shown dots (0–100 int, kept within 1–99 while both kinds are shown),
|
||||||
|
* excluding closures; `tilesFetched` counts flow-tile requests
|
||||||
* issued to the proxy this session (decode-cache hits excluded).
|
* issued to the proxy this session (decode-cache hits excluded).
|
||||||
* @returns {{count:number, lastUpdate:number|null, loading:boolean,
|
* @returns {{count:number, lastUpdate:number|null, loading:boolean,
|
||||||
* mode:'live'|'sim', error:string|null, flowCoveragePct:number,
|
* mode:'live'|'sim', error:string|null, flowCoveragePct:number,
|
||||||
@@ -304,8 +305,18 @@ export function createControls({ state: layerState, services, parts, source }) {
|
|||||||
Boolean(layerState._heightPending);
|
Boolean(layerState._heightPending);
|
||||||
const { free, slow, jam, sim } = layerState._bucketCounts;
|
const { free, slow, jam, sim } = layerState._bucketCounts;
|
||||||
const matched = free + slow + jam;
|
const matched = free + slow + jam;
|
||||||
|
// The label reads 0 as "no matches" and 100 as nothing simulated, so
|
||||||
|
// rounding must not reach either while both kinds of dot are shown.
|
||||||
const flowCoveragePct =
|
const flowCoveragePct =
|
||||||
matched + sim > 0 ? Math.round((100 * matched) / (matched + sim)) : 0;
|
matched + sim > 0
|
||||||
|
? Math.min(
|
||||||
|
sim > 0 ? 99 : 100,
|
||||||
|
Math.max(
|
||||||
|
matched > 0 ? 1 : 0,
|
||||||
|
Math.round((100 * matched) / (matched + sim)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: 0;
|
||||||
const feed = parts.model.trafficFeedPresentation({
|
const feed = parts.model.trafficFeedPresentation({
|
||||||
liveMode: layerState._liveMode,
|
liveMode: layerState._liveMode,
|
||||||
fetching: loading,
|
fetching: loading,
|
||||||
|
|||||||
@@ -516,6 +516,26 @@ test('late closures hide and stop dots; coverage counts shown matched dots, and
|
|||||||
assert.equal(controls.getStats().flowCoveragePct, 80);
|
assert.equal(controls.getStats().flowCoveragePct, 80);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('coverage never rounds to "no matches" or full coverage while both kinds of dot are shown', async () => {
|
||||||
|
const { state, controls } = await matchingContext(async () => []);
|
||||||
|
state._bucketCounts = { free: 1, slow: 0, jam: 0, sim: 300 };
|
||||||
|
assert.equal(controls.getStats().flowCoveragePct, 1);
|
||||||
|
assert.equal(
|
||||||
|
controls.getStats().loadingLabel,
|
||||||
|
'LIVE · Roads: OpenStreetMap · Flow: TomTom · 1% cov · Unmatched: simulated',
|
||||||
|
);
|
||||||
|
state._bucketCounts = { free: 300, slow: 0, jam: 0, sim: 1 };
|
||||||
|
assert.equal(controls.getStats().flowCoveragePct, 99);
|
||||||
|
assert.equal(
|
||||||
|
controls.getStats().loadingLabel,
|
||||||
|
'LIVE · Roads: OpenStreetMap · Flow: TomTom · 99% cov · Unmatched: simulated',
|
||||||
|
);
|
||||||
|
state._bucketCounts = { free: 300, slow: 0, jam: 0, sim: 0 };
|
||||||
|
assert.equal(controls.getStats().flowCoveragePct, 100);
|
||||||
|
state._bucketCounts = { free: 0, slow: 0, jam: 0, sim: 300 };
|
||||||
|
assert.equal(controls.getStats().flowCoveragePct, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('refresh failure removes cached matches and reports simulated flow', async () => {
|
test('refresh failure removes cached matches and reports simulated flow', async () => {
|
||||||
const { flow, state, model, controls } = await matchingContext(async () => {
|
const { flow, state, model, controls } = await matchingContext(async () => {
|
||||||
throw new Error('HTTP 429');
|
throw new Error('HTTP 429');
|
||||||
|
|||||||
Reference in new issue
Block a user