feat: add GeoJSON import for SPBU mode
This commit is contained in:
@@ -15,6 +15,7 @@ let mode = null; // 'ibadah' | 'miskin' | null
|
|||||||
let editMode = null; // { type:'ibadah'|'miskin', id } — saat edit
|
let editMode = null; // { type:'ibadah'|'miskin', id } — saat edit
|
||||||
let ibadahList = [];
|
let ibadahList = [];
|
||||||
let miskinList = [];
|
let miskinList = [];
|
||||||
|
let importedGeoJSON = [];
|
||||||
let myMarker = null;
|
let myMarker = null;
|
||||||
let pendingLatLng = null;
|
let pendingLatLng = null;
|
||||||
let pendingAddr = null;
|
let pendingAddr = null;
|
||||||
@@ -589,14 +590,15 @@ window.removeMiskin = (id) => {
|
|||||||
document.getElementById('btn-reset').addEventListener('click', () => {
|
document.getElementById('btn-reset').addEventListener('click', () => {
|
||||||
ibadahList.forEach(ib => { map.removeLayer(ib.marker); map.removeLayer(ib.circle); });
|
ibadahList.forEach(ib => { map.removeLayer(ib.marker); map.removeLayer(ib.circle); });
|
||||||
miskinList.forEach(m => { map.removeLayer(m.marker); if (m.circle) map.removeLayer(m.circle); });
|
miskinList.forEach(m => { map.removeLayer(m.marker); if (m.circle) map.removeLayer(m.circle); });
|
||||||
|
importedGeoJSON.forEach(g => { map.removeLayer(g.layer); });
|
||||||
if (myMarker) { map.removeLayer(myMarker); myMarker = null; }
|
if (myMarker) { map.removeLayer(myMarker); myMarker = null; }
|
||||||
if (tempMarker) { map.removeLayer(tempMarker); tempMarker = null; }
|
if (tempMarker) { map.removeLayer(tempMarker); tempMarker = null; }
|
||||||
ibadahList = []; miskinList = [];
|
ibadahList = []; miskinList = []; importedGeoJSON = [];
|
||||||
mode = null; editMode = null; updateToolbar(); resetMapCursor();
|
mode = null; editMode = null; updateToolbar(); resetMapCursor();
|
||||||
document.getElementById('form-overlay').classList.add('hidden');
|
document.getElementById('form-overlay').classList.add('hidden');
|
||||||
document.getElementById('my-location-info').style.display = 'none';
|
document.getElementById('my-location-info').style.display = 'none';
|
||||||
document.getElementById('loc-bar').style.display = 'none';
|
document.getElementById('loc-bar').style.display = 'none';
|
||||||
renderIbadahList(); renderMiskinList(); updateStats();
|
renderIbadahList(); renderMiskinList(); if(typeof renderGeoJSONList === 'function') renderGeoJSONList(); updateStats();
|
||||||
showToast('🗑️ Semua data dihapus', '#ef4444');
|
showToast('🗑️ Semua data dihapus', '#ef4444');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -644,4 +646,97 @@ document.addEventListener('keydown', e => {
|
|||||||
mode = null; updateToolbar(); resetMapCursor(); clearHighlights();
|
mode = null; updateToolbar(); resetMapCursor(); clearHighlights();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// GEOJSON IMPORT
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
const fImportGeoJSON = document.getElementById('f-import-geojson');
|
||||||
|
if (fImportGeoJSON) {
|
||||||
|
fImportGeoJSON.addEventListener('change', function(e) {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function(evt) {
|
||||||
|
try {
|
||||||
|
const geojsonData = JSON.parse(evt.target.result);
|
||||||
|
|
||||||
|
// Buat layer GeoJSON
|
||||||
|
const layer = L.geoJSON(geojsonData, {
|
||||||
|
style: function(feature) {
|
||||||
|
return {
|
||||||
|
color: '#f59e0b',
|
||||||
|
weight: 3,
|
||||||
|
opacity: 0.8,
|
||||||
|
fillColor: '#f59e0b',
|
||||||
|
fillOpacity: 0.2
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onEachFeature: function(feature, layer) {
|
||||||
|
let popupContent = '<b>GeoJSON Feature</b><br>';
|
||||||
|
if (feature.properties) {
|
||||||
|
for (const key in feature.properties) {
|
||||||
|
popupContent += `<i>${key}</i>: ${feature.properties[key]}<br>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layer.bindPopup(popupContent);
|
||||||
|
}
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
// Zoom ke layer yang baru diimpor
|
||||||
|
map.fitBounds(layer.getBounds());
|
||||||
|
|
||||||
|
const id = Date.now();
|
||||||
|
importedGeoJSON.push({
|
||||||
|
id: id,
|
||||||
|
name: file.name,
|
||||||
|
layer: layer
|
||||||
|
});
|
||||||
|
|
||||||
|
renderGeoJSONList();
|
||||||
|
showToast(`📂 File ${file.name} berhasil diimpor`, '#22c55e');
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
showToast('❌ Gagal memparsing file GeoJSON', '#ef4444');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset input agar file yang sama bisa dipilih lagi
|
||||||
|
fImportGeoJSON.value = '';
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.renderGeoJSONList = function() {
|
||||||
|
const el = document.getElementById('geojson-list');
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
if (!importedGeoJSON.length) {
|
||||||
|
el.innerHTML = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.innerHTML = importedGeoJSON.map(g => `
|
||||||
|
<div class="item-card" style="margin-bottom: 5px;">
|
||||||
|
<div class="item-icon" style="background: rgba(245, 158, 11, 0.2); color: #f59e0b; border: 1px solid rgba(245, 158, 11, 0.3);">🗺️</div>
|
||||||
|
<div class="item-info">
|
||||||
|
<div class="item-name">${truncate(g.name, 25)}</div>
|
||||||
|
<div class="item-addr">GeoJSON Layer</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-actions">
|
||||||
|
<button class="btn-remove" onclick="removeGeoJSON(${g.id})" title="Hapus Layer">✕</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.removeGeoJSON = function(id) {
|
||||||
|
const idx = importedGeoJSON.findIndex(g => g.id === id);
|
||||||
|
if (idx < 0) return;
|
||||||
|
map.removeLayer(importedGeoJSON[idx].layer);
|
||||||
|
importedGeoJSON.splice(idx, 1);
|
||||||
|
renderGeoJSONList();
|
||||||
|
showToast('🗑️ Layer dihapus', '#f59e0b');
|
||||||
|
};
|
||||||
@@ -85,6 +85,12 @@
|
|||||||
<span class="dot" style="background:var(--green)"></span>SPBU & Pangkalan BBM
|
<span class="dot" style="background:var(--green)"></span>SPBU & Pangkalan BBM
|
||||||
<span class="count-badge" id="count-miskin">0</span>
|
<span class="count-badge" id="count-miskin">0</span>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="btn btn-loc" id="btn-import-geojson" style="margin-bottom: 10px; background: rgba(245, 158, 11, 0.1); color: #f59e0b; border: 1px solid rgba(245, 158, 11, 0.3);" onclick="document.getElementById('f-import-geojson').click()">
|
||||||
|
📂 Import GeoJSON (ArcGIS)
|
||||||
|
</button>
|
||||||
|
<input type="file" id="f-import-geojson" accept=".geojson,.json" style="display:none;">
|
||||||
|
<div id="geojson-list" style="margin-bottom: 10px;"></div>
|
||||||
|
|
||||||
<div class="item-list" id="miskin-list">
|
<div class="item-list" id="miskin-list">
|
||||||
<div class="empty-state">Belum ada data SPBU</div>
|
<div class="empty-state">Belum ada data SPBU</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user