add user accounts and OSM peak catalog with zoom-based notability

This commit is contained in:
Vincent van der Wal
2026-07-22 11:10:59 +02:00
parent 196f30521c
commit b17f56b194
26 changed files with 1019 additions and 191 deletions
+13 -12
View File
@@ -1,10 +1,11 @@
import { fail } from '@sveltejs/kit';
import { db, listPeaks, markPeakClimbed } from '$lib/server/db';
import { db, peaksNearBounds, recordAscent } from '$lib/server/db';
import { matchPeaks, parseGpx } from '$lib/server/gpx';
import type { Actions } from './$types';
export const actions: Actions = {
default: async ({ request }) => {
default: async ({ request, locals }) => {
const userId = locals.user!.id;
const form = await request.formData();
const files = form.getAll('gpx').filter((f): f is File => f instanceof File && f.size > 0);
if (files.length === 0) return fail(400, { error: 'No GPX files selected.' });
@@ -14,10 +15,10 @@ export const actions: Actions = {
const insert = db.prepare(`
INSERT INTO activities
(name, type, date, distance_m, duration_s, moving_s,
(user_id, name, type, date, distance_m, duration_s, moving_s,
elev_gain_m, elev_loss_m, elev_min_m, elev_max_m, points, bounds)
VALUES
(@name, @type, @date, @distance_m, @duration_s, @moving_s,
(@user_id, @name, @type, @date, @distance_m, @duration_s, @moving_s,
@elev_gain_m, @elev_loss_m, @elev_min_m, @elev_max_m, @points, @bounds)
`);
@@ -25,6 +26,7 @@ export const actions: Actions = {
try {
const gpx = parseGpx(await file.text());
const result = insert.run({
user_id: userId,
name: gpx.name ?? file.name.replace(/\.gpx$/i, ''),
type: gpx.type ?? 'outdoor',
date: gpx.date,
@@ -40,15 +42,14 @@ export const actions: Actions = {
});
const activityId = Number(result.lastInsertRowid);
const unclimbed = listPeaks().filter((p) => !p.climbed_at);
const bagged = matchPeaks(gpx.points, unclimbed);
for (const peak of bagged) markPeakClimbed(peak.id, activityId, gpx.date);
const nearby = peaksNearBounds(gpx.bounds);
const summited = matchPeaks(gpx.points, nearby);
const newPeaks: string[] = [];
for (const peak of summited) {
if (recordAscent(userId, peak.id, activityId, gpx.date)) newPeaks.push(peak.name);
}
uploaded.push({
id: activityId,
name: gpx.name ?? file.name,
newPeaks: bagged.map((p) => p.name)
});
uploaded.push({ id: activityId, name: gpx.name ?? file.name, newPeaks });
} catch (err) {
errors.push(`${file.name}: ${err instanceof Error ? err.message : 'could not parse'}`);
}