307 lines
12 KiB
JavaScript
307 lines
12 KiB
JavaScript
// Inisialisasi Peta
|
|
// Koordinat awal: [-0.0263, 109.3425] (Pontianak)
|
|
const map = L.map('map', { zoomControl: false }).setView([-0.0263, 109.3425], 13);
|
|
|
|
// Custom Zoom Control Logic
|
|
document.getElementById('zoomInBtn').addEventListener('click', function() { map.zoomIn(); });
|
|
document.getElementById('zoomOutBtn').addEventListener('click', function() { map.zoomOut(); });
|
|
|
|
// Base Map dari OpenStreetMap
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
}).addTo(map);
|
|
|
|
// Inisialisasi FeatureGroups untuk masing-masing layer
|
|
const spbuLayer = L.featureGroup().addTo(map);
|
|
const jalanLayer = L.featureGroup().addTo(map);
|
|
const parsilLayer = L.featureGroup().addTo(map);
|
|
const rumahIbadahLayer = L.featureGroup().addTo(map);
|
|
const pendudukMiskinLayer = L.featureGroup().addTo(map);
|
|
const geoJsonLayer = L.featureGroup().addTo(map);
|
|
|
|
const searchInput = document.getElementById('searchInput');
|
|
const searchClear = document.getElementById('searchClear');
|
|
|
|
searchInput.addEventListener('input', function() {
|
|
const val = this.value.toLowerCase();
|
|
if (val.length > 0) {
|
|
searchClear.style.visibility = 'visible';
|
|
window.showSearchResults(val);
|
|
} else {
|
|
searchClear.style.visibility = 'hidden';
|
|
document.getElementById('searchResults').style.display = 'none';
|
|
}
|
|
});
|
|
|
|
searchClear.addEventListener('click', function() {
|
|
searchInput.value = '';
|
|
searchClear.style.visibility = 'hidden';
|
|
document.getElementById('searchResults').style.display = 'none';
|
|
searchInput.focus();
|
|
});
|
|
|
|
window.showSearchResults = function(query) {
|
|
const resultsContainer = document.getElementById('searchResults');
|
|
resultsContainer.innerHTML = '';
|
|
let results = [];
|
|
|
|
if (typeof spbuLayer !== 'undefined') {
|
|
spbuLayer.eachLayer(layer => {
|
|
if (layer.spbuData && layer.spbuData.nama && layer.spbuData.nama.toLowerCase().includes(query)) {
|
|
results.push({ type: 'SPBU', nama: layer.spbuData.nama, layer: layer });
|
|
}
|
|
});
|
|
}
|
|
|
|
if (typeof jalanLayer !== 'undefined') {
|
|
jalanLayer.eachLayer(layer => {
|
|
if (layer.jalanData && layer.jalanData.nama && layer.jalanData.nama.toLowerCase().includes(query)) {
|
|
results.push({ type: 'Jalan', nama: layer.jalanData.nama, layer: layer });
|
|
}
|
|
});
|
|
}
|
|
|
|
if (typeof parsilLayer !== 'undefined') {
|
|
parsilLayer.eachLayer(layer => {
|
|
if (layer.parsilData && layer.parsilData.nama && layer.parsilData.nama.toLowerCase().includes(query)) {
|
|
results.push({ type: 'Parsil', nama: layer.parsilData.nama, layer: layer });
|
|
}
|
|
});
|
|
}
|
|
|
|
if (typeof rumahIbadahLayer !== 'undefined') {
|
|
rumahIbadahLayer.eachLayer(layer => {
|
|
if (layer.ibadahData && layer.ibadahData.nama && layer.ibadahData.nama.toLowerCase().includes(query)) {
|
|
if(layer instanceof L.Marker) {
|
|
results.push({ type: 'Rumah Ibadah', nama: layer.ibadahData.nama, layer: layer });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if (results.length === 0) {
|
|
resultsContainer.innerHTML = '<div style="padding: 10px 15px; color: #666; font-size: 14px;">Tidak ada hasil</div>';
|
|
} else {
|
|
results.forEach(res => {
|
|
const item = document.createElement('div');
|
|
item.style.padding = '10px 15px';
|
|
item.style.cursor = 'pointer';
|
|
item.style.borderBottom = '1px solid #eee';
|
|
item.style.fontSize = '14px';
|
|
item.innerHTML = `<strong>${res.type}:</strong> ${res.nama}`;
|
|
item.addEventListener('mouseenter', () => item.style.backgroundColor = '#f8f9fa');
|
|
item.addEventListener('mouseleave', () => item.style.backgroundColor = 'white');
|
|
item.addEventListener('click', () => {
|
|
if (res.layer instanceof L.Marker) {
|
|
map.setView(res.layer.getLatLng(), 17);
|
|
} else if (res.layer.getBounds) {
|
|
map.fitBounds(res.layer.getBounds());
|
|
}
|
|
res.layer.openPopup();
|
|
resultsContainer.style.display = 'none';
|
|
});
|
|
resultsContainer.appendChild(item);
|
|
});
|
|
}
|
|
resultsContainer.style.display = 'block';
|
|
};
|
|
|
|
// UI Logic: Custom Layer Control Toggle
|
|
const layerBtn = document.getElementById('layerBtn');
|
|
const layerPanel = document.getElementById('layerPanel');
|
|
|
|
layerBtn.addEventListener('click', function() {
|
|
layerPanel.style.display = layerPanel.style.display === 'block' ? 'none' : 'block';
|
|
});
|
|
|
|
// Sembunyikan layer panel saat klik di peta
|
|
map.on('click', function() {
|
|
layerPanel.style.display = 'none';
|
|
});
|
|
|
|
|
|
// Logic untuk Toggle Layer Visibility
|
|
document.getElementById('layerSpbu').addEventListener('change', function(e) {
|
|
e.target.checked ? map.addLayer(spbuLayer) : map.removeLayer(spbuLayer);
|
|
});
|
|
document.getElementById('layerJalan').addEventListener('change', function(e) {
|
|
e.target.checked ? map.addLayer(jalanLayer) : map.removeLayer(jalanLayer);
|
|
});
|
|
document.getElementById('layerParsil').addEventListener('change', function(e) {
|
|
e.target.checked ? map.addLayer(parsilLayer) : map.removeLayer(parsilLayer);
|
|
});
|
|
document.getElementById('layerRumahIbadah').addEventListener('change', function(e) {
|
|
e.target.checked ? map.addLayer(rumahIbadahLayer) : map.removeLayer(rumahIbadahLayer);
|
|
});
|
|
document.getElementById('layerMiskin').addEventListener('change', function(e) {
|
|
e.target.checked ? map.addLayer(pendudukMiskinLayer) : map.removeLayer(pendudukMiskinLayer);
|
|
});
|
|
|
|
// --- Sub-layer Toggle (expand/collapse) ---
|
|
window.toggleSubLayer = function(subId, iconEl) {
|
|
const sub = document.getElementById(subId);
|
|
if (!sub) return;
|
|
const isHidden = sub.style.display === 'none';
|
|
sub.style.display = isHidden ? '' : 'none';
|
|
iconEl.classList.toggle('collapsed', !isHidden);
|
|
};
|
|
|
|
// --- Sub-layer Filter ---
|
|
window.applySubFilter = function(type) {
|
|
if (type === 'spbu') {
|
|
const checked = [...document.querySelectorAll('.sub-spbu:checked')].map(el => el.value);
|
|
spbuLayer.eachLayer(layer => {
|
|
if (!layer.spbuData) return;
|
|
const val = layer.spbuData.is_24_jam ? '1' : '0';
|
|
if (checked.includes(val)) {
|
|
if (!spbuLayer.hasLayer(layer)) spbuLayer.addLayer(layer);
|
|
layer.getElement && layer.getElement() && (layer.getElement().style.display = '');
|
|
} else {
|
|
layer.getElement && layer.getElement() && (layer.getElement().style.display = 'none');
|
|
}
|
|
});
|
|
}
|
|
|
|
if (type === 'jalan') {
|
|
const checked = [...document.querySelectorAll('.sub-jalan:checked')].map(el => el.value);
|
|
jalanLayer.eachLayer(layer => {
|
|
if (!layer.jalanData) return;
|
|
const visible = checked.includes(layer.jalanData.status);
|
|
const display = visible ? '' : 'none';
|
|
// Sembunyikan garis polyline
|
|
if (layer._path) layer._path.style.display = display;
|
|
// Sembunyikan label teks (leaflet-textpath simpan di _textNode)
|
|
if (layer._textNode) layer._textNode.style.display = display;
|
|
});
|
|
}
|
|
|
|
if (type === 'parsil') {
|
|
const checked = [...document.querySelectorAll('.sub-parsil:checked')].map(el => el.value);
|
|
parsilLayer.eachLayer(layer => {
|
|
if (!layer.parsilData) return;
|
|
if (checked.includes(layer.parsilData.status)) {
|
|
layer._path && (layer._path.style.display = '');
|
|
} else {
|
|
layer._path && (layer._path.style.display = 'none');
|
|
}
|
|
});
|
|
}
|
|
|
|
if (type === 'miskin') {
|
|
const checked = [...document.querySelectorAll('.sub-miskin:checked')].map(el => el.value);
|
|
pendudukMiskinLayer.eachLayer(layer => {
|
|
if (!layer.miskinData) return;
|
|
if (checked.includes(layer.miskinData.kategori_bantuan)) {
|
|
layer.getElement && layer.getElement() && (layer.getElement().style.display = '');
|
|
} else {
|
|
layer.getElement && layer.getElement() && (layer.getElement().style.display = 'none');
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// --- Modal Logic ---
|
|
const unifiedModal = document.getElementById('unifiedModal');
|
|
const modalTitle = document.getElementById('modalTitle');
|
|
const modalBody = document.getElementById('modalBody');
|
|
|
|
window.openModal = function(title, bodyHTML, saveCallback) {
|
|
modalTitle.textContent = title;
|
|
modalBody.innerHTML = bodyHTML;
|
|
unifiedModal.classList.add('show');
|
|
|
|
// Ambil elemen tombol save terbaru dari DOM
|
|
const currentSaveBtn = document.getElementById('modalSaveBtn');
|
|
|
|
// Clone untuk menghapus semua event listener lama
|
|
const newSaveBtn = currentSaveBtn.cloneNode(true);
|
|
currentSaveBtn.parentNode.replaceChild(newSaveBtn, currentSaveBtn);
|
|
|
|
newSaveBtn.addEventListener('click', saveCallback);
|
|
};
|
|
|
|
window.closeModal = function() {
|
|
unifiedModal.classList.remove('show');
|
|
};
|
|
|
|
const confirmModal = document.getElementById('confirmModal');
|
|
const confirmMessage = document.getElementById('confirmMessage');
|
|
|
|
window.openConfirmModal = function(msg, confirmCallback) {
|
|
confirmMessage.textContent = msg;
|
|
confirmModal.classList.add('show');
|
|
|
|
const currentYesBtn = document.getElementById('confirmYesBtn');
|
|
const newYesBtn = currentYesBtn.cloneNode(true);
|
|
currentYesBtn.parentNode.replaceChild(newYesBtn, currentYesBtn);
|
|
|
|
newYesBtn.addEventListener('click', function() {
|
|
confirmModal.classList.remove('show');
|
|
confirmCallback();
|
|
});
|
|
};
|
|
|
|
window.closeConfirmModal = function() {
|
|
confirmModal.classList.remove('show');
|
|
};
|
|
|
|
// --- Action Menu Logic (replaced by left sidebar) ---
|
|
|
|
window.currentAddMode = null; // 'spbu' atau 'rumah_ibadah'
|
|
window.currentDrawMode = null; // 'polyline' atau 'polygon'
|
|
|
|
window.activateAddMode = function(mode) {
|
|
// Toggle: jika mode yang sama diklik lagi, batalkan
|
|
if (window.currentAddMode === mode) {
|
|
window.deactivateAddMode();
|
|
return;
|
|
}
|
|
|
|
// Reset draw mode if active
|
|
if (window.activeDrawHandler) {
|
|
window.activeDrawHandler.disable();
|
|
window.activeDrawHandler = null;
|
|
}
|
|
|
|
window.currentAddMode = mode;
|
|
window.currentDrawMode = null;
|
|
|
|
// Tooltip
|
|
const tooltips = {
|
|
'spbu': 'Klik untuk Tambah SPBU',
|
|
'rumah_ibadah': 'Klik untuk Tambah Rumah Ibadah'
|
|
};
|
|
if (window.cursorTooltip && tooltips[mode]) window.cursorTooltip.textContent = tooltips[mode];
|
|
|
|
// Ubah kursor map menjadi crosshair
|
|
document.getElementById('map').style.cursor = 'crosshair';
|
|
};
|
|
|
|
window.deactivateAddMode = function() {
|
|
window.currentAddMode = null;
|
|
window.currentDrawMode = null;
|
|
if (window.activeDrawHandler) {
|
|
window.activeDrawHandler.disable();
|
|
window.activeDrawHandler = null;
|
|
}
|
|
document.getElementById('map').style.cursor = '';
|
|
if (window.cursorTooltip) window.cursorTooltip.style.display = 'none';
|
|
};
|
|
|
|
// --- Custom Tooltip Cursor ---
|
|
window.cursorTooltip = document.createElement('div');
|
|
window.cursorTooltip.className = 'custom-cursor-tooltip';
|
|
document.body.appendChild(window.cursorTooltip);
|
|
|
|
// Gunakan document-level mousemove agar selalu terpicu
|
|
// bahkan saat Leaflet Draw overlay aktif menangkap event map
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (window.currentAddMode || window.currentDrawMode) {
|
|
window.cursorTooltip.style.display = 'block';
|
|
window.cursorTooltip.style.left = e.pageX + 15 + 'px';
|
|
window.cursorTooltip.style.top = e.pageY + 15 + 'px';
|
|
} else {
|
|
window.cursorTooltip.style.display = 'none';
|
|
}
|
|
});
|