Fix login JSON errors and WebGIS02 rendering

This commit is contained in:
2026-06-11 16:10:45 +07:00
parent b3cacf6432
commit ad5a82ca36
4 changed files with 92 additions and 33 deletions
+44 -24
View File
@@ -316,6 +316,17 @@ const layerJalan = L.layerGroup().addTo(map);
const layerParsil = L.layerGroup().addTo(map);
const layerRusak = L.layerGroup().addTo(map);
function parseGeojsonSafe(raw){
try{
const gj = typeof raw === 'string' ? JSON.parse(raw) : raw;
if(!gj || !gj.geometry || !gj.geometry.type) return null;
return gj;
}catch(e){
console.warn('GeoJSON tidak valid:', raw);
return null;
}
}
// =============================================================
// 2. WARNA & IKON
// =============================================================
@@ -688,16 +699,19 @@ async function loadJalan(q=''){
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-road"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan')+'</p></div>'; return; }
list.innerHTML='';
data.forEach(item=>{
const gj = JSON.parse(item.geojson);
const gj = parseGeojsonSafe(item.geojson);
const style = WARNA_JALAN[item.status_jalan]||WARNA_JALAN['Kabupaten'];
const layer = L.geoJSON(gj,{style}).addTo(layerJalan);
layer.bindPopup(`
<div class="popup-title">${item.nama_jalan}</div>
<div class="popup-row">Status: <span>${item.status_jalan}</span></div>
<div class="popup-row">Panjang: <span>${parseFloat(item.panjang_meter).toFixed(2)} m</span></div>
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
`);
let layer = null;
if(gj){
layer = L.geoJSON(gj,{style}).addTo(layerJalan);
layer.bindPopup(`
<div class="popup-title">${item.nama_jalan}</div>
<div class="popup-row">Status: <span>${item.status_jalan}</span></div>
<div class="popup-row">Panjang: <span>${parseFloat(item.panjang_meter).toFixed(2)} m</span></div>
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
`);
}
const card = document.createElement('div');
card.className='data-card';
card.innerHTML=`
@@ -708,12 +722,12 @@ async function loadJalan(q=''){
<div class="card-meta"><span><i class="fas fa-ruler"></i>${parseFloat(item.panjang_meter).toFixed(0)} m</span></div>
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
<div class="card-actions">
<button class="btn-sm btn-zoom" onclick="zoomJalan${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomJalan${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-edit" onclick="editJalan(${item.id})"><i class="fas fa-edit"></i> Edit</button>
<button class="btn-sm btn-hapus" onclick="hapusJalan(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
</div>`;
list.appendChild(card);
window[`zoomJalan${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
if(layer) window[`zoomJalan${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
});
}
@@ -739,17 +753,20 @@ async function loadParsil(q=''){
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-map"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data parsil')+'</p></div>'; return; }
list.innerHTML='';
data.forEach(item=>{
const gj = JSON.parse(item.geojson);
const gj = parseGeojsonSafe(item.geojson);
const style = WARNA_PARSIL[item.status_kepemilikan]||WARNA_PARSIL['SHM'];
const layer = L.geoJSON(gj,{style}).addTo(layerParsil);
layer.bindPopup(`
let layer = null;
if(gj){
layer = L.geoJSON(gj,{style}).addTo(layerParsil);
layer.bindPopup(`
<div class="popup-title">${item.nama_pemilik}</div>
<div class="popup-row">No. Sertifikat: <span>${item.no_sertifikat}</span></div>
<div class="popup-row">Status: <span>${item.status_kepemilikan}</span></div>
<div class="popup-row">Luas: <span>${parseFloat(item.luas_m2).toFixed(2)} m²</span></div>
${item.alamat?`<div class="popup-row">Alamat: <span>${item.alamat}</span></div>`:''}
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
`);
`);
}
const card = document.createElement('div');
card.className='data-card';
card.innerHTML=`
@@ -763,12 +780,12 @@ async function loadParsil(q=''){
</div>
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
<div class="card-actions">
<button class="btn-sm btn-zoom" onclick="zoomParsil${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomParsil${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-edit" onclick="editParsil(${item.id})"><i class="fas fa-edit"></i> Edit</button>
<button class="btn-sm btn-hapus" onclick="hapusParsil(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
</div>`;
list.appendChild(card);
window[`zoomParsil${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
if(layer) window[`zoomParsil${item.id}`]=()=>map.fitBounds(layer.getBounds(),{padding:[50,50]});
});
}
@@ -794,18 +811,21 @@ async function loadRusak(q=''){
if(!data.length){ list.innerHTML='<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan rusak')+'</p></div>'; return; }
list.innerHTML='';
data.forEach(item=>{
const gj = JSON.parse(item.geojson);
const gj = parseGeojsonSafe(item.geojson);
const cfg = WARNA_RUSAK[item.tingkat]||WARNA_RUSAK['Sedang'];
const coord = gj.geometry.coordinates; // [lng, lat]
const layer = L.circleMarker([coord[1],coord[0]], cfg).addTo(layerRusak);
layer.bindPopup(`
const coord = gj && Array.isArray(gj.geometry.coordinates) ? gj.geometry.coordinates : null; // [lng, lat]
let layer = null;
if(coord){
layer = L.circleMarker([coord[1],coord[0]], cfg).addTo(layerRusak);
layer.bindPopup(`
<div class="popup-title"><i class="fas fa-exclamation-triangle" style="color:#ef4444;margin-right:5px"></i>${item.lokasi}</div>
<div class="popup-row">Tingkat: <span style="color:${cfg.color};font-weight:700">${item.tingkat}</span></div>
${item.jenis?`<div class="popup-row">Jenis: <span>${item.jenis}</span></div>`:''}
<div class="popup-row">Dilaporkan: <span>${item.tanggal_lapor||'-'}</span></div>
${item.keterangan?`<div class="popup-row">Ket: <span>${item.keterangan}</span></div>`:''}
${item.foto?`<img class="popup-foto" src="${item.foto}" alt="foto">`:''}
`);
`);
}
const card = document.createElement('div');
card.className='data-card';
card.innerHTML=`
@@ -819,12 +839,12 @@ async function loadRusak(q=''){
</div>
${item.foto?`<img class="card-thumb" src="${item.foto}" alt="foto">`:''}
<div class="card-actions">
<button class="btn-sm btn-zoom" onclick="zoomRusak${item.id}()"><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-zoom" ${layer ? `onclick="zoomRusak${item.id}()"` : 'disabled title="Lokasi belum valid"'}><i class="fas fa-search-location"></i> Zoom</button>
<button class="btn-sm btn-edit" onclick="editRusak(${item.id})"><i class="fas fa-edit"></i> Edit</button>
<button class="btn-sm btn-hapus" onclick="hapusRusak(${item.id})"><i class="fas fa-trash"></i> Hapus</button>
</div>`;
list.appendChild(card);
window[`zoomRusak${item.id}`]=()=>map.setView([coord[1],coord[0]],17);
if(layer) window[`zoomRusak${item.id}`]=()=>map.setView([coord[1],coord[0]],17);
});
}