Files
webgis-poverty-pontianak/assets/js/map.js
T

243 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Inisialisasi Peta
// Koordinat awal: [-0.0263, 109.3425] (Pontianak)
const map = L.map('map', { zoomControl: false }).setView([-0.0263, 109.3425], 13);
// ===== Toast Notification =====
window.showToast = function(message, type = 'success', duration = 3500) {
const icons = { success: '✅', error: '❌', info: '️', warning: '⚠️' };
const container = document.getElementById('toastContainer');
if (!container) return;
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
toast.innerHTML = `<span class="toast-icon">${icons[type] || '️'}</span><span>${message}</span>`;
container.appendChild(toast);
setTimeout(() => {
toast.classList.add('hiding');
toast.addEventListener('animationend', () => toast.remove());
}, duration);
};
// 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: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Inisialisasi FeatureGroups untuk masing-masing layer
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('focus', function() {
if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode();
});
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 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() {
if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode();
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('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 === '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; // 'rumah_ibadah' atau 'miskin_click'
window.activateAddMode = function(mode) {
// Toggle: jika mode yang sama diklik lagi, batalkan
if (window.currentAddMode === mode) {
window.deactivateAddMode();
return;
}
window.currentAddMode = mode;
// Tooltip
const tooltips = {
'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;
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.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';
}
});