fix: make stop data consistent

This commit is contained in:
uku 2024-10-25 11:56:53 +02:00
parent 61fdb1adba
commit 2255355f21
Signed by: uku
SSH key fingerprint: SHA256:4P0aN6M8ajKukNi6aPOaX0LacanGYtlfjmN+m/sHY/o
4 changed files with 34 additions and 13 deletions

View file

@ -1,6 +1,7 @@
export interface GameData { export interface GameData {
center: [number, number]; center: [number, number];
lines: [GeoJSON.Feature, string][]; lines: [GeoJSON.Feature, string][];
stops: GeoJSON.Feature[];
stopName: string; stopName: string;
stopId: string; stopId: string;
} }
@ -24,12 +25,34 @@ const stopsUrl =
"https://data.grandlyon.com/geoserver/sytral/ows?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=sytral:tcl_sytral.tclarret&outputFormat=application/json&SRSNAME=EPSG:4171&sortBy=gid"; "https://data.grandlyon.com/geoserver/sytral/ows?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=sytral:tcl_sytral.tclarret&outputFormat=application/json&SRSNAME=EPSG:4171&sortBy=gid";
let lazyLines: GeoJSON.FeatureCollection | null = null; let lazyLines: GeoJSON.FeatureCollection | null = null;
let lazyStops: GeoJSON.FeatureCollection | null = null; let lazyStops: GeoJSON.Feature[] | null = null;
export async function getLines(fetch: FetchType): Promise<GeoJSON.FeatureCollection> { export async function getLines(fetch: FetchType): Promise<GeoJSON.FeatureCollection> {
return lazyLines ?? (lazyLines = await fetch(linesUrl).then((r) => r.json())); return lazyLines ?? (lazyLines = await fetch(linesUrl).then((r) => r.json()));
} }
export async function getStops(fetch: FetchType): Promise<GeoJSON.FeatureCollection> { export async function getStops(fetch: FetchType): Promise<GeoJSON.Feature[]> {
return lazyStops ?? (lazyStops = await fetch(stopsUrl).then((r) => r.json())); if (!lazyStops) {
const stops: GeoJSON.FeatureCollection = await fetch(stopsUrl).then((r) => r.json());
lazyStops = Array.from(new Set(stops.features.map((f) => f.properties?.nom))).map((nom) => {
const matching = stops.features.filter((f) => f.properties?.nom === nom);
const longs = matching.map((f) => (f.geometry as GeoJSON.Point).coordinates[0]);
const lonAvg = longs.reduce((a, b) => a + b) / longs.length;
const lats = matching.map((f) => (f.geometry as GeoJSON.Point).coordinates[1]);
const latAvg = lats.reduce((a, b) => a + b) / lats.length;
const desserte = matching.map((f) => f.properties?.desserte).join(",");
const feature = matching[0];
feature.geometry = { type: "Point", coordinates: [lonAvg, latAvg] };
if (feature.properties) feature.properties.desserte = desserte;
return feature;
});
}
return lazyStops;
} }

View file

@ -15,13 +15,12 @@
let { data }: Props = $props(); let { data }: Props = $props();
const hidden = !$page.url.searchParams.has("debug"); const hidden = !$page.url.searchParams.has("debug");
const lignes = data.gameData.lines;
const center = L.latLng(data.gameData.center); const center = L.latLng(data.gameData.center);
const linesJson = lignes.map(([feature, color]) => { const linesJson = data.gameData.lines.map(([feature, color]) => {
return L.geoJSON(feature, { style: { color } }); return L.geoJSON(feature, { style: { color } });
}); });
const pointsJson = data.gameData.stops.map((f) => L.geoJSON(f));
let latlng = $state(L.latLng(0, 0)); let latlng = $state(L.latLng(0, 0));
let results: CheckResponse | null = $state(null); let results: CheckResponse | null = $state(null);
@ -49,8 +48,10 @@
if (lines) { if (lines) {
linesJson.forEach((line) => line.addTo(map!)); linesJson.forEach((line) => line.addTo(map!));
pointsJson.forEach((p) => p.addTo(map!));
} else { } else {
linesJson.forEach((line) => line.removeFrom(map!)); linesJson.forEach((line) => line.removeFrom(map!));
pointsJson.forEach((p) => p.removeFrom(map!));
} }
}); });

View file

@ -5,7 +5,7 @@ export const POST: RequestHandler = async ({ fetch, request }) => {
const stops = await getStops(fetch); const stops = await getStops(fetch);
const data: CheckData = await request.json(); const data: CheckData = await request.json();
const stop = stops.features.find((f) => f.id === data.stopId); const stop = stops.find((f) => f.id === data.stopId);
if (stop) { if (stop) {
// GeoJSON data is LonLat, not LatLon // GeoJSON data is LonLat, not LatLon

View file

@ -16,7 +16,7 @@ export const GET: RequestHandler = async ({ fetch }) => {
const lineCodes = new Set<string>(lines.features.map((f) => f.properties!.code_ligne)); const lineCodes = new Set<string>(lines.features.map((f) => f.properties!.code_ligne));
const crossingStops = stops.features.filter((f) => { const crossingStops = stops.filter((f) => {
if (f.properties?.desserte) { if (f.properties?.desserte) {
return f.properties.desserte return f.properties.desserte
.split(",") .split(",")
@ -27,15 +27,12 @@ export const GET: RequestHandler = async ({ fetch }) => {
} }
}); });
const uniqueStops = crossingStops.filter( const randomStop = crossingStops[Math.floor(Math.random() * crossingStops.length)];
(f1, i, arr) => arr.findIndex((f2) => f2.properties?.nom === f1.properties?.nom) === i,
);
const randomStop = uniqueStops[Math.floor(Math.random() * uniqueStops.length)];
const data: GameData = { const data: GameData = {
center: [centerLat, centerLon], center: [centerLat, centerLon],
lines: lineColors, lines: lineColors,
stops: crossingStops,
stopName: randomStop.properties!.nom, stopName: randomStop.properties!.nom,
stopId: randomStop.id!.toString(), stopId: randomStop.id!.toString(),
}; };