Files
webgis_Ikbal/webgis-poverty-pontianak/assets/js/map.js
T
2026-06-11 22:29:16 +07:00

225 lines
8.5 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.
// ============================================================
// WebGIS Kemiskinan Pontianak — map.js (Redesign)
// ============================================================
// Inisialisasi Peta
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);
};
// ===== Zoom Controls =====
document.getElementById('zoomInBtn').addEventListener('click', () => map.zoomIn());
document.getElementById('zoomOutBtn').addEventListener('click', () => map.zoomOut());
// ===== Base Map =====
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
// ===== Feature Groups =====
const rumahIbadahLayer = L.featureGroup().addTo(map);
const pendudukMiskinLayer = L.featureGroup().addTo(map);
const geoJsonLayer = L.featureGroup().addTo(map);
// ===== Sidebar Collapse =====
const collapseBtn = document.getElementById('sidebarCollapseBtn');
const collapseIcon = document.getElementById('collapseIcon');
if (collapseBtn) {
collapseBtn.addEventListener('click', function() {
const collapsed = document.body.classList.toggle('sidebar-collapsed');
if (collapseIcon) collapseIcon.className = collapsed ? 'fas fa-chevron-right' : 'fas fa-chevron-left';
setTimeout(() => map.invalidateSize(), 320);
});
}
// ===== Search =====
const searchInput = document.getElementById('searchInput');
const searchClear = document.getElementById('searchClear');
const searchResultsEl = document.getElementById('searchResults');
searchInput.addEventListener('focus', () => {
if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode();
});
searchInput.addEventListener('input', function() {
const val = this.value.toLowerCase().trim();
if (val.length > 0) {
searchClear.style.visibility = 'visible';
window.showSearchResults(val);
} else {
searchClear.style.visibility = 'hidden';
searchResultsEl.style.display = 'none';
}
});
searchClear.addEventListener('click', function() {
searchInput.value = '';
searchClear.style.visibility = 'hidden';
searchResultsEl.style.display = 'none';
searchInput.focus();
});
document.addEventListener('click', function(e) {
if (!e.target.closest('.search-bar') && !e.target.closest('#searchResults')) {
searchResultsEl.style.display = 'none';
}
});
window.showSearchResults = function(query) {
searchResultsEl.innerHTML = '';
let results = [];
if (typeof rumahIbadahLayer !== 'undefined') {
rumahIbadahLayer.eachLayer(layer => {
if (layer.ibadahData?.nama?.toLowerCase().includes(query) && layer instanceof L.Marker) {
results.push({ type: 'Rumah Ibadah', icon: '🕌', nama: layer.ibadahData.nama, layer });
}
});
}
if (results.length === 0) {
searchResultsEl.innerHTML = '<div class="search-result-item" style="color:#94a3b8;">Tidak ada hasil ditemukan</div>';
} else {
results.forEach(res => {
const item = document.createElement('div');
item.className = 'search-result-item';
item.innerHTML = `<span>${res.icon}</span><span><strong style="font-size:10px; color:#94a3b8; text-transform:uppercase;">${res.type}</strong><br>${res.nama}</span>`;
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();
searchResultsEl.style.display = 'none';
searchInput.value = res.nama;
searchClear.style.visibility = 'visible';
});
searchResultsEl.appendChild(item);
});
}
searchResultsEl.style.display = 'block';
};
// ===== Layer Panel Toggle =====
const layerBtn = document.getElementById('layerBtn');
const layerPanel = document.getElementById('layerPanel');
layerBtn.addEventListener('click', function() {
if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode();
const isOpen = layerPanel.classList.toggle('show');
layerBtn.classList.toggle('active', isOpen);
});
map.on('click', function() {
layerPanel.classList.remove('show');
layerBtn.classList.remove('active');
});
// ===== 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);
});
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);
};
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;
const el = layer.getElement?.();
if (el) el.style.display = checked.includes(layer.miskinData.kategori_bantuan) ? '' : 'none';
});
}
};
// ===== Modal Logic =====
const unifiedModal = document.getElementById('unifiedModal');
window.openModal = function(title, bodyHTML, saveCallback) {
document.getElementById('modalTitle').textContent = title;
document.getElementById('modalBody').innerHTML = bodyHTML;
unifiedModal.classList.add('show');
const oldBtn = document.getElementById('modalSaveBtn');
const newBtn = oldBtn.cloneNode(true);
oldBtn.parentNode.replaceChild(newBtn, oldBtn);
newBtn.addEventListener('click', saveCallback);
};
window.closeModal = function() { unifiedModal.classList.remove('show'); };
const confirmModal = document.getElementById('confirmModal');
window.openConfirmModal = function(msg, confirmCallback) {
document.getElementById('confirmMessage').textContent = msg;
confirmModal.classList.add('show');
const oldBtn = document.getElementById('confirmYesBtn');
const newBtn = oldBtn.cloneNode(true);
oldBtn.parentNode.replaceChild(newBtn, oldBtn);
newBtn.addEventListener('click', function() {
confirmModal.classList.remove('show');
confirmCallback();
});
};
window.closeConfirmModal = function() { confirmModal.classList.remove('show'); };
// ===== Add Mode =====
window.currentAddMode = null;
window.activateAddMode = function(mode) {
if (window.currentAddMode === mode) { window.deactivateAddMode(); return; }
window.currentAddMode = mode;
const tooltips = { 'rumah_ibadah': 'Klik peta untuk tambah Rumah Ibadah' };
if (window.cursorTooltip && tooltips[mode]) window.cursorTooltip.textContent = tooltips[mode];
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';
};
// ===== Cursor Tooltip =====
window.cursorTooltip = document.createElement('div');
window.cursorTooltip.className = 'custom-cursor-tooltip';
document.body.appendChild(window.cursorTooltip);
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';
}
});