Files
Wilhelmus Ikchan Dwi Putra c8e75593cb Upload semua tugas SIG
2026-06-13 00:45:23 +07:00

216 lines
8.5 KiB
PHP

<?php
// ==========================================
// 1. BACKEND: KONEKSI & OTOMATISASI DATABASE
// ==========================================
$host = "localhost";
$user = "root"; // Sesuaikan jika username XAMPP/Laragon kamu berbeda
$pass = ""; // Sesuaikan jika ada password
// Koneksi awal ke MySQL
$conn = new mysqli($host, $user, $pass);
if ($conn->connect_error) {
die("Koneksi ke MySQL Gagal: " . $conn->connect_error);
}
// Buat database otomatis jika belum ada
$conn->query("CREATE DATABASE IF NOT EXISTS db_webgis_jalan");
$conn->select_db("db_webgis_jalan");
// Buat tabel otomatis jika belum ada
$conn->query("CREATE TABLE IF NOT EXISTS jalan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_jalan VARCHAR(150) NOT NULL,
status_jalan ENUM('Nasional', 'Provinsi', 'Kabupaten') NOT NULL,
panjang_jalan FLOAT NOT NULL,
geom TEXT NOT NULL
)");
// ==========================================
// 2. BACKEND: ROUTING API (SIMPAN & AMBIL)
// ==========================================
// A. Logika Ambil Data (Read)
if (isset($_GET['aksi']) && $_GET['aksi'] == 'ambil') {
header('Content-Type: application/json');
$result = $conn->query("SELECT * FROM jalan");
$data_jalan = array();
while($row = $result->fetch_assoc()) {
$data_jalan[] = $row;
}
echo json_encode($data_jalan);
exit; // Stop eksekusi agar HTML tidak ikut ter-echo
}
// B. Logika Simpan Data (Create)
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['aksi']) && $_POST['aksi'] == 'simpan') {
$nama = $_POST['nama'];
$status = $_POST['status'];
$panjang = $_POST['panjang'];
$geom = $_POST['geom'];
$stmt = $conn->prepare("INSERT INTO jalan (nama_jalan, status_jalan, panjang_jalan, geom) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssds", $nama, $status, $panjang, $geom);
if ($stmt->execute()) {
echo "Sukses";
} else {
echo "Gagal: " . $conn->error;
}
$stmt->close();
exit; // Stop eksekusi
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>WebGIS Manajemen Jalan (Single File)</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
body { margin: 0; padding: 0; font-family: sans-serif; display: flex; }
#sidebar { width: 320px; height: 100vh; padding: 20px; box-sizing: border-box; background: #f8f9fa; border-right: 2px solid #ddd; z-index: 1000; }
#map { width: calc(100% - 320px); height: 100vh; }
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; font-size: 14px; }
.form-group input, .form-group select { width: 100%; padding: 8px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; }
button { width: 100%; padding: 10px; background: #28a745; color: white; border: none; border-radius: 4px; font-weight: bold; cursor: pointer; }
button:hover { background: #218838; }
.info { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.4; }
</style>
</head>
<body>
<div id="sidebar">
<h2>Data Jalan</h2>
<hr>
<div class="form-group">
<label>Nama Jalan</label>
<input type="text" id="nama_jalan" placeholder="Contoh: Jl. Sudirman">
</div>
<div class="form-group">
<label>Status Jalan</label>
<select id="status_jalan">
<option value="Nasional">Nasional (Merah)</option>
<option value="Provinsi">Provinsi (Hijau)</option>
<option value="Kabupaten">Kabupaten (Biru)</option>
</select>
</div>
<div class="form-group">
<label>Panjang (Meter)</label>
<input type="text" id="panjang_jalan" readonly placeholder="Terhitung otomatis oleh Leaflet">
</div>
<button onclick="simpanKeDatabase()">Simpan Jalan</button>
<div class="info">
<strong>Cara Pakai:</strong><br>
1. Klik beberapa kali di peta untuk menggambar rute jalan.<br>
2. Panjang jalan akan terhitung otomatis.<br>
3. Isi Nama & Status, lalu klik Simpan.
</div>
</div>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
// Inisialisasi Peta (Pusat di Indonesia)
const map = L.map('map').setView([-2.5, 118], 5);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
}).addTo(map);
// Variabel untuk gambar jalan baru
let koordinatJalan = [];
let layerJalanBaru = L.polyline([], { color: '#555', weight: 4, dashArray: '5, 10' }).addTo(map);
// Fungsi pewarnaan dinamis sesuai perintah dosen
function dapatkanWarnaJalan(status) {
switch(status) {
case 'Nasional': return { color: '#FF0000', weight: 5 }; // Merah
case 'Provinsi': return { color: '#00FF00', weight: 4 }; // Hijau
case 'Kabupaten': return { color: '#0000FF', weight: 3 }; // Biru
default: return { color: '#000000', weight: 2 };
}
}
// Aksi klik di atas peta (Menggambar + Hitung otomatis)
map.on('click', function(e) {
let titik = e.latlng;
koordinatJalan.push(titik);
layerJalanBaru.setLatLngs(koordinatJalan);
// Hitung panjang otomatis dengan fungsi bawaan Leaflet .distanceTo()
let totalPanjang = 0;
for (let i = 0; i < koordinatJalan.length - 1; i++) {
totalPanjang += koordinatJalan[i].distanceTo(koordinatJalan[i+1]);
}
document.getElementById('panjang_jalan').value = totalPanjang.toFixed(2);
});
// Kirim data ke backend (proses INSERT)
function simpanKeDatabase() {
let nama = document.getElementById('nama_jalan').value;
let status = document.getElementById('status_jalan').value;
let panjang = document.getElementById('panjang_jalan').value;
if (!nama || koordinatJalan.length < 2) {
alert("Masukkan nama jalan dan klik minimal 2 titik di peta!");
return;
}
// Ubah polyline Leaflet ke bentuk String GeoJSON sesuai validasi dosen
let geojsonData = JSON.stringify(layerJalanBaru.toGeoJSON().geometry);
// AJAX kirim ke file ini sendiri (index.php)
fetch('index.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `aksi=simpan&nama=${encodeURIComponent(nama)}&status=${status}&panjang=${panjang}&geom=${encodeURIComponent(geojsonData)}`
})
.then(res => res.text())
.then(respon => {
if (respon.trim() === "Sukses") {
alert("Data jalan berhasil disimpan!");
location.reload(); // Reload untuk render ulang peta
} else {
alert("Gagal: " + respon);
}
});
}
// Ambil data jalan lama dari database (proses READ)
fetch('index.php?aksi=ambil')
.then(res => res.json())
.then(dataJalan => {
dataJalan.forEach(function(jalan) {
// Convert teks GeoJSON dari DB balik jadi objek JavaScript
let geometri = JSON.parse(jalan.geom);
let geojsonFeature = {
"type": "Feature",
"geometry": geometri,
"properties": {
"nama": jalan.nama_jalan,
"status": jalan.status_jalan,
"panjang": jalan.panjang_jalan
}
};
// Gambar ke peta dengan warna dinamis
L.geoJSON(geojsonFeature, {
style: function(feature) {
return dapatkanWarnaJalan(feature.properties.status);
}
}).bindPopup(`
<b>Nama Jalan:</b> ${jalan.nama_jalan}<br>
<b>Status:</b> Jalan ${jalan.status_jalan}<br>
<b>Panjang:</b> ${jalan.panjang_jalan} Meter
`).addTo(map);
});
});
</script>
</body>
</html>