let ciel = { lat: 49.0780, lon: 19.3100 }; async function reroute(gps) { if (!ciel) { return; } const form = new FormData(); form.append( "lat", gps.lat ); form.append( "lon", gps.lon ); form.append( "destLat", ciel.lat ); form.append( "destLon", ciel.lon ); try { const response = await fetch( "reroute.php", { method: "POST", body: form } ); if (!response.ok) { throw new Error( "Reroute HTTP " + response.status ); } const data = await response.json(); if (!data.route) { console.log( "Nová trasa neexistuje" ); return; } /* * Nahradíme starú trasu. */ mapa.route = data.route; /* * Nový začiatok trasy */ mapa.start = data.start; /* * Reset pozície na route */ mapa.currentRouteIndex = 0; /* * Prekreslenie */ vykresliMapu(); } catch (error) { console.error( "Reroute chyba:", error ); } } function kontrolujTrasu(gps) { if ( !mapa.route || !mapa.route.points ) { return; } const route = mapa.route.points; let minDistance = Infinity; let nearestIndex = 0; for ( let i = 0; i < route.length; i++ ) { const d = vzdialenostGPS( gps.lat, gps.lon, route[i].lat, route[i].lon ); if (d < minDistance) { minDistance = d; nearestIndex = i; } } /* * Zapamätáme si postup */ mapa.currentRouteIndex = nearestIndex; /* * 30 metrov mimo trasy */ if (minDistance > 30) { spustiReroute(gps); } vykresliMapu(); } let reroutePrebieha = false; async function spustiReroute(gps) { if (reroutePrebieha) { return; } reroutePrebieha = true; try { await reroute(gps); } finally { reroutePrebieha = false; } } sledujPolohu(gps => { aktualnaPoloha = gps; kontrolujTrasu(gps); }); let odchylkaStart = null; let reroutePrebieha = false; const MAX_ODCHYLKA = 30; // metre const CAS_ODCHYLKY = 5000; // 5 sekúnd const KRIZOVATKA_RADIUS = 15; // metre function kontrolujReroute(gps) { if ( !mapa.route || !mapa.route.points || mapa.route.points.length < 2 ) { return; } const route = mapa.route.points; let minDistance = Infinity; let nearestIndex = 0; /* * Nájdeme najbližší bod trasy. */ for (let i = 0; i < route.length; i++) { const d = vzdialenostGPS( gps.lat, gps.lon, route[i].lat, route[i].lon ); if (d < minDistance) { minDistance = d; nearestIndex = i; } } /* * ----------------------------------------- * PODMIENKA 1 * ----------------------------------------- * * Sme viac ako 30 m od trasy? */ if (minDistance <= MAX_ODCHYLKA) { /* * Sme späť na trase. */ odchylkaStart = null; mapa.currentRouteIndex = nearestIndex; vykresliMapu(); return; } /* * ----------------------------------------- * PODMIENKA 2 * ----------------------------------------- * * Odchýlka musí trvať 5 sekúnd. */ if (odchylkaStart === null) { odchylkaStart = Date.now(); return; } const casMimoTrasy = Date.now() - odchylkaStart; if (casMimoTrasy < CAS_ODCHYLKY) { return; } /* * ----------------------------------------- * PODMIENKA 3 * ----------------------------------------- * * Nie sme práve pri významnom bode trasy. * * Napríklad križovatka / prudká zmena smeru. */ if ( jePriKrizovatke( gps, route, nearestIndex ) ) { return; } /* * ----------------------------------------- * Všetky podmienky splnené * ----------------------------------------- */ spustiReroute(gps); } function jePriKrizovatke( gps, route, index ) { if (index <= 0) { return true; } if (index >= route.length - 1) { return true; } const bod = route[index]; const vzdialenost = vzdialenostGPS( gps.lat, gps.lon, bod.lat, bod.lon ); if ( vzdialenost <= KRIZOVATKA_RADIUS ) { return true; } /* * Zatiaľ teda považujeme * blízky významný bod trasy * za miesto, kde počkáme. */ return false; } async function spustiReroute(gps) { if (reroutePrebieha) { return; } reroutePrebieha = true; try { await reroute(gps); /* * Po úspešnom reroute * začneme odchýlku sledovať znova. */ odchylkaStart = null; } catch (error) { console.error( "Reroute:", error ); } finally { reroutePrebieha = false; } } sledujPolohu(gps => { aktualnaPoloha = gps; kontrolujReroute(gps); });