откатил построение марщрута через API
Gitea Actions Demo / build_and_push (push) Successful in 46s Details

This commit is contained in:
artem 2026-09-18 21:51:28 +03:00
parent d9dfb4ae82
commit 8056c5f132
3 changed files with 13 additions and 39 deletions

View File

@ -5,17 +5,19 @@
- task_id: TASK-ROUTE-FIX
- status: success
- parent_task: —
- summary: **FIX + FEATURE: Route.vue — багфикс GPX-генератора (for...in, дубликаты, фейковый ele) + snap to road через GraphHopper Cloud API.**
- summary: **FIX: Route.vue — багфикс GPX-генератора (for...in, дубликаты, фейковый ele) + фильтр близлежащих точек 5м. Snap to road убран (GraphHopper 401, риск блокировки OSM в РФ).**
- next task: —
## ✅ CODER SUCCESS REPORT — TASK-ROUTE-FIX
## ✅ CODER SUCCESS REPORT — TASK-ROUTE-FIX (final)
- Изменены файлы:
- `src/pages/routes/Route.vue`: `toGPX()` (var→const, for...in→index loop, ele fix), `handleMapClick` (async, 5m filter + snapToRoad), template onClick
- `src/services/roadSnap.ts` (НОВЫЙ): `snapToRoad(lon, lat)` → GraphHopper Cloud API, fallback к исходным координатам
- Поведение: клик рядом с дорогой → точка прилипает (snap); двойной клик < 5м → игнорируется; GraphHopper down → работает как раньше
- Изменён файл: `src/pages/routes/Route.vue`
- `toGPX()`: `var date` → `const date`, `for...in` → index-based loop, `<ele>${i}</ele>` → `<ele>0</ele>`
- `handleMapClick`: синхронная (не async), фильтр < 5м до последней точки (игнор клика), push без snap
- `SNAP_THRESHOLD_M` → `MIN_DISTANCE_M`
- Убран import `snapToRoad` (файл `src/services/roadSnap.ts` остался в репо, но не используется)
- Поведение: клик < 5м от последней точки → игнорируется; клик в другом месте → точка добавляется как есть; GPX генерируется корректно (index loop, ele=0)
- `yarn lint`: exit 0
- `yarn build`: exit 0 (vue-tsc --noEmit + vite build)
- `yarn build`: exit 0 (vue-tsc --noEmit 0 ошибок, vite build ✓ 6.58s)
## TASK-LINK1 — TODO (delegate to Coder)

View File

@ -89,7 +89,6 @@
import { ref, shallowRef } from "vue";
import type { LngLat, YMap } from "@yandex/ymaps3-types";
import { snapToRoad } from "../../services/roadSnap";
import {
YandexMap,
YandexMapDefaultSchemeLayer,
@ -108,25 +107,21 @@ const height = `${window.innerHeight}px`;
const map = shallowRef<null | YMap>(null);
const clickCoordinates = ref<LngLat[]>([]);
const SNAP_THRESHOLD_M = 5;
const MIN_DISTANCE_M = 5;
async function handleMapClick(coords: LngLat): Promise<void> {
function handleMapClick(coords: LngLat): void {
if (clickCoordinates.value.length > 0) {
const last = clickCoordinates.value[clickCoordinates.value.length - 1];
if (
calculateHaversineDistance(coords[0], coords[1], last[0], last[1]) *
1000 <
SNAP_THRESHOLD_M
MIN_DISTANCE_M
) {
return;
}
}
const [snappedLon, snappedLat] = await snapToRoad(coords[0], coords[1]);
clickCoordinates.value = [
...clickCoordinates.value,
[snappedLon, snappedLat],
];
clickCoordinates.value = [...clickCoordinates.value, coords];
}
const toGPX = () => {

View File

@ -1,23 +0,0 @@
/**
* Привязывает точку к ближайшей дороге через 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];
}
}