Files
2026-08-20 18:39:37 +07:00

180 lines
5.9 KiB
JavaScript

/**
* MAPS TOPOLOGI - MAPLIBRE VERSION
* Menampilkan marker dinamis dengan icon custom
*/
let map;
const markers = []; // Array untuk menyimpan instance marker
var currentStyle = 'hybrid';
// --- DEFINISI STYLE GOOGLE MAPS ---
const googleHybridStyle = {
'version': 8,
'sources': {
'google-hybrid': {
'type': 'raster',
'tiles': ['https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}'],
'tileSize': 256,
'attribution': '© Google Maps'
}
},
'layers': [{
'id': 'google-hybrid-layer',
'type': 'raster',
'source': 'google-hybrid',
'minzoom': 0,
'maxzoom': 22
}]
};
const googleStreetStyle = {
'version': 8,
'sources': {
'google-street': {
'type': 'raster',
'tiles': ['https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}'],
'tileSize': 256,
'attribution': '© Google Maps'
}
},
'layers': [{
'id': 'google-street-layer',
'type': 'raster',
'source': 'google-street',
'minzoom': 0,
'maxzoom': 22
}]
};
function initMap(center) {
// Init MapLibre
map = new maplibregl.Map({
container: 'map',
style: googleHybridStyle, // Default Hybrid
center: [center.lng, center.lat], // [Lng, Lat]
zoom: 10,
attributionControl: true,
dragRotate: false,
pitchWithRotate: false,
touchPitch: false
});
map.touchZoomRotate.disableRotation();
map.addControl(new maplibregl.NavigationControl({ showCompass: false, showZoom: true }), 'top-right');
map.addControl(new maplibregl.FullscreenControl(), 'top-left');
// Tambahkan tombol ganti layer
addLayerSwitcher();
// Tunggu map load sebelum ambil data marker
map.on('load', function() {
fetchMarkers();
// Refresh marker tiap 30 detik
setInterval(fetchMarkers, 30000);
});
}
function addLayerSwitcher() {
class LayerSwitchControl {
onAdd(map) {
this._map = map;
this._container = document.createElement('div');
this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group';
const btn = document.createElement('button');
btn.innerHTML = '🗺️'; // Icon peta
btn.title = "Ganti Tampilan (Satelit/Jalan)";
btn.type = "button";
btn.onclick = () => {
// Logic ganti style
if (currentStyle === 'hybrid') {
map.setStyle(googleStreetStyle);
currentStyle = 'street';
// Kita perlu fetch ulang marker karena ganti style me-reset canvas DOM di beberapa versi
setTimeout(fetchMarkers, 500);
} else {
map.setStyle(googleHybridStyle);
currentStyle = 'hybrid';
setTimeout(fetchMarkers, 500);
}
};
this._container.appendChild(btn);
return this._container;
}
onRemove() {
this._container.parentNode.removeChild(this._container);
this._map = undefined;
}
}
map.addControl(new LayerSwitchControl(), 'top-right');
}
function fetchMarkers() {
// topologiId diambil dari variabel global di halaman PHP
fetch(`load/maps_marker.php?i=${topologiId}`)
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.then(res => {
if (!res.status) {
console.warn("⚠️ Tidak ada data marker");
return;
}
// 1. Hapus marker lama dari peta
markers.forEach(marker => marker.remove());
markers.length = 0; // Kosongkan array
// 2. Tambahkan marker baru
res.data.forEach(markerData => {
// Buat elemen HTML Custom untuk Icon
const el = document.createElement('div');
el.className = 'custom-marker';
// Masukkan gambar icon dari API
const img = document.createElement('img');
img.src = markerData.icon; // URL icon dari database
img.style.width = '30px';
img.style.height = '30px';
img.style.display = 'block';
// Opsional: tambahkan style cursor
el.style.cursor = 'pointer';
el.appendChild(img);
// Buat Marker MapLibre
const markerInstance = new maplibregl.Marker({
element: el,
// anchor bottom agar ujung bawah icon menunjuk ke lokasi persis
anchor: 'bottom'
})
.setLngLat([markerData.lng, markerData.lat]) // [Lng, Lat]
.setPopup(new maplibregl.Popup({ offset: 25 }).setHTML(markerData.content)) // Popup
.addTo(map);
markers.push(markerInstance);
});
console.log(`✅ Marker berhasil ditampilkan: ${markers.length}`);
})
.catch(error => console.error('❌ Error fetching markers:', error));
}
// Entry Point: Ambil center dari API, lalu init map
window.onload = function() {
fetch(`load/maps_marker.php?i=${topologiId}`)
.then(res => res.json())
.then(res => {
if (res.status && res.centerlonglat) {
console.log("📍 Init map pakai centerlonglat:", res.centerlonglat);
initMap(res.centerlonglat);
} else {
console.warn("⚠️ Centerlonglat tidak ada, pakai fallback Jakarta");
initMap({ lat: -6.2, lng: 106.816666 });
}
})
.catch(err => {
console.error("❌ Gagal ambil data awal:", err);
initMap({ lat: -6.2, lng: 106.816666 }); // fallback
});
};