Humanize turn-by-turn distances; drop arrival step distance
All checks were successful
CI / test-and-build (push) Successful in 1m2s
All checks were successful
CI / test-and-build (push) Successful in 1m2s
This commit is contained in:
parent
fb6ad3eb0c
commit
1d4ae6c76d
@ -119,6 +119,66 @@
|
||||
return min ? `${h} h ${min} min` : `${h} h`;
|
||||
}
|
||||
|
||||
// ---- Humanized (spoken-style) distance phrasing for the turn-by-turn list ----
|
||||
// e.g. "500 ft", "half a mile", "a quarter mile", "1 and a half miles", "2 km".
|
||||
function fracWords(f: number): string {
|
||||
if (Math.abs(f - 0.25) < 0.001) return 'a quarter';
|
||||
if (Math.abs(f - 0.5) < 0.001) return 'a half';
|
||||
if (Math.abs(f - 0.75) < 0.001) return 'three-quarters';
|
||||
return `${f.toFixed(2)}`;
|
||||
}
|
||||
function friendlyMiles(mi: number): string {
|
||||
if (mi >= 10) return `${Math.round(mi)} miles`;
|
||||
const q = Math.round((mi + Number.EPSILON) * 4) / 4; // nearest quarter mile
|
||||
const whole = Math.floor(q);
|
||||
const frac = q - whole;
|
||||
const unit = whole === 1 ? 'mile' : 'miles';
|
||||
if (whole === 0) {
|
||||
if (Math.abs(frac - 0.25) < 0.001) return 'a quarter mile';
|
||||
if (Math.abs(frac - 0.5) < 0.001) return 'half a mile';
|
||||
if (Math.abs(frac - 0.75) < 0.001) return 'three-quarters of a mile';
|
||||
return `${q.toFixed(2)} miles`;
|
||||
}
|
||||
if (frac === 0) return whole === 1 ? '1 mile' : `${whole} miles`;
|
||||
return `${whole} and ${fracWords(frac)} miles`;
|
||||
}
|
||||
function friendlyKms(km: number): string {
|
||||
if (km >= 10) return `${Math.round(km)} km`;
|
||||
const q = Math.round((km + Number.EPSILON) * 4) / 4;
|
||||
const whole = Math.floor(q);
|
||||
const frac = q - whole;
|
||||
if (whole === 0) {
|
||||
if (Math.abs(frac - 0.25) < 0.001) return 'a quarter km';
|
||||
if (Math.abs(frac - 0.5) < 0.001) return 'half a km';
|
||||
if (Math.abs(frac - 0.75) < 0.001) return 'three-quarters of a km';
|
||||
return `${q.toFixed(2)} km`;
|
||||
}
|
||||
if (frac === 0) return whole === 1 ? '1 km' : `${whole} km`;
|
||||
return `${whole} and ${fracWords(frac)} km`;
|
||||
}
|
||||
function humanizeDistance(m: number): string {
|
||||
if ($prefs.system === 'imperial') {
|
||||
const ft = m * 3.28084;
|
||||
const mi = m / 1609.344;
|
||||
if (mi < 0.12) {
|
||||
let f = Math.round(ft / 50) * 50; // '500 ft'
|
||||
if (f < 75) f = Math.round(ft / 10) * 10; // below ~75ft be more precise
|
||||
return `${Math.max(20, f)} ft`;
|
||||
}
|
||||
return friendlyMiles(mi);
|
||||
}
|
||||
if (m < 200) {
|
||||
let d = Math.round(m / 25) * 25;
|
||||
if (d < 50) d = Math.round(m);
|
||||
return `${Math.max(10, d)} m`;
|
||||
}
|
||||
return friendlyKms(m / 1000);
|
||||
}
|
||||
// Detects the terminal step so we can drop its (always 0) distance.
|
||||
function isArrival(t: TurnStep): boolean {
|
||||
return t.instruction === 'Arrive at destination';
|
||||
}
|
||||
|
||||
// --- destination (set via the context dialog or search/picked below) ---
|
||||
function setDestination(lat: number, lon: number, label?: string) {
|
||||
onDestinationChange({ lat, lon, label });
|
||||
@ -360,7 +420,11 @@
|
||||
<div class="turns-head"><span>Turn-by-turn</span></div>
|
||||
<ol class="turnlist">
|
||||
{#each turns.list as t, i (i + '-' + t.instruction)}
|
||||
<li><span class="tdist">{formatDistance(t.distanceM)}</span><span class="tins">{t.instruction}</span></li>
|
||||
{#if isArrival(t)}
|
||||
<li><span class="tarrival">{t.instruction}</span></li>
|
||||
{:else}
|
||||
<li><span class="tdist">{humanizeDistance(t.distanceM)}</span><span class="tins">{t.instruction}</span></li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ol>
|
||||
<div class="turns-total">{turns.list.length} steps · {formatDistance(turns.total)} total</div>
|
||||
@ -444,6 +508,7 @@
|
||||
.turnlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
|
||||
.turnlist li { display: flex; gap: 8px; align-items: baseline; font-size: 0.74rem; }
|
||||
.tdist { color: #0ea5e9; font-weight: 600; min-width: 52px; }
|
||||
.tarrival { font-weight: 700; color: #16a34a; }
|
||||
.tins { color: #0f172a; }
|
||||
.turns-total { color: #94a3b8; font-size: 0.68rem; margin-top: 4px; }
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user