993 lines
27 KiB
HTML
993 lines
27 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>WebGIS SPBU — Kota Pontianak</title>
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
|
|
|
|
<style>
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
html, body {
|
|
height: 100%;
|
|
font-family: 'Inter', -apple-system, 'Segoe UI', sans-serif;
|
|
background-color: #f1f5f9;
|
|
}
|
|
|
|
#map {
|
|
margin-left: 300px;
|
|
height: 100vh;
|
|
width: calc(100% - 300px);
|
|
}
|
|
|
|
/* =========================================
|
|
SIDEBAR
|
|
========================================= */
|
|
#sidebar {
|
|
position: absolute;
|
|
left: 0; top: 0;
|
|
width: 300px;
|
|
height: 100%;
|
|
background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
|
|
color: #f8fafc;
|
|
z-index: 1000;
|
|
padding: 0;
|
|
overflow-y: auto;
|
|
box-shadow: 4px 0 25px rgba(0,0,0,0.15);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* Scrollbar styling */
|
|
#sidebar::-webkit-scrollbar { width: 4px; }
|
|
#sidebar::-webkit-scrollbar-track { background: transparent; }
|
|
#sidebar::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }
|
|
|
|
#sidebar h2 {
|
|
text-align: left;
|
|
margin: 0;
|
|
padding: 24px 20px 20px;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
letter-spacing: -0.3px;
|
|
background: linear-gradient(135deg, rgba(6,182,212,0.1) 0%, rgba(139,92,246,0.08) 100%);
|
|
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
}
|
|
|
|
.section {
|
|
margin-top: 4px;
|
|
padding: 0 20px;
|
|
}
|
|
|
|
.section h3 {
|
|
font-size: 10px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1.5px;
|
|
color: #64748b;
|
|
margin-bottom: 8px;
|
|
margin-top: 16px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.section h4 {
|
|
font-size: 12px;
|
|
color: #94a3b8;
|
|
margin-bottom: 6px;
|
|
margin-top: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Search input */
|
|
#searchInput {
|
|
width: calc(100% - 40px);
|
|
margin: 16px 20px 4px;
|
|
padding: 10px 12px;
|
|
border-radius: 10px;
|
|
border: 1px solid #334155;
|
|
background: rgba(15, 23, 42, 0.6);
|
|
color: #f8fafc;
|
|
font-family: inherit;
|
|
font-size: 13px;
|
|
outline: none;
|
|
transition: all 0.3s;
|
|
}
|
|
#searchInput::placeholder { color: #475569; }
|
|
#searchInput:focus {
|
|
border-color: #06b6d4;
|
|
box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.1);
|
|
background: rgba(15, 23, 42, 0.8);
|
|
}
|
|
|
|
/* List items */
|
|
.list-item {
|
|
background: rgba(51, 65, 85, 0.5);
|
|
padding: 10px 12px;
|
|
margin-bottom: 6px;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
border: 1px solid transparent;
|
|
}
|
|
.list-item:hover {
|
|
background: rgba(71, 85, 105, 0.6);
|
|
transform: translateX(4px);
|
|
border-color: rgba(6, 182, 212, 0.3);
|
|
box-shadow: 0 2px 12px rgba(6, 182, 212, 0.06);
|
|
}
|
|
.list-item div[style*="font-weight"] { font-size: 13px; }
|
|
.list-item small { font-size: 10px; color: #64748b !important; }
|
|
|
|
/* Sidebar buttons */
|
|
#sidebar button {
|
|
width: 100%;
|
|
padding: 10px;
|
|
margin-top: 5px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
background: linear-gradient(135deg, #0891b2, #06b6d4);
|
|
color: white;
|
|
font-weight: 600;
|
|
font-family: inherit;
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
transition: all 0.25s;
|
|
box-shadow: 0 2px 8px rgba(6, 182, 212, 0.2);
|
|
}
|
|
#sidebar button:hover {
|
|
background: linear-gradient(135deg, #0e7490, #0891b2);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(6, 182, 212, 0.3);
|
|
}
|
|
|
|
/* =========================================
|
|
POPUP FORM STYLING
|
|
========================================= */
|
|
.leaflet-popup-content {
|
|
font-family: 'Inter', sans-serif !important;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
min-width: 220px;
|
|
}
|
|
.leaflet-popup-content b {
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
color: #0f172a;
|
|
}
|
|
|
|
input[type="text"], select {
|
|
width: 100%;
|
|
padding: 8px 10px;
|
|
margin-bottom: 10px;
|
|
margin-top: 4px;
|
|
border-radius: 8px;
|
|
border: 1px solid #e2e8f0;
|
|
background: #f8fafc;
|
|
font-family: inherit;
|
|
font-size: 13px;
|
|
color: #0f172a;
|
|
outline: none;
|
|
transition: all 0.2s;
|
|
}
|
|
input[type="text"]:focus, select:focus {
|
|
border-color: #06b6d4;
|
|
box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.1);
|
|
background: #ffffff;
|
|
}
|
|
|
|
form button[type="submit"] {
|
|
background: linear-gradient(135deg, #059669, #10b981);
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 14px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
font-family: inherit;
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
transition: all 0.25s;
|
|
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.2);
|
|
}
|
|
form button[type="submit"]:hover {
|
|
background: linear-gradient(135deg, #047857, #059669);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
|
|
}
|
|
|
|
/* Popup edit/delete buttons */
|
|
.leaflet-popup-content button {
|
|
padding: 6px 14px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-family: inherit;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
transition: all 0.2s;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.leaflet-editing-icon {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="sidebar">
|
|
<h2>🌍 WebGIS</h2>
|
|
|
|
<input type="text" id="searchInput" placeholder="Cari layer..." onkeyup="filterList()">
|
|
|
|
<div class="section">
|
|
<h3>📍 Layer</h3>
|
|
<h4>⛽ SPBU 24 Jam</h4>
|
|
<div id="list24"></div>
|
|
|
|
<h4>⛽ SPBU Tidak 24 Jam</h4>
|
|
<div id="listTidak"></div>
|
|
|
|
<h4>🛣️ Jalan</h4>
|
|
<div id="listJalan"></div>
|
|
|
|
<h4>🏡 Kavling</h4>
|
|
<div id="listKavling"></div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>🎛 Tools</h3>
|
|
<button onclick="map.zoomIn()">Zoom In</button>
|
|
<button onclick="map.zoomOut()">Zoom Out</button>
|
|
</div>
|
|
</div>
|
|
<div id="map"></div>
|
|
|
|
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw/dist/leaflet.draw.css"/>
|
|
<script src="https://unpkg.com/leaflet-draw/dist/leaflet.draw.js"></script>
|
|
<script src="https://unpkg.com/leaflet-geometryutil"></script>
|
|
|
|
<script>
|
|
// =======================
|
|
// FUNGSI SEARCH LAYER
|
|
// =======================
|
|
function filterList() {
|
|
let input = document.getElementById('searchInput').value.toLowerCase();
|
|
let items = document.querySelectorAll('.list-item');
|
|
|
|
items.forEach(item => {
|
|
let text = item.innerText.toLowerCase();
|
|
item.style.display = text.includes(input) ? "block" : "none";
|
|
});
|
|
}
|
|
|
|
// =======================
|
|
// HAPUS DATA
|
|
// =======================
|
|
function hapusData(id){
|
|
if(confirm("Yakin hapus data?")){
|
|
fetch('hapus.php?id=' + id + '&type=spbu')
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
alert("Data dihapus!");
|
|
location.reload();
|
|
});
|
|
}
|
|
}
|
|
|
|
// =======================
|
|
// EDIT DATA
|
|
// =======================
|
|
function editData(id, nama, wa, status){
|
|
let formEdit = `
|
|
<form id="editForm">
|
|
<input type="hidden" name="type" value="spbu">
|
|
<input type="hidden" name="id" value="${id}">
|
|
|
|
Nama SPBU:
|
|
<input type="text" name="nama_spbu" value="${nama}">
|
|
|
|
No WA:
|
|
<input type="text" name="no_wa" value="${wa}">
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="24jam" ${status === '24jam' ? 'selected' : ''}>24 Jam</option>
|
|
<option value="tidak" ${status === 'tidak' ? 'selected' : ''}>Tidak</option>
|
|
</select>
|
|
|
|
<button type="submit">Update</button>
|
|
</form>
|
|
`;
|
|
|
|
L.popup()
|
|
.setLatLng(map.getCenter())
|
|
.setContent(formEdit)
|
|
.openOn(map);
|
|
}
|
|
|
|
// =======================
|
|
// SUBMIT EDIT
|
|
// =======================
|
|
document.addEventListener('submit', function(e){
|
|
if(e.target && e.target.id === 'editForm'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('update.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Data berhasil diupdate!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal mengupdate data: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
});
|
|
|
|
// =======================
|
|
// INIT MAP
|
|
// =======================
|
|
// Menambahkan zoomControl: false agar tombol +- bawaan yang tertimpa sidebar hilang
|
|
const map = L.map('map', { zoomControl: false }).setView([-0.0557, 109.3491], 13);
|
|
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© OpenStreetMap'
|
|
}).addTo(map);
|
|
|
|
// AKTIFKAN DRAW TOOL
|
|
var drawnItems = new L.FeatureGroup();
|
|
map.addLayer(drawnItems);
|
|
|
|
var drawControl = new L.Control.Draw({
|
|
position: 'topright', // POSISI DRAW TOOL DIUBAH KE KANAN ATAS
|
|
draw: {
|
|
polygon: true,
|
|
polyline: true,
|
|
marker: true,
|
|
circle: false,
|
|
rectangle: false
|
|
},
|
|
edit: {
|
|
featureGroup: drawnItems,
|
|
edit: true,
|
|
remove: true
|
|
}
|
|
});
|
|
|
|
|
|
// HITUNG PANJANG & LUAS OTOMATIS
|
|
map.addControl(drawControl);
|
|
|
|
map.on(L.Draw.Event.CREATED, function (e) {
|
|
|
|
var layer = e.layer;
|
|
var type = e.layerType;
|
|
|
|
// =====================
|
|
// MARKER (SPBU)
|
|
// =====================
|
|
if(type === 'marker'){
|
|
var spbuIcon = L.icon({
|
|
iconUrl: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png',
|
|
iconSize: [32, 32]
|
|
});
|
|
|
|
layer.setIcon(spbuIcon);
|
|
|
|
let lat = layer.getLatLng().lat;
|
|
let lng = layer.getLatLng().lng;
|
|
|
|
let form = `
|
|
<form id="formData">
|
|
<b>Tambah SPBU</b><br><br>
|
|
|
|
Nama SPBU:
|
|
<input type="text" name="nama_spbu" required>
|
|
|
|
No WhatsApp:
|
|
<input type="text" name="no_wa" required>
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="24jam">Buka 24 Jam</option>
|
|
<option value="tidak">Tidak</option>
|
|
</select>
|
|
|
|
<input type="hidden" name="latitude" value="${lat}">
|
|
<input type="hidden" name="longitude" value="${lng}">
|
|
|
|
<button type="submit">Simpan</button>
|
|
</form>
|
|
`;
|
|
|
|
layer.bindPopup(form).openPopup();
|
|
}
|
|
|
|
// =====================
|
|
// TAMBAH KE MAP
|
|
// =====================
|
|
drawnItems.addLayer(layer);
|
|
|
|
let geojson = layer.toGeoJSON();
|
|
|
|
// =====================
|
|
// POLYLINE
|
|
// =====================
|
|
if(type === 'polyline'){
|
|
|
|
layer.setStyle({
|
|
color: 'blue',
|
|
weight: 4
|
|
});
|
|
|
|
let latlngs = layer.getLatLngs();
|
|
let panjang = 0;
|
|
|
|
for(let i=0; i<latlngs.length-1; i++){
|
|
panjang += latlngs[i].distanceTo(latlngs[i+1]);
|
|
}
|
|
|
|
layer.bindPopup(`
|
|
<form id="formJalan">
|
|
Nama Jalan:
|
|
<input type="text" name="nama_jalan">
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="nasional">Nasional</option>
|
|
<option value="provinsi">Provinsi</option>
|
|
<option value="kabupaten">Kabupaten</option>
|
|
</select>
|
|
|
|
Panjang: ${panjang.toFixed(2)} meter
|
|
|
|
<input type="hidden" name="panjang" value="${panjang}">
|
|
<input type="hidden" name="geom" value='${JSON.stringify(geojson)}'>
|
|
|
|
<button type="submit">Simpan</button>
|
|
</form>
|
|
`).openPopup();
|
|
}
|
|
|
|
// =====================
|
|
// POLYGON
|
|
// =====================
|
|
if(type === 'polygon'){
|
|
|
|
let latlngs = layer.getLatLngs()[0];
|
|
let luas = L.GeometryUtil.geodesicArea(latlngs);
|
|
|
|
layer.myId = null; // sementara
|
|
|
|
drawnItems.addLayer(layer);
|
|
|
|
layer.bindPopup(`
|
|
<form id="formKavling">
|
|
Nama Pemilik:
|
|
<input type="text" name="pemilik">
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="SHM">SHM</option>
|
|
<option value="HGB">HGB</option>
|
|
<option value="HGU">HGU</option>
|
|
<option value="HP">HP</option>
|
|
</select>
|
|
|
|
Luas: ${luas.toFixed(2)} m²
|
|
|
|
<input type="hidden" name="luas" value="${luas}">
|
|
<input type="hidden" name="geom" value='${JSON.stringify(geojson)}'>
|
|
|
|
<button type="submit">Simpan</button>
|
|
</form>
|
|
`).openPopup();
|
|
}
|
|
});
|
|
|
|
// WARNA OTOMATIS
|
|
// Polyline
|
|
|
|
function getWarnaJalan(status){
|
|
if(status === 'nasional') return 'blue';
|
|
if(status === 'provinsi') return 'green';
|
|
return 'red';
|
|
}
|
|
|
|
// Polygon
|
|
function getWarnaKavling(status){
|
|
if(status === 'SHM') return 'green';
|
|
if(status === 'HGB') return 'blue';
|
|
if(status === 'HGU') return 'orange';
|
|
return 'purple';
|
|
}
|
|
|
|
// SIMPAN JALAN
|
|
document.addEventListener('submit', function(e){
|
|
if(e.target.id === 'formJalan'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('simpan_jalan.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Jalan disimpan!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal menyimpan jalan: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
});
|
|
|
|
// SIMPAN KAVLING
|
|
document.addEventListener('submit', function(e){
|
|
if(e.target.id === 'formKavling'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('simpan_kavling.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Kavling disimpan!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal menyimpan kavling: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
});
|
|
|
|
// =======================
|
|
// ICON MARKER
|
|
// =======================
|
|
const greenIcon = new L.Icon({
|
|
iconUrl: 'https://maps.google.com/mapfiles/ms/icons/green-dot.png',
|
|
iconSize: [32, 32]
|
|
});
|
|
|
|
const redIcon = new L.Icon({
|
|
iconUrl: 'https://maps.google.com/mapfiles/ms/icons/red-dot.png',
|
|
iconSize: [32, 32]
|
|
});
|
|
// =======================
|
|
// LAYER GROUP SPBU
|
|
// =======================
|
|
var spbu24Jam = L.layerGroup();
|
|
var spbuTidak24Jam = L.layerGroup();
|
|
|
|
// Tambahkan ke map default (opsional)
|
|
spbu24Jam.addTo(map);
|
|
spbuTidak24Jam.addTo(map);
|
|
|
|
fetch('get_all.php')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
|
|
// =====================
|
|
// SPBU (POINT)
|
|
// =====================
|
|
if(data.spbu) { // Ditambahkan pengecekan agar tidak error jika data kosong
|
|
data.spbu.forEach(item => {
|
|
|
|
let icon = item.status === '24jam' ? greenIcon : redIcon;
|
|
|
|
let marker = L.marker([item.latitude, item.longitude], {
|
|
icon: icon,
|
|
draggable: true
|
|
});
|
|
|
|
marker.myId = item.id;
|
|
// MASUKKAN KE GROUP SESUAI STATUS
|
|
drawnItems.addLayer(marker);
|
|
|
|
// tetap simpan ke group hanya untuk kontrol layer
|
|
if(item.status === '24jam'){
|
|
spbu24Jam.addLayer(marker);
|
|
} else {
|
|
spbuTidak24Jam.addLayer(marker);
|
|
}
|
|
// tetap tambahkan ke drawnItems jika ingin bisa edit
|
|
drawnItems.addLayer(marker);
|
|
|
|
marker.bindPopup(`
|
|
<b>${item.nama_spbu}</b><br>
|
|
WA: ${item.no_wa}<br>
|
|
Status: ${item.status}<br><br>
|
|
|
|
<button onclick="editData(${item.id}, '${item.nama_spbu}', '${item.no_wa}', '${item.status}')">Edit</button>
|
|
<button onclick="hapusData(${item.id})">Hapus</button>
|
|
`);
|
|
|
|
marker.on('dragend', function(e){
|
|
let posisi = e.target.getLatLng();
|
|
|
|
fetch('update_posisi.php', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
|
body: `id=${item.id}&lat=${posisi.lat}&lng=${posisi.lng}`
|
|
});
|
|
});
|
|
|
|
tambahKeList(
|
|
item.nama_spbu,
|
|
[item.latitude, item.longitude],
|
|
marker,
|
|
item.status,
|
|
'spbu'
|
|
);
|
|
});
|
|
}
|
|
// =======================
|
|
// LAYER CONTROL
|
|
// =======================
|
|
var overlayMaps = {
|
|
"SPBU 24 Jam": spbu24Jam,
|
|
"SPBU Tidak 24 Jam": spbuTidak24Jam
|
|
};
|
|
|
|
L.control.layers(null, overlayMaps, {
|
|
collapsed: false
|
|
}).addTo(map);
|
|
// =====================
|
|
// KAVLING (POLYGON)
|
|
// =====================
|
|
if(data.kavling) {
|
|
data.kavling.forEach(item => {
|
|
|
|
try {
|
|
let geojson = JSON.parse(item.geom);
|
|
let warna = getWarnaKavling(item.status);
|
|
|
|
let layer = L.geoJSON(geojson, {
|
|
style: {
|
|
color: warna,
|
|
fillOpacity: 0.5
|
|
}
|
|
});
|
|
|
|
layer.eachLayer(l => {
|
|
l.myId = item.id;
|
|
drawnItems.addLayer(l);
|
|
|
|
l.bindPopup(`
|
|
<b>${item.pemilik || 'Tanpa Nama'}</b><br>
|
|
Status: ${item.status}<br>
|
|
Luas: ${parseFloat(item.luas).toFixed(2)} m²<br><br>
|
|
|
|
<button onclick="editKavling(${item.id}, '${item.pemilik || ''}', '${item.status}')">Edit</button>
|
|
<button onclick="hapusKavling(${item.id})">Hapus</button>
|
|
`);
|
|
|
|
tambahKeList(item.pemilik || 'Kavling', l.getBounds().getCenter(), l, null, 'kavling');
|
|
});
|
|
|
|
} catch(e){
|
|
console.log("Geom error kavling ID:", item.id);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
// =====================
|
|
// JALAN (POLYLINE)
|
|
// =====================
|
|
if(data.jalan) {
|
|
data.jalan.forEach(item => {
|
|
|
|
try {
|
|
let geojson = JSON.parse(item.geom);
|
|
let warna = getWarnaJalan(item.status);
|
|
|
|
let layer = L.geoJSON(geojson, {
|
|
style: {
|
|
color: warna,
|
|
weight: 4
|
|
}
|
|
});
|
|
|
|
layer.eachLayer(l => {
|
|
l.myId = item.id;
|
|
drawnItems.addLayer(l);
|
|
|
|
l.bindPopup(`
|
|
<b>${item.nama_jalan}</b><br>
|
|
Status: ${item.status}<br>
|
|
Panjang: ${parseFloat(item.panjang).toFixed(2)} meter<br><br>
|
|
|
|
<button onclick="editJalan(${item.id}, '${item.nama_jalan}', '${item.status}')">Edit</button>
|
|
<button onclick="hapusJalan(${item.id})">Hapus</button>
|
|
`);
|
|
|
|
tambahKeList(item.nama_jalan, l.getBounds().getCenter(), l, null, 'jalan');
|
|
});
|
|
|
|
} catch(e){
|
|
console.log("Geom error jalan ID:", item.id);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
|
|
// =======================
|
|
// SUBMIT FORM
|
|
// =======================
|
|
document.addEventListener('submit', function(e){
|
|
if(e.target && e.target.id === 'formData'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('simpan.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Data berhasil disimpan!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal menyimpan data: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
});
|
|
|
|
map.on(L.Draw.Event.EDITED, function (e) {
|
|
let layers = e.layers;
|
|
|
|
layers.eachLayer(function(layer){
|
|
|
|
// =====================
|
|
// MARKER (SPBU)
|
|
// =====================
|
|
if(layer instanceof L.Marker){
|
|
|
|
let latlng = layer.getLatLng();
|
|
|
|
fetch('update_posisi.php', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
|
body: `id=${layer.myId}&lat=${latlng.lat}&lng=${latlng.lng}`
|
|
});
|
|
|
|
}
|
|
|
|
// =====================
|
|
// POLYLINE / POLYGON
|
|
// =====================
|
|
else {
|
|
|
|
let geojson = layer.toGeoJSON();
|
|
let type = (layer instanceof L.Polygon) ? 'kavling' : 'jalan';
|
|
|
|
fetch('update_geom.php', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
id: layer.myId,
|
|
geom: geojson,
|
|
type: type
|
|
})
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
});
|
|
|
|
function hapusJalan(id){
|
|
if(confirm("Yakin hapus jalan?")){
|
|
fetch('hapus.php?id=' + id + '&type=jalan')
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
alert("Jalan dihapus!");
|
|
location.reload();
|
|
});
|
|
}
|
|
}
|
|
|
|
function hapusKavling(id){
|
|
if(confirm("Yakin hapus kavling?")){
|
|
fetch('hapus.php?id=' + id + '&type=kavling')
|
|
.then(() => {
|
|
alert("Kavling dihapus!");
|
|
location.reload();
|
|
});
|
|
}
|
|
}
|
|
|
|
function editJalan(id, nama, status){
|
|
|
|
let form = `
|
|
<form id="editJalanForm">
|
|
<input type="hidden" name="type" value="jalan">
|
|
<input type="hidden" name="id" value="${id}">
|
|
|
|
Nama Jalan:
|
|
<input type="text" name="nama_jalan" value="${nama}" required>
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="nasional" ${status==='nasional'?'selected':''}>Nasional</option>
|
|
<option value="provinsi" ${status==='provinsi'?'selected':''}>Provinsi</option>
|
|
<option value="kabupaten" ${status==='kabupaten'?'selected':''}>Kabupaten</option>
|
|
</select>
|
|
|
|
<button type="submit">Update</button>
|
|
</form>
|
|
`;
|
|
|
|
L.popup()
|
|
.setLatLng(map.getCenter())
|
|
.setContent(form)
|
|
.openOn(map);
|
|
}
|
|
|
|
document.addEventListener('submit', function(e){
|
|
|
|
// EDIT JALAN
|
|
if(e.target.id === 'editJalanForm'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('update.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Jalan berhasil diupdate!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal mengupdate jalan: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
|
|
// EDIT KAVLING
|
|
if(e.target.id === 'editKavlingForm'){
|
|
e.preventDefault();
|
|
|
|
let formData = new FormData(e.target);
|
|
|
|
fetch('update.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
if (res.trim() === 'OK') {
|
|
alert("Kavling berhasil diupdate!");
|
|
location.reload();
|
|
} else {
|
|
alert("Gagal mengupdate kavling: " + res);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert("Terjadi kesalahan jaringan: " + err.message);
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
function editKavling(id, pemilik, status){
|
|
let form = `
|
|
<form id="editKavlingForm">
|
|
<input type="hidden" name="type" value="kavling">
|
|
<input type="hidden" name="id" value="${id}">
|
|
|
|
Nama Pemilik:
|
|
<input type="text" name="pemilik" value="${pemilik}">
|
|
|
|
Status:
|
|
<select name="status">
|
|
<option value="SHM" ${status==='SHM'?'selected':''}>SHM</option>
|
|
<option value="HGB" ${status==='HGB'?'selected':''}>HGB</option>
|
|
<option value="HGU" ${status==='HGU'?'selected':''}>HGU</option>
|
|
<option value="HP" ${status==='HP'?'selected':''}>HP</option>
|
|
</select>
|
|
|
|
<button type="submit">Update</button>
|
|
</form>
|
|
`;
|
|
L.popup().setLatLng(map.getCenter()).setContent(form).openOn(map);
|
|
}
|
|
|
|
map.on(L.Draw.Event.DRAWSTART, function(){
|
|
console.log("Mulai gambar");
|
|
});
|
|
|
|
map.on(L.Draw.Event.DRAWSTOP, function(){
|
|
console.log("Selesai gambar");
|
|
});
|
|
|
|
function tambahKeList(nama, latlng, layer, status, type){
|
|
|
|
let div;
|
|
let icon = "";
|
|
|
|
if (type === 'jalan') {
|
|
div = document.getElementById('listJalan');
|
|
icon = "🛣️";
|
|
} else if (type === 'kavling') {
|
|
div = document.getElementById('listKavling');
|
|
icon = "🏡";
|
|
} else {
|
|
// PILIH CONTAINER BERDASARKAN STATUS
|
|
if(status === '24jam'){
|
|
div = document.getElementById('list24');
|
|
} else {
|
|
div = document.getElementById('listTidak');
|
|
}
|
|
icon = "⛽";
|
|
}
|
|
|
|
let item = document.createElement('div');
|
|
item.className = 'list-item';
|
|
|
|
item.innerHTML = `
|
|
<div style="font-weight:bold">${icon} ${nama}</div>
|
|
<small style="color:#cbd5f5;">Klik untuk fokus</small>
|
|
`;
|
|
|
|
item.onclick = function(){
|
|
map.setView(latlng, 16);
|
|
|
|
if(layer.getBounds){
|
|
map.fitBounds(layer.getBounds());
|
|
}
|
|
|
|
layer.openPopup();
|
|
};
|
|
|
|
div.appendChild(item);
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html> |