Rute Jalan Asli & Animasi Peta
Penggabungan geometri jalan raya dari OpenStreetMap Routing Machine (OSRM) dengan animasi pergerakan berbasis requestAnimationFrame.
Membaca sekitar 2 menit
Penggabungan geometri jalan raya dari OpenStreetMap Routing Machine (OSRM) dengan animasi pergerakan berbasis requestAnimationFrame.
Mengambil poligon jalan untuk setiap hari perjalanan, menyambungkannya dengan garis konektor antar-hari, dan menggerakkan penanda berotasi mengikuti lekukan jalan.
Menghubungkan titik koordinat dengan garis lurus terlihat kaku; menanyakan jalur ke OSRM per segmen hari membuat visualisasi terasa seperti navigasi sungguhan.
Masalahnya dulu
Menampilkan titik-titik wisata di atas peta lalu menghubungkannya dengan garis lurus (straight polyline) sering kali menipu mata: garis bisa menembus gunung, sungai, atau bangunan. Selain itu, melihat daftar jadwal dari Hari 1 sampai Hari N dalam bentuk teks saja terkadang sulit membayangkan alur pergerakan geografisnya dari pagi hingga malam.
Mengambil geometri jalan OSRM dan menganimasikan pointer
Pada halaman hasil itinerary, setiap kelompok koordinat per hari dikirim ke endpoint publik OSRM (router.project-osrm.org) dengan opsi overview=full&geometries=geojson. Hasilnya adalah ratusan titik koordinat rapat yang mengikuti lekukan jalan raya Yogyakarta. Seluruh segmen jalan harian beserta konektor antar-hari kemudian digabungkan ke dalam array fullRouteCoords untuk dijalani oleh penanda (marker) animasi menggunakan requestAnimationFrame.
Peta yang baik tidak sekadar menaruh pin lokasi, tetapi menceritakan bagaimana perjalanan mengalir dari satu titik ke titik berikutnya di atas jalan yang sebenarnya.
Implementasi di ngodingan ini
Cuplikan kode JavaScript di trip-planner-result.blade.php berikut menunjukkan pengambilan rute jalan dari OSRM serta perhitungan sudut rotasi kendaraan/pointer saat animasi berjalan:
async function fetchRoadRoute(coords) {
if (coords.length < 2) return coords.map(c => [c[0], c[1]]);
try {
const coordStr = coords.map(c => `${c[1]},${c[0]}`).join(';');
const url = `https://router.project-osrm.org/route/v1/driving/${coordStr}?overview=full&geometries=geojson`;
const res = await fetch(url);
const data = await res.json();
if (data.code === 'Ok' && data.routes[0]) {
return data.routes[0].geometry.coordinates.map(c => [c[1], c[0]]);
}
} catch (e) {
console.warn('OSRM error, pakai garis lurus:', e);
}
return coords;
}
function getAngle(from, to) {
const dy = to[0] - from[0];
const dx = to[1] - from[1];
return Math.atan2(dx, dy) * 180 / Math.PI;
}Jebakan dan detail yang harus dijaga
- Format urutan koordinat antara Leaflet dan standar GeoJSON/OSRM berkebalikan: Leaflet menggunakan [lat, lng], sedangkan OSRM meminta lng,lat di URL dan mengembalikan [lng, lat]. Pembalikan indeks wajib dilakukan saat mengirim dan menerima data.
- Saat menyambung segmen rute Hari 1 ke konektor menuju Hari 2, titik akhir segmen pertama sama persis dengan titik awal segmen kedua. Penggunaan seg.slice(1) mencegah duplikasi koordinat yang bisa membuat animasi pointer tersendat di titik sambungan.