initialize
This commit is contained in:
+181
@@ -0,0 +1,181 @@
|
||||
// --- Fitur Import GeoJSON ---
|
||||
|
||||
const fileGeoJson = document.getElementById('fileGeoJson');
|
||||
let geoJsonLayers = {};
|
||||
let geoJsonCounter = 0;
|
||||
|
||||
window.toggleGeoJsonMenu = function() {
|
||||
const list = document.getElementById('geoJsonFileList');
|
||||
const icon = document.getElementById('geoJsonToggleIcon');
|
||||
if (list.style.display === 'none') {
|
||||
list.style.display = 'block';
|
||||
icon.className = 'fas fa-minus';
|
||||
} else {
|
||||
list.style.display = 'none';
|
||||
icon.className = 'fas fa-plus';
|
||||
}
|
||||
};
|
||||
|
||||
// Cek apakah fitur GeoJSON ini terlihat seperti data penduduk miskin
|
||||
function isMiskinFeature(feature) {
|
||||
if (!feature || !feature.geometry || feature.geometry.type !== 'Point') return false;
|
||||
const props = feature.properties || {};
|
||||
const keys = Object.keys(props).map(k => k.toLowerCase());
|
||||
// Dianggap data miskin jika punya properti nama (dan bukan ibadah atau spbu)
|
||||
const hasNama = keys.some(k => ['nama', 'name', 'penduduk'].includes(k));
|
||||
const isIbadah = keys.some(k => ['jenis', 'radius', 'alamat'].includes(k));
|
||||
const isSpbu = keys.some(k => ['alamat_spbu', 'is_24_jam'].includes(k));
|
||||
return hasNama && !isIbadah && !isSpbu;
|
||||
}
|
||||
|
||||
fileGeoJson.addEventListener('change', function(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
try {
|
||||
const geoJsonData = JSON.parse(event.target.result);
|
||||
const fileName = file.name;
|
||||
|
||||
// Pisahkan fitur menjadi dua kelompok: miskin dan non-miskin
|
||||
const features = geoJsonData.type === 'FeatureCollection'
|
||||
? geoJsonData.features
|
||||
: [geoJsonData];
|
||||
|
||||
const miskinFeatures = features.filter(f => isMiskinFeature(f));
|
||||
const otherFeatures = features.filter(f => !isMiskinFeature(f));
|
||||
|
||||
// ---- Proses fitur miskin: Simpan ke DB, lalu tampilkan seperti penduduk miskin ----
|
||||
if (miskinFeatures.length > 0) {
|
||||
const bulkData = miskinFeatures.map(f => {
|
||||
const props = f.properties || {};
|
||||
const coords = f.geometry.coordinates;
|
||||
return {
|
||||
nama: props.nama || props.name || props.penduduk || 'Data Impor',
|
||||
kategori_bantuan: props.kategori_bantuan || props.kategori || props.bantuan || 'Makan',
|
||||
jumlah_jiwa: parseInt(props.jumlah_jiwa || props.jumlah || props.jiwa || 1, 10) || 1,
|
||||
lat: parseFloat(coords[1]),
|
||||
lng: parseFloat(coords[0])
|
||||
};
|
||||
});
|
||||
|
||||
fetch('api/penduduk_miskin/bulk_create.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(bulkData)
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
// Reload layer penduduk miskin agar marker tampil dengan edit/hapus/log bantuan
|
||||
if (typeof loadPendudukMiskin === 'function') {
|
||||
loadPendudukMiskin();
|
||||
}
|
||||
if (typeof window.refreshActivePanel === 'function') {
|
||||
window.refreshActivePanel();
|
||||
}
|
||||
showToast(data.message || 'Data berhasil diimpor ke layer Penduduk Miskin.', 'success');
|
||||
} else {
|
||||
showToast(data.message || 'Gagal menyimpan data miskin.', 'error');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
showToast('Gagal terhubung ke server saat menyimpan data miskin.', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Proses fitur non-miskin: Render sebagai layer GeoJSON biasa ----
|
||||
if (otherFeatures.length > 0) {
|
||||
const layerId = 'gj_' + (++geoJsonCounter);
|
||||
const individualLayer = L.featureGroup();
|
||||
|
||||
const otherGeoJson = {
|
||||
type: 'FeatureCollection',
|
||||
features: otherFeatures
|
||||
};
|
||||
|
||||
L.geoJSON(otherGeoJson, {
|
||||
pointToLayer: function(feature, latlng) {
|
||||
const props = feature.properties || {};
|
||||
let emoji = props.emoji;
|
||||
|
||||
if (!emoji) {
|
||||
const text = JSON.stringify(props).toLowerCase();
|
||||
if (text.includes('spbu')) emoji = '⛽';
|
||||
else if (text.includes('masjid')) emoji = '🕌';
|
||||
else if (text.includes('gereja')) emoji = '⛪';
|
||||
else if (text.includes('vihara')) emoji = '🪷';
|
||||
else if (text.includes('pura')) emoji = '🛕';
|
||||
else if (text.includes('kelenteng')) emoji = '🏮';
|
||||
else emoji = '📍';
|
||||
}
|
||||
|
||||
let cls = 'miskin-out';
|
||||
if (emoji === '⛽') cls = 'spbu-24';
|
||||
else if (['🕌','⛪','🛕','🪷','🏮'].includes(emoji)) cls = 'ibadah';
|
||||
|
||||
const icon = L.divIcon({
|
||||
className: '',
|
||||
html: `<div class="emoji-marker"><div class="bubble ${cls}"><span>${emoji}</span></div></div>`,
|
||||
iconSize: [38, 38],
|
||||
iconAnchor: [19, 38],
|
||||
popupAnchor: [0, -40]
|
||||
});
|
||||
|
||||
return L.marker(latlng, { icon: icon });
|
||||
},
|
||||
onEachFeature: function(feature, layer) {
|
||||
if (feature.properties) {
|
||||
let popupContent = '<h4>Informasi Feature</h4><ul style="list-style:none; padding:0; font-size:12px; margin: 0;">';
|
||||
for (let key in feature.properties) {
|
||||
popupContent += `<li><strong>${key}:</strong> ${feature.properties[key]}</li>`;
|
||||
}
|
||||
popupContent += '</ul>';
|
||||
layer.bindPopup(popupContent);
|
||||
}
|
||||
},
|
||||
style: function(feature) {
|
||||
return {
|
||||
color: (feature.properties && feature.properties.color) || '#3388ff',
|
||||
weight: 2,
|
||||
fillOpacity: 0.4
|
||||
};
|
||||
}
|
||||
}).addTo(individualLayer);
|
||||
|
||||
individualLayer.addTo(map);
|
||||
geoJsonLayers[layerId] = individualLayer;
|
||||
|
||||
// Tambahkan checkbox ke UI
|
||||
const container = document.getElementById('geoJsonLayersContainer');
|
||||
const label = document.createElement('label');
|
||||
label.className = 'layer-option';
|
||||
label.innerHTML = `<input type="checkbox" id="chk_${layerId}" checked> ${fileName}`;
|
||||
|
||||
label.querySelector('input').addEventListener('change', function(e) {
|
||||
if (e.target.checked) {
|
||||
map.addLayer(geoJsonLayers[layerId]);
|
||||
} else {
|
||||
map.removeLayer(geoJsonLayers[layerId]);
|
||||
}
|
||||
});
|
||||
|
||||
container.appendChild(label);
|
||||
|
||||
if (miskinFeatures.length === 0) {
|
||||
showToast('File GeoJSON berhasil dimuat!', 'success');
|
||||
}
|
||||
}
|
||||
|
||||
// Reset input file agar bisa import file yang sama
|
||||
fileGeoJson.value = '';
|
||||
|
||||
} catch (error) {
|
||||
showToast('Gagal memproses file GeoJSON. Pastikan format valid.', 'error');
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
});
|
||||
Reference in New Issue
Block a user