feat: use snapped location by default
Some checks are pending
TrafficCue CI / check (push) Has started running

This commit is contained in:
2025-10-25 18:49:34 +02:00
parent 640a2e8ef6
commit 1f99976f97
4 changed files with 31 additions and 17 deletions

View File

@ -7,7 +7,7 @@
decodePolyline, decodePolyline,
routing, routing,
} from "$lib/services/navigation/routing.svelte"; } from "$lib/services/navigation/routing.svelte";
import { getSnappedLocation, location } from "./location.svelte"; import { location } from "./location.svelte";
import RoutingLayers from "$lib/services/navigation/RoutingLayers.svelte"; import RoutingLayers from "$lib/services/navigation/RoutingLayers.svelte";
import { import {
getPMTilesURL, getPMTilesURL,
@ -137,15 +137,6 @@
pitchAlignment="map" pitchAlignment="map"
/> />
{/if} {/if}
{#if getSnappedLocation().current}
<Marker
lnglat={{
lat: getSnappedLocation().current!.lat,
lng: getSnappedLocation().current!.lon,
}}
color="blue"
/>
{/if}
<MapLocationMarkers /> <MapLocationMarkers />

View File

@ -34,6 +34,7 @@ export const location = $state({
advertiser: null as WebSocket | null, advertiser: null as WebSocket | null,
code: null as string | null, code: null as string | null,
lastUpdate: null as Date | null, lastUpdate: null as Date | null,
useSnapped: true,
}); });
const _isDriving = $derived(location.speed > 7 / 3.6); const _isDriving = $derived(location.speed > 7 / 3.6);
@ -48,6 +49,9 @@ const roadMetadata: WrappedValue<GeoJSON.GeoJsonProperties> = $state({
const roadFeature: WrappedValue<GeoJSON.Feature | null> = $state({ const roadFeature: WrappedValue<GeoJSON.Feature | null> = $state({
current: null, current: null,
}); });
const rawLocation: WrappedValue<WorldLocation | null> = $state({
current: null,
});
const snappedLocation: WrappedValue<WorldLocation | null> = $state({ const snappedLocation: WrappedValue<WorldLocation | null> = $state({
current: null, current: null,
}); });
@ -69,8 +73,9 @@ function snapLocation() {
const feature = roadFeature.current; const feature = roadFeature.current;
console.log("Snapping location to road feature:", feature); console.log("Snapping location to road feature:", feature);
if (!feature) return; if (!feature) return;
if (!rawLocation.current) return;
if (feature.geometry.type === "LineString") { if (feature.geometry.type === "LineString") {
const loc = nearestPointOnLine(lineString(feature.geometry.coordinates), point([location.lng, location.lat])); const loc = nearestPointOnLine(lineString(feature.geometry.coordinates), point([rawLocation.current.lon, rawLocation.current.lat]));
snappedLocation.current = { snappedLocation.current = {
lat: loc.geometry.coordinates[1], lat: loc.geometry.coordinates[1],
lon: loc.geometry.coordinates[0], lon: loc.geometry.coordinates[0],
@ -80,10 +85,10 @@ function snapLocation() {
let nearestLoc: GeoJSON.Feature<GeoJSON.Point> | null = null; let nearestLoc: GeoJSON.Feature<GeoJSON.Point> | null = null;
let minDist = Infinity; let minDist = Infinity;
for (const coords of feature.geometry.coordinates) { for (const coords of feature.geometry.coordinates) {
const loc = nearestPointOnLine(lineString(coords), point([location.lng, location.lat])); const loc = nearestPointOnLine(lineString(coords), point([rawLocation.current.lon, rawLocation.current.lat]));
const dist = Math.hypot( const dist = Math.hypot(
loc.geometry.coordinates[0] - location.lng, loc.geometry.coordinates[0] - rawLocation.current.lon,
loc.geometry.coordinates[1] - location.lat, loc.geometry.coordinates[1] - rawLocation.current.lat,
); );
if (dist < minDist) { if (dist < minDist) {
minDist = dist; minDist = dist;
@ -105,8 +110,14 @@ export function watchLocation() {
(pos) => { (pos) => {
if (location.provider !== "gps") return; if (location.provider !== "gps") return;
// console.log("Geolocation update:", pos) // console.log("Geolocation update:", pos)
rawLocation.current = {
lat: pos.coords.latitude,
lon: pos.coords.longitude,
};
if(!location.useSnapped) {
location.lat = pos.coords.latitude; location.lat = pos.coords.latitude;
location.lng = pos.coords.longitude; location.lng = pos.coords.longitude;
}
location.accuracy = pos.coords.accuracy; location.accuracy = pos.coords.accuracy;
location.speed = pos.coords.speed || 0; location.speed = pos.coords.speed || 0;
location.available = true; location.available = true;
@ -115,7 +126,7 @@ export function watchLocation() {
const blacklist = ["path", "track", "raceway", "busway", "bus_guideway", "ferry"]; const blacklist = ["path", "track", "raceway", "busway", "bus_guideway", "ferry"];
getFeature( getFeature(
{ lat: location.lat, lon: location.lng }, { lat: rawLocation.current.lat, lon: rawLocation.current.lon },
"transportation", "transportation",
{ {
filter: (f) => { filter: (f) => {
@ -131,6 +142,10 @@ export function watchLocation() {
roadMetadata.current = feature ? feature.properties : null; roadMetadata.current = feature ? feature.properties : null;
lastFeatureId = feature ? String(feature.id) : null; lastFeatureId = feature ? String(feature.id) : null;
snapLocation(); snapLocation();
if(location.useSnapped && snappedLocation.current) {
location.lat = snappedLocation.current.lat;
location.lng = snappedLocation.current.lon;
}
}); });
if (location.locked) { if (location.locked) {

View File

@ -1,5 +1,7 @@
<script> <script>
import { m } from "$lang/messages"; import { m } from "$lang/messages";
import { BeakerIcon } from "@lucide/svelte";
import { location } from "../../location.svelte";
import SidebarHeader from "../SidebarHeader.svelte"; import SidebarHeader from "../SidebarHeader.svelte";
import SettingsToggle from "./SettingsToggle.svelte"; import SettingsToggle from "./SettingsToggle.svelte";
</script> </script>
@ -12,3 +14,8 @@
text={m["sidebar.appearance.bigger-buttons-in-drive"]()} text={m["sidebar.appearance.bigger-buttons-in-drive"]()}
localStorageKey="bigger-buttons-in-drive" localStorageKey="bigger-buttons-in-drive"
/> />
<SettingsToggle
text="Use snapped location (experimental)"
bind:value={location.useSnapped}
icon={BeakerIcon}
/>

View File

@ -53,6 +53,7 @@ export async function getFeature(coord: WorldLocation, layer: string, { lastId,
console.log("lastId:", lastId, "a.id:", a.id, "b.id:", b.id); console.log("lastId:", lastId, "a.id:", a.id, "b.id:", b.id);
const STAY_BIAS = getBias(); const STAY_BIAS = getBias();
// TODO: don't bias if feature is continuing straight (split ways vs turn)
if (lastId && String(a.id) == lastId) { if (lastId && String(a.id) == lastId) {
console.log("Applying stay bias to B"); console.log("Applying stay bias to B");
distB += STAY_BIAS; distB += STAY_BIAS;