From fd8f286e22f4f8b6a24123937c24c52b9c1407ba Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 27 Feb 2026 10:09:25 -0800 Subject: map updates --- index.ts | 1 + lib/locations.ts | 13 +++++++++++-- routes/locations.ts | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/index.ts b/index.ts index 3d07245b..5eba71b2 100644 --- a/index.ts +++ b/index.ts @@ -66,6 +66,7 @@ app.get("/rate", rates.last); app.get("/rates", rates.index); app.get("/locations", locations.list); +app.get("/locations/nearby", locations.nearby); app.get("/invoice/:id", invoices.get); app.get("/invoices", auth, invoices.list); diff --git a/lib/locations.ts b/lib/locations.ts index 91bc4599..734cd027 100644 --- a/lib/locations.ts +++ b/lib/locations.ts @@ -1,4 +1,4 @@ -import { g, s } from "$lib/db"; +import { db, g, s } from "$lib/db"; import { err } from "$lib/logging"; import { fields, getUser } from "$lib/utils"; import got from "got"; @@ -49,8 +49,17 @@ export const getLocations = async () => { locations.push(...previous); - await s("locations", dedup(locations)); + const dedupedLocations = dedup(locations); + await s("locations", dedupedLocations); await s("locations:since", `${new Date().toISOString().split(".")[0]}Z`); + + for (const loc of dedupedLocations) { + if (loc.deleted_at) continue; + const { lat, lon } = loc.osm_json; + if (!(lat && lon)) continue; + await db.geoAdd("locations:geo", { longitude: lon, latitude: lat, member: String(loc.id) }); + await s(`location:${loc.id}`, loc); + } } catch (e) { console.log(e); err("problem fetching locations", e); diff --git a/routes/locations.ts b/routes/locations.ts index d7a5b636..23b0f3b4 100644 --- a/routes/locations.ts +++ b/routes/locations.ts @@ -1,8 +1,44 @@ -import { g } from "$lib/db"; +import { db, g } from "$lib/db"; export default { async list(_, res) { const locations = await g("locations"); res.send({ locations }); }, + + async nearby(req, res) { + const lat = parseFloat(req.query.lat); + const lon = parseFloat(req.query.lon); + const radius = parseFloat(req.query.radius) || 50; + const count = parseInt(req.query.count) || 50; + + if (isNaN(lat) || isNaN(lon)) { + return res.status(400).send({ error: "lat and lon required" }); + } + + try { + const ids = await db.geoSearch("locations:geo", { + longitude: lon, + latitude: lat, + }, { + radius, + unit: "km", + }, { + COUNT: count, + SORT: "ASC", + }); + + const locations = []; + for (const id of ids) { + const loc = await g(`location:${id}`); + if (loc) locations.push(loc); + } + + res.send({ locations }); + } catch (e) { + console.log("nearby search failed", e); + const locations = await g("locations"); + res.send({ locations }); + } + }, }; -- cgit v1.2.3