This commit is contained in:
@ -3,15 +3,16 @@ import { FSSource, hasPMTiles } from "./OfflineTiles";
|
||||
import { PMTiles } from "pmtiles";
|
||||
import { VectorTile } from "@mapbox/vector-tile";
|
||||
import Protobuf from "pbf";
|
||||
import { location } from "$lib/components/lnv/location.svelte";
|
||||
|
||||
function getFeatureDistance(f: GeoJSON.Feature, point: [number, number]) {
|
||||
if (f.geometry.type === "LineString") {
|
||||
return pointToLineDistance(point, lineString(f.geometry.coordinates));
|
||||
return pointToLineDistance(point, lineString(f.geometry.coordinates), { units: "meters" });
|
||||
} else if (f.geometry.type === "MultiLineString") {
|
||||
// Compute the min distance across all parts
|
||||
return Math.min(
|
||||
...f.geometry.coordinates.map((coords) =>
|
||||
pointToLineDistance(point, lineString(coords)),
|
||||
pointToLineDistance(point, lineString(coords), { units: "meters" }),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
@ -19,7 +20,17 @@ function getFeatureDistance(f: GeoJSON.Feature, point: [number, number]) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getFeature(coord: WorldLocation, layer: string, filter?: (feature: GeoJSON.Feature) => boolean) {
|
||||
interface GetFeatureOptions {
|
||||
lastId?: string;
|
||||
filter?: (feature: GeoJSON.Feature) => boolean;
|
||||
}
|
||||
|
||||
function getBias() {
|
||||
if(!location.speed) return 5;
|
||||
return Math.max(5, Math.min(15, location.speed * 0.5)); // Bias increases with speed, min 5, max 15, 0.5 per km/h
|
||||
}
|
||||
|
||||
export async function getFeature(coord: WorldLocation, layer: string, { lastId, filter }: GetFeatureOptions = {}) {
|
||||
const zxy = coordToTile(coord, 14);
|
||||
const tile = await fetchTile(zxy.z, zxy.x, zxy.y);
|
||||
const layerData = tile.layers[layer];
|
||||
@ -36,15 +47,31 @@ export async function getFeature(coord: WorldLocation, layer: string, filter?: (
|
||||
).filter((f) => (filter ? filter(f) : true));
|
||||
if (filtered.length === 0) return null;
|
||||
const nearest = filtered.reduce((a, b) => {
|
||||
const distA = getFeatureDistance(a, [coord.lon, coord.lat]);
|
||||
const distB = getFeatureDistance(b, [coord.lon, coord.lat]);
|
||||
let distA = getFeatureDistance(a, [coord.lon, coord.lat]);
|
||||
let distB = getFeatureDistance(b, [coord.lon, coord.lat]);
|
||||
|
||||
console.log("lastId:", lastId, "a.id:", a.id, "b.id:", b.id);
|
||||
const STAY_BIAS = getBias();
|
||||
|
||||
if (lastId && String(a.id) == lastId) {
|
||||
console.log("Applying stay bias to B");
|
||||
distB += STAY_BIAS;
|
||||
}
|
||||
if (lastId && String(b.id) == lastId) {
|
||||
console.log("Applying stay bias to A");
|
||||
distA += STAY_BIAS;
|
||||
}
|
||||
|
||||
console.log("Distances:", distA, distB);
|
||||
|
||||
return distA < distB ? a : b;
|
||||
});
|
||||
console.log("ID: ", nearest.id);
|
||||
return nearest;
|
||||
}
|
||||
|
||||
export async function getMeta(coord: WorldLocation, layer: string, filter?: (feature: GeoJSON.Feature) => boolean) {
|
||||
const nearest = await getFeature(coord, layer, filter);
|
||||
export async function getMeta(coord: WorldLocation, layer: string, options?: GetFeatureOptions) {
|
||||
const nearest = await getFeature(coord, layer, options);
|
||||
return nearest ? nearest.properties : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user