201 lines
10 KiB
PHP
201 lines
10 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>WebGIS Manajemen Jalan & Parsil Tanah</title>
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<link rel="stylesheet" href="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.css" />
|
|
<script src="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.min.js"></script>
|
|
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f6f9; }
|
|
#map { height: 500px; width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); }
|
|
.container { display: flex; gap: 20px; margin-top: 20px; }
|
|
.form-container { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); width: 35%; display: none; }
|
|
.table-container { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); width: 100%; }
|
|
.form-group { margin-bottom: 12px; }
|
|
.form-group label { display: block; font-weight: bold; margin-bottom: 5px; }
|
|
.form-group input, .form-group select { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }
|
|
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
|
table, th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
th { background-color: #333; color: white; }
|
|
.btn { padding: 6px 12px; border: none; border-radius: 4px; cursor: pointer; color: white; font-weight: bold; text-decoration: none; }
|
|
.btn-save { background-color: #28a745; width: 100%; }
|
|
.btn-delete { background-color: #dc3545; font-size: 12px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h2>Manajemen Data Spasial Jalan & Parsil Tanah - Kota Pontianak</h2>
|
|
<div id="map"></div>
|
|
|
|
<div class="container">
|
|
<div class="form-container" id="form-box">
|
|
<h3 id="form-title">Input Data Spasial</h3>
|
|
<form action="proses.php" method="POST">
|
|
<input type="hidden" id="action" name="action" value="create">
|
|
<input type="hidden" id="id_data" name="id_data">
|
|
<input type="hidden" id="type" name="type">
|
|
<input type="hidden" id="geojson-str" name="geojson">
|
|
|
|
<div class="form-group">
|
|
<label id="label-nama">Nama Objek:</label>
|
|
<input type="text" id="nama_atribut" name="nama_atribut" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Status / Hak Kepemilikan:</label>
|
|
<select id="status-select" name="status" required></select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label id="label-hitung">Hasil Hitung Otomatis:</label>
|
|
<input type="text" id="hasil-hitung" name="hasil_hitung" readonly style="background-color: #e9ecef; font-weight: bold;">
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-save">Simpan Data</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<h3>Daftar Data Tersimpan</h3>
|
|
<div style="display: flex; gap: 20px;">
|
|
<div style="flex: 1;">
|
|
<h4>Data Jalan (Line)</h4>
|
|
<table id="tabel-jalan">
|
|
<tr><th>Nama Jalan</th><th>Status</th><th>Panjang (m)</th><th>Aksi</th></tr>
|
|
</table>
|
|
</div>
|
|
<div style="flex: 1;">
|
|
<h4>Data Parsil (Polygon)</h4>
|
|
<table id="tabel-parsil">
|
|
<tr><th>Kode Kavling</th><th>Status</th><th>Luas (m²)</th><th>Aksi</th></tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// 1. Inisialisasi Peta Satelit
|
|
const map = L.map('map').setView([-0.0245, 109.3400], 14);
|
|
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}').addTo(map);
|
|
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png').addTo(map);
|
|
|
|
// 2. Toolbar Digitasi Leaflet-Geoman
|
|
map.pm.addControls({
|
|
position: 'topleft',
|
|
drawMarker: false, drawCircleMarker: false, drawRectangle: false, drawCircle: false,
|
|
drawPolyline: true, drawPolygon: true, editMode: true, removalMode: false
|
|
});
|
|
|
|
// 3. Aksi Setelah Menggambar (CREATE)
|
|
map.on('pm:create', function(e) {
|
|
const layer = e.layer;
|
|
const shape = e.shape;
|
|
const geojson = layer.toGeoJSON();
|
|
|
|
document.getElementById('form-box').style.display = 'block';
|
|
document.getElementById('action').value = 'create';
|
|
document.getElementById('geojson-str').value = JSON.stringify(geojson);
|
|
|
|
if (shape === 'Line') {
|
|
document.getElementById('form-title').innerText = "Tambah Data Jalan Baru";
|
|
document.getElementById('label-nama').innerText = "Nama Jalan:";
|
|
document.getElementById('type').value = "jalan";
|
|
|
|
// Hitung Panjang Otomatis dengan fungsi bawaan LeafletJS (.distanceTo)
|
|
const latlngs = layer.getLatLngs();
|
|
let totalLength = 0;
|
|
for (let i = 0; i < latlngs.length - 1; i++) {
|
|
totalLength += latlngs[i].distanceTo(latlngs[i+1]);
|
|
}
|
|
document.getElementById('hasil-hitung').value = totalLength.toFixed(2) + " Meter";
|
|
setDropdown(['Nasional', 'Provinsi', 'Kabupaten']);
|
|
} else if (shape === 'Polygon') {
|
|
document.getElementById('form-title').innerText = "Tambah Data Parsil Tanah";
|
|
document.getElementById('label-nama').innerText = "Kode Kavling:";
|
|
document.getElementById('type').value = "parsil";
|
|
|
|
// Hitung Luas Otomatis rumus bola sferis bawahan Leaflet
|
|
const luas = hitungLuasBumi(layer.getLatLngs()[0]);
|
|
document.getElementById('hasil-hitung').value = luas.toFixed(2) + " m²";
|
|
setDropdown(['SHM', 'HGB', 'HGU', 'HP']);
|
|
}
|
|
});
|
|
|
|
function setDropdown(options) {
|
|
const select = document.getElementById('status-select');
|
|
select.innerHTML = '';
|
|
options.forEach(opt => {
|
|
let el = document.createElement('option');
|
|
el.value = opt; el.innerText = opt; select.appendChild(el);
|
|
});
|
|
}
|
|
|
|
function hitungLuasBumi(latlngs) {
|
|
let area = 0; const radius = 6378137;
|
|
if (latlngs.length > 2) {
|
|
for (let i = 0; i < latlngs.length; i++) {
|
|
let p1 = latlngs[i]; let p2 = latlngs[(i + 1) % latlngs.length];
|
|
area += (p2.lng - p1.lng) * Math.PI / 180 * (2 + Math.sin(p1.lat * Math.PI / 180) + Math.sin(p2.lat * Math.PI / 180));
|
|
}
|
|
area = area * radius * radius / 2;
|
|
}
|
|
return Math.abs(area);
|
|
}
|
|
|
|
// 4. LOAD DATA DARI DATABASE & PEWARNAAN OTOMATIS (READ)
|
|
fetch('get_data.php')
|
|
.then(res => {
|
|
if (!res.ok) throw new Error("Gagal mengambil data dari get_data.php");
|
|
return res.json();
|
|
})
|
|
.then(data => {
|
|
console.log("Data dari database:", data); // Untuk cek di F12 Console
|
|
|
|
// A. Render Jalan (Line)
|
|
if (data.jalan && data.jalan.length > 0) {
|
|
data.jalan.forEach(j => {
|
|
// Antisipasi variasi penulisan huruf besar/kecil di database
|
|
let statusJalan = j.status ? j.status.toLowerCase().trim() : '';
|
|
let warna = 'red'; // Default jika tidak cocok
|
|
|
|
if (statusJalan === 'nasional') warna = 'red';
|
|
else if (statusJalan === 'provinsi') warna = 'blue';
|
|
else if (statusJalan === 'kabupaten') warna = 'green';
|
|
|
|
L.geoJSON(j.geojson, {
|
|
style: { color: warna, weight: 5, opacity: 0.9 }
|
|
}).addTo(map)
|
|
.bindPopup(`<b>Jalan: ${j.nama}</b><br>Status: Jalan ${j.status}<br>Panjang: ${j.panjang} m`);
|
|
|
|
appendKeTabel('tabel-jalan', j.id, j.nama, j.status, j.panjang, 'jalan');
|
|
});
|
|
}
|
|
|
|
// B. Render Parsil (Polygon)
|
|
if (data.parsil && data.parsil.length > 0) {
|
|
data.parsil.forEach(p => {
|
|
let statusParsil = p.status ? p.status.toUpperCase().trim() : '';
|
|
let warna = '#FFD700'; // Default SHM (Kuning/Emas)
|
|
|
|
if (statusParsil === 'SHM') warna = '#FFD700';
|
|
else if (statusParsil === 'HGB') warna = '#FF8C00'; // Oranye
|
|
else if (statusParsil === 'HGU') warna = '#9370DB'; // Ungu
|
|
else if (statusParsil === 'HP') warna = '#00CED1'; // Biru Muda
|
|
|
|
L.geoJSON(p.geojson, {
|
|
style: { color: warna, fillColor: warna, fillOpacity: 0.5, weight: 2 }
|
|
}).addTo(map)
|
|
.bindPopup(`<b>Kavling: ${p.kode}</b><br>Status: ${p.status}<br>Luas: ${p.luas} m²`);
|
|
|
|
appendKeTabel('tabel-parsil', p.id, p.kode, p.status, p.luas, 'parsil');
|
|
});
|
|
}
|
|
})
|
|
.catch(err => console.error("Error WebGIS:", err));
|
|
</script>
|
|
</body>
|
|
</html> |