From d9dfb4ae822ad779198a61c644a3e19dbc91bd71 Mon Sep 17 00:00:00 2001 From: artem Date: Fri, 18 Sep 2026 21:02:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D1=81=D1=82=D0=BE=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BC=D0=B0=D1=80=D1=88=D1=80=D1=83=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/roadSnap.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/services/roadSnap.ts diff --git a/src/services/roadSnap.ts b/src/services/roadSnap.ts new file mode 100644 index 0000000..82ad997 --- /dev/null +++ b/src/services/roadSnap.ts @@ -0,0 +1,23 @@ +/** + * Привязывает точку к ближайшей дороге через GraphHopper Cloud API. + * Free tier: 2000 req/день, без API key. + * Fallback: если API недоступен — возвращает исходные координаты. + */ +export async function snapToRoad( + lon: number, + lat: number, +): Promise<[number, number]> { + try { + const res = await fetch( + `https://graphhopper.com/api/1/snap?point=${lat},${lon}&layers=road`, + ); + if (!res.ok) return [lon, lat]; + const data: { points: { lat: number; lon: number }[] } = await res.json(); + if (data.points && data.points.length > 0) { + return [data.points[0].lon, data.points[0].lat]; + } + return [lon, lat]; + } catch { + return [lon, lat]; + } +}