let ploughing = false; let ploughingPoints = []; const PLOUGHING_START_DISTANCE = 30; const PLOUGHING_STOP_DISTANCE = 15; function vzdialenostOdCiest(gps) { let minDistance = Infinity; for (const road of mapa.roads) { const nodes = road.nodes; for (let i = 0; i < nodes.length - 1; i++) { const a = nodes[i]; const b = nodes[i + 1]; const d = vzdialenostNaSegment( gps.lon, gps.lat, a.lon, a.lat, b.lon, b.lat ); if (d < minDistance) { minDistance = d; } } } return minDistance; } function vzdialenostNaSegment( lon, lat, lon1, lat1, lon2, lat2 ) { /* * Lokálna aproximácia GPS súradníc * na metre. */ const kx = 111320 * Math.cos( lat * Math.PI / 180 ); const ky = 110540; const px = lon * kx; const py = lat * ky; const ax = lon1 * kx; const ay = lat1 * ky; const bx = lon2 * kx; const by = lat2 * ky; const dx = bx - ax; const dy = by - ay; if (dx === 0 && dy === 0) { return Math.hypot( px - ax, py - ay ); } let t = ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy); t = Math.max( 0, Math.min(1, t) ); const cx = ax + t * dx; const cy = ay + t * dy; return Math.hypot( px - cx, py - cy ); }
Zapni brázdenie
#ploughingButton { position: fixed; right: 20px; bottom: 20px; padding: 14px 20px; background: #222; color: white; border-radius: 10px; font-size: 16px; display: none; cursor: pointer; z-index: 1000; } function zobrazBrázdenieButton() { document.getElementById( "ploughingButton" ).style.display = "block"; } function skryBrázdenieButton() { document.getElementById( "ploughingButton" ).style.display = "none"; } document .getElementById("ploughingButton") .addEventListener("click", () => { ploughing = true; ploughingPoints = []; skryBrázdenieButton(); console.log( "BRÁZDENIE ON" ); }); sledujPolohu(gps => { aktualnaPoloha = gps; kontrolujPloughing(gps); }); function kontrolujPloughing(gps) { const distance = vzdialenostOdCiest(gps); /* * -------------------------------- * BRÁZDENIE AKTÍVNE * -------------------------------- */ if (ploughing) { ploughingPoints.push({ lat: gps.lat, lon: gps.lon, time: Date.now() }); /* * Pri návrate na existujúcu cestu * brázdenie vypneme. */ if ( distance <= PLOUGHING_STOP_DISTANCE ) { ukonciPloughing(); return; } vykresliMapu(); return; } /* * -------------------------------- * BRÁZDENIE NIE JE AKTÍVNE * -------------------------------- */ if ( distance >= PLOUGHING_START_DISTANCE ) { zobrazBrázdenieButton(); } } function vykresliPloughing() { if ( !ploughingPoints || ploughingPoints.length < 2 ) { return; } ctx.beginPath(); for ( let i = 0; i < ploughingPoints.length; i++ ) { const p = gpsToCanvas( ploughingPoints[i].lon, ploughingPoints[i].lat ); if (i === 0) { ctx.moveTo( p.x, p.y ); } else { ctx.lineTo( p.x, p.y ); } } ctx.lineWidth = 5; ctx.strokeStyle = "#8B4513"; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.stroke(); } async function ukonciPloughing() { if (!ploughing) { return; } ploughing = false; const novaCesta = [ ...ploughingPoints ]; ploughingPoints = []; skryBrázdenieButton(); /* * Pošleme novú cestu PHP. */ await ulozNovuCestu(novaCesta); /* * Teraz už pokračujeme * klasickou navigáciou. */ vykresliMapu(); }