perbaikan format kode web-gis

This commit is contained in:
2026-06-06 12:53:54 +07:00
parent c2efc4414f
commit 6b7fa7e467
20 changed files with 52 additions and 703 deletions
+16 -3
View File
@@ -366,14 +366,27 @@ web-gis/
├── create_tables.php ← Init database ├── create_tables.php ← Init database
├── db_config.php ← Database config ├── db_config.php ← Database config
├── api/ ├── rancangan_sistem/ ← API & UI untuk rumah ibadah + penduduk miskin
│ ├── save_rumah_ibadah.php
│ ├── get_rumah_ibadah.php │ ├── get_rumah_ibadah.php
│ ├── save_rumah_ibadah.php
│ ├── update_rumah_ibadah.php
│ ├── delete_rumah_ibadah.php │ ├── delete_rumah_ibadah.php
│ ├── save_penduduk_miskin.php
│ ├── get_penduduk_miskin.php │ ├── get_penduduk_miskin.php
│ ├── save_penduduk_miskin.php
│ ├── update_penduduk_miskin.php
│ └── delete_penduduk_miskin.php │ └── delete_penduduk_miskin.php
├── fitur_jalan_parsel/ ← API & UI untuk jalan rusak, polyline/polygon
│ ├── get_jalan_rusak.php
│ ├── save_jalan_rusak.php
│ └── delete_jalan_rusak.php
├── layer_groups_choropleth/← API & UI untuk spatial features + choropleth
│ ├── get_features.php
│ ├── save_feature.php
│ ├── update_feature.php
│ └── delete_feature.php
└── data/ └── data/
├── pontianak-kecamatan.geojson ← Choropleth data ├── pontianak-kecamatan.geojson ← Choropleth data
└── Export_Output_2.json ← Road network data └── Export_Output_2.json ← Road network data
-36
View File
@@ -1,36 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'ID fitur tidak valid']);
$conn->close();
exit;
}
$stmt = $conn->prepare("DELETE FROM spatial_features WHERE id = ?");
if (!$stmt) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $conn->error]);
$conn->close();
exit;
}
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Fitur berhasil dihapus']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-46
View File
@@ -1,46 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = $_POST['id'] ?? '';
if (empty($id)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'ID wajib diisi']);
exit;
}
// Ambil data gambar untuk dihapus
$stmt = $conn->prepare("SELECT gambar FROM jalan_rusak WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if ($row && $row['gambar'] && file_exists($row['gambar'])) {
unlink($row['gambar']);
}
$stmt->close();
// Hapus record
$stmt = $conn->prepare("DELETE FROM jalan_rusak WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Laporan jalan rusak berhasil dihapus']);
} else {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
$conn->close();
exit;
}
http_response_code(405);
echo json_encode(['status' => 'error', 'message' => 'Method tidak diizinkan']);
$conn->close();
?>
-26
View File
@@ -1,26 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']);
$conn->close();
exit;
}
$stmt = $conn->prepare("DELETE FROM penduduk_miskin WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Data penduduk miskin dihapus']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-26
View File
@@ -1,26 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']);
$conn->close();
exit;
}
$stmt = $conn->prepare("DELETE FROM rumah_ibadah WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Rumah ibadah dihapus']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-41
View File
@@ -1,41 +0,0 @@
<?php
header('Content-Type: application/json');
// Pastikan file db_config.php sudah benar konfigurasinya
include 'db_config.php';
/**
* Mengambil semua fitur spasial dari tabel spatial_features.
* Data diurutkan berdasarkan waktu pembuatan terbaru.
*/
$sql = "SELECT id, nama_objek, kategori, status_objek, type, geometry_data, nilai_ukur, created_at
FROM spatial_features
ORDER BY created_at DESC";
$result = $conn->query($sql);
$features = [];
if (!$result) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Query gagal: ' . $conn->error]);
$conn->close();
exit;
}
if ($result && $result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
// Mendecode data JSON koordinat agar bisa langsung digunakan oleh Leaflet di frontend
$row['geometry_data'] = json_decode($row['geometry_data']);
// Memastikan nilai_ukur dikirim sebagai angka (float/double)
$row['nilai_ukur'] = (float)$row['nilai_ukur'];
$features[] = $row;
}
}
// Mengirimkan data dalam format JSON
echo json_encode($features);
// Menutup koneksi database
$conn->close();
?>
-29
View File
@@ -1,29 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
$sql = "SELECT id, latitude, longitude, jenis_kerusakan, deskripsi, severity, gambar, created_at
FROM jalan_rusak
ORDER BY created_at DESC";
$result = $conn->query($sql);
$data = [];
if (!$result) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Query gagal: ' . $conn->error]);
$conn->close();
exit;
}
if ($result && $result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$row['latitude'] = (float)$row['latitude'];
$row['longitude'] = (float)$row['longitude'];
$data[] = $row;
}
}
echo json_encode($data);
$conn->close();
?>
-34
View File
@@ -1,34 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
$sql = "SELECT id, nama_ketua_kk, jumlah_anggota, latitude, longitude, rumah_ibadah_id, rumah_ibadah_nama, jarak_ke_rumah_ibadah_m, bantuan_status, bantuan_catatan, bantuan_updated_at, created_at
FROM penduduk_miskin
ORDER BY created_at DESC";
$result = $conn->query($sql);
$data = [];
if (!$result) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Query gagal: ' . $conn->error]);
$conn->close();
exit;
}
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$row['latitude'] = (float)$row['latitude'];
$row['longitude'] = (float)$row['longitude'];
$row['jumlah_anggota'] = (int)$row['jumlah_anggota'];
$row['rumah_ibadah_id'] = $row['rumah_ibadah_id'] !== null ? (int)$row['rumah_ibadah_id'] : null;
$row['jarak_ke_rumah_ibadah_m'] = $row['jarak_ke_rumah_ibadah_m'] !== null ? (float)$row['jarak_ke_rumah_ibadah_m'] : null;
$row['bantuan_status'] = $row['bantuan_status'] ?: 'belum';
$row['bantuan_catatan'] = $row['bantuan_catatan'] ?? '';
$data[] = $row;
}
}
echo json_encode($data);
$conn->close();
?>
-30
View File
@@ -1,30 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
$sql = "SELECT id, nama, alamat, pic, latitude, longitude, radius_m, created_at
FROM rumah_ibadah
ORDER BY created_at DESC";
$result = $conn->query($sql);
$data = [];
if (!$result) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Query gagal: ' . $conn->error]);
$conn->close();
exit;
}
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$row['latitude'] = (float)$row['latitude'];
$row['longitude'] = (float)$row['longitude'];
$row['radius_m'] = (int)$row['radius_m'];
$data[] = $row;
}
}
echo json_encode($data);
$conn->close();
?>
+22 -22
View File
@@ -2090,8 +2090,8 @@
formData.append('gambar', fileInput.files[0]); formData.append('gambar', fileInput.files[0]);
} }
fetch('save_jalan_rusak.php', { method: 'POST', body: formData }) fetch('fitur_jalan_parsel/save_jalan_rusak.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'save_jalan_rusak.php')) .then(res => parseJsonResponse(res, 'fitur_jalan_parsel/save_jalan_rusak.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
showMessage('✅ Laporan jalan rusak berhasil disimpan', 'bg-green-600 text-white'); showMessage('✅ Laporan jalan rusak berhasil disimpan', 'bg-green-600 text-white');
@@ -2152,7 +2152,7 @@
function loadRoadDamage(force = false) { function loadRoadDamage(force = false) {
if (!force && (document.hidden || suppressAutoReload)) return; if (!force && (document.hidden || suppressAutoReload)) return;
fetch('get_jalan_rusak.php') fetch('fitur_jalan_parsel/get_jalan_rusak.php')
.then(res => { .then(res => {
if (!res.ok) throw new Error('HTTP Error: ' + res.status); if (!res.ok) throw new Error('HTTP Error: ' + res.status);
return res.text(); return res.text();
@@ -2367,8 +2367,8 @@
const formData = new FormData(); const formData = new FormData();
formData.append('id', id); formData.append('id', id);
fetch('delete_jalan_rusak.php', { method: 'POST', body: formData }) fetch('fitur_jalan_parsel/delete_jalan_rusak.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'delete_jalan_rusak.php')) .then(res => parseJsonResponse(res, 'fitur_jalan_parsel/delete_jalan_rusak.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
showMessage('🗑️ Laporan berhasil dihapus', 'bg-orange-600 text-white'); showMessage('🗑️ Laporan berhasil dihapus', 'bg-orange-600 text-white');
@@ -3065,7 +3065,7 @@
formData.append('longitude', pendingRumahIbadahCoords.lng); formData.append('longitude', pendingRumahIbadahCoords.lng);
formData.append('radius_m', radius); formData.append('radius_m', radius);
const endpoint = id ? 'update_rumah_ibadah.php' : 'save_rumah_ibadah.php'; const endpoint = id ? 'rancangan_sistem/update_rumah_ibadah.php' : 'rancangan_sistem/save_rumah_ibadah.php';
if (id) { if (id) {
formData.append('id', id); formData.append('id', id);
} }
@@ -3090,8 +3090,8 @@
const formData = new FormData(); const formData = new FormData();
formData.append('id', id); formData.append('id', id);
fetch('delete_rumah_ibadah.php', { method: 'POST', body: formData }) fetch('rancangan_sistem/delete_rumah_ibadah.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'delete_rumah_ibadah.php')) .then(res => parseJsonResponse(res, 'rancangan_sistem/delete_rumah_ibadah.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
showMessage('🗑️ Rumah ibadah berhasil dihapus', 'bg-orange-600 text-white'); showMessage('🗑️ Rumah ibadah berhasil dihapus', 'bg-orange-600 text-white');
@@ -3134,7 +3134,7 @@
formData.append('rumah_ibadah_nama', nearest.record.nama); formData.append('rumah_ibadah_nama', nearest.record.nama);
formData.append('jarak_ke_rumah_ibadah_m', nearest.distance.toFixed(2)); formData.append('jarak_ke_rumah_ibadah_m', nearest.distance.toFixed(2));
const endpoint = id ? 'update_penduduk_miskin.php' : 'save_penduduk_miskin.php'; const endpoint = id ? 'rancangan_sistem/update_penduduk_miskin.php' : 'rancangan_sistem/save_penduduk_miskin.php';
if (id) { if (id) {
formData.append('id', id); formData.append('id', id);
} }
@@ -3160,8 +3160,8 @@
const formData = new FormData(); const formData = new FormData();
formData.append('id', id); formData.append('id', id);
fetch('delete_penduduk_miskin.php', { method: 'POST', body: formData }) fetch('rancangan_sistem/delete_penduduk_miskin.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'delete_penduduk_miskin.php')) .then(res => parseJsonResponse(res, 'rancangan_sistem/delete_penduduk_miskin.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
showMessage('🗑️ Data penduduk miskin berhasil dihapus', 'bg-orange-600 text-white'); showMessage('🗑️ Data penduduk miskin berhasil dihapus', 'bg-orange-600 text-white');
@@ -3206,7 +3206,7 @@
function loadRumahIbadah(force = false) { function loadRumahIbadah(force = false) {
if (!force && (document.hidden || suppressAutoReload)) return; if (!force && (document.hidden || suppressAutoReload)) return;
fetch('get_rumah_ibadah.php') fetch('rancangan_sistem/get_rumah_ibadah.php')
.then(res => { .then(res => {
if (!res.ok) throw new Error('HTTP Error: ' + res.status); if (!res.ok) throw new Error('HTTP Error: ' + res.status);
return res.text(); return res.text();
@@ -3250,7 +3250,7 @@
function loadPendudukMiskin(force = false) { function loadPendudukMiskin(force = false) {
if (!force && (document.hidden || suppressAutoReload)) return; if (!force && (document.hidden || suppressAutoReload)) return;
fetch('get_penduduk_miskin.php') fetch('rancangan_sistem/get_penduduk_miskin.php')
.then(res => { .then(res => {
if (!res.ok) throw new Error('HTTP Error: ' + res.status); if (!res.ok) throw new Error('HTTP Error: ' + res.status);
return res.text(); return res.text();
@@ -3566,7 +3566,7 @@
function loadFeatures(force = false) { function loadFeatures(force = false) {
if (!force && (document.hidden || suppressAutoReload || isFeatureDrawing || isFeatureSaving)) return; if (!force && (document.hidden || suppressAutoReload || isFeatureDrawing || isFeatureSaving)) return;
fetch('get_features.php') fetch('layer_groups_choropleth/get_features.php')
.then(res => { .then(res => {
if (!res.ok) throw new Error('HTTP Error: ' + res.status); if (!res.ok) throw new Error('HTTP Error: ' + res.status);
return res.text(); return res.text();
@@ -3638,8 +3638,8 @@
formData.append('nilai', nilai); formData.append('nilai', nilai);
isFeatureSaving = true; isFeatureSaving = true;
fetch('save_feature.php', { method: 'POST', body: formData }) fetch('layer_groups_choropleth/save_feature.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'save_feature.php')) .then(res => parseJsonResponse(res, 'layer_groups_choropleth/save_feature.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
showMessage('✅ Fitur berhasil disimpan', 'bg-green-600 text-white'); showMessage('✅ Fitur berhasil disimpan', 'bg-green-600 text-white');
@@ -3762,8 +3762,8 @@
const formData = new FormData(); const formData = new FormData();
Object.entries(payload).forEach(([key, value]) => formData.append(key, value)); Object.entries(payload).forEach(([key, value]) => formData.append(key, value));
fetch('update_feature.php', { method: 'POST', body: formData }) fetch('layer_groups_choropleth/update_feature.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'update_feature.php')) .then(res => parseJsonResponse(res, 'layer_groups_choropleth/update_feature.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
layer.featureData.nama_objek = payload.nama; layer.featureData.nama_objek = payload.nama;
@@ -3830,8 +3830,8 @@
const formData = new FormData(); const formData = new FormData();
Object.entries(payload).forEach(([key, value]) => formData.append(key, value)); Object.entries(payload).forEach(([key, value]) => formData.append(key, value));
fetch('update_feature.php', { method: 'POST', body: formData }) fetch('layer_groups_choropleth/update_feature.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'update_feature.php')) .then(res => parseJsonResponse(res, 'layer_groups_choropleth/update_feature.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
layer.featureData.geometry_data = JSON.parse(payload.geometry); layer.featureData.geometry_data = JSON.parse(payload.geometry);
@@ -3859,8 +3859,8 @@
const formData = new FormData(); const formData = new FormData();
formData.append('id', id); formData.append('id', id);
fetch('delete_feature.php', { method: 'POST', body: formData }) fetch('layer_groups_choropleth/delete_feature.php', { method: 'POST', body: formData })
.then(res => parseJsonResponse(res, 'delete_feature.php')) .then(res => parseJsonResponse(res, 'layer_groups_choropleth/delete_feature.php'))
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
if (layer) removeSpatialFeatureLayer(layer, layer.featureType || 'polyline'); if (layer) removeSpatialFeatureLayer(layer, layer.featureType || 'polyline');
+5 -1
View File
@@ -3,18 +3,21 @@
Ringkasan singkat: rancangan ini menggabungkan data titik (SPBU, fasilitas), jaringan jalan (polyline), parsel tanah (polygon dengan luas otomatis), dan peta tematik (choropleth). Tujuan: menyediakan basis data spasial untuk analisis kebutuhan bantuan, akses layanan, dan prioritas intervensi. Ringkasan singkat: rancangan ini menggabungkan data titik (SPBU, fasilitas), jaringan jalan (polyline), parsel tanah (polygon dengan luas otomatis), dan peta tematik (choropleth). Tujuan: menyediakan basis data spasial untuk analisis kebutuhan bantuan, akses layanan, dan prioritas intervensi.
Komponen: Komponen:
- Data: sampel sensus, kemiskinan, infrastruktur, peta batas administrasi, penggunaan lahan, parsel tanah. - Data: sampel sensus, kemiskinan, infrastruktur, peta batas administrasi, penggunaan lahan, parsel tanah.
- Backend: API PHP ringan untuk CRUD GeoJSON + penyimpanan file atau database spatial (PostGIS direkomendasikan). - Backend: API PHP ringan untuk CRUD GeoJSON + penyimpanan file atau database spatial (PostGIS direkomendasikan).
- Frontend: Leaflet + plugins (Draw, Turf.js) untuk editing, pengukuran, dan visualisasi layer groups. - Frontend: Leaflet + plugins (Draw, Turf.js) untuk editing, pengukuran, dan visualisasi layer groups.
- Analitik: agregasi statistik per kelurahan/kecamatan untuk choropleth (tingkat kemiskinan, akses fasilitas). - Analitik: agregasi statistik per kelurahan/kecamatan untuk choropleth (tingkat kemiskinan, akses fasilitas).
Alur kerja singkat: Alur kerja singkat:
1. Kumpulkan & validasi data atribut (nama, id, status ekonomis, luas parsel). 1. Kumpulkan & validasi data atribut (nama, id, status ekonomis, luas parsel).
2. Masukkan ke sistem: titik/line/polygon. 2. Masukkan ke sistem: titik/line/polygon.
3. Hitung atribut turunan: luas parsel (m²), distance-to-nearest-facility, road-condition index. 3. Hitung atribut turunan: luas parsel (m²), distance-to-nearest-facility, road-condition index.
4. Hasilkan peta tematik & laporan untuk prioritisasi intervensi. 4. Hasilkan peta tematik & laporan untuk prioritisasi intervensi.
Rekomendasi teknis singkat: Rekomendasi teknis singkat:
- Gunakan PostGIS untuk query spasial yang efisien. - Gunakan PostGIS untuk query spasial yang efisien.
- Simpan snapshot GeoJSON untuk interoperabilitas. - Simpan snapshot GeoJSON untuk interoperabilitas.
- Bangun API otentikasi dan logging perubahan (audit trail) untuk kebijakan bantuan. - Bangun API otentikasi dan logging perubahan (audit trail) untuk kebijakan bantuan.
@@ -22,8 +25,9 @@ Rekomendasi teknis singkat:
Catatan: folder lain di repo ini berisi contoh starter untuk tiap fitur (uji_spbu, fitur_jalan_parsel, layer_groups_choropleth). Catatan: folder lain di repo ini berisi contoh starter untuk tiap fitur (uji_spbu, fitur_jalan_parsel, layer_groups_choropleth).
Global Leaflet loader: Global Leaflet loader:
- File: `global/leaflet-loader.js` — tambahkan tag berikut ke halaman HTML Anda untuk memuat Leaflet dari satu sumber global: - File: `global/leaflet-loader.js` — tambahkan tag berikut ke halaman HTML Anda untuk memuat Leaflet dari satu sumber global:
<script src="../global/leaflet-loader.js"></script> <script src="../global/leaflet-loader.js"></script>
Gunakan `rancangan_sistem/index.html` sebagai contoh integrasi: halaman akan memanggil `../get_rumah_ibadah.php` dan `../get_penduduk_miskin.php` dari root repository dan menambahkan data ke peta. Gunakan `rancangan_sistem/index.html` sebagai contoh integrasi: halaman akan memanggil `rancangan_sistem/get_rumah_ibadah.php` dan `rancangan_sistem/get_penduduk_miskin.php` (endpoints lokal di folder yang sama) dan menambahkan data ke peta.
-50
View File
@@ -1,50 +0,0 @@
<?php
header('Content-Type: application/json');
ini_set('display_errors', '0');
ini_set('html_errors', '0');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nama = trim($_POST['nama'] ?? '');
$kategori = trim($_POST['kategori'] ?? '');
if ($kategori === 'Parsil Tanah') {
$kategori = 'Tanah';
}
$status = trim($_POST['status'] ?? '');
$type = trim($_POST['type'] ?? '');
$geometry = $_POST['geometry'] ?? '';
$nilai = (float)($_POST['nilai'] ?? 0); // Nilai otomatis dari frontend
if ($nama === '' || $kategori === '' || $status === '' || $type === '' || $geometry === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Data fitur tidak lengkap']);
$conn->close();
exit;
}
$stmt = $conn->prepare("INSERT INTO spatial_features (nama_objek, kategori, status_objek, type, geometry_data, nilai_ukur) VALUES (?, ?, ?, ?, ?, ?)");
if (!$stmt) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $conn->error]);
$conn->close();
exit;
}
$stmt->bind_param("sssssd", $nama, $kategori, $status, $type, $geometry, $nilai);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Data berhasil disimpan']);
} else {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
$conn->close();
exit;
}
http_response_code(405);
echo json_encode(['status' => 'error', 'message' => 'Method tidak diizinkan']);
$conn->close();
?>
-72
View File
@@ -1,72 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$latitude = $_POST['latitude'] ?? '';
$longitude = $_POST['longitude'] ?? '';
$jenis_kerusakan = $_POST['jenis_kerusakan'] ?? '';
$deskripsi = $_POST['deskripsi'] ?? '';
$severity = $_POST['severity'] ?? 'sedang';
if (empty($latitude) || empty($longitude) || empty($jenis_kerusakan)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Latitude, longitude, dan jenis kerusakan wajib diisi']);
exit;
}
$gambar = null;
// Handle file upload
if (isset($_FILES['gambar']) && $_FILES['gambar']['error'] === UPLOAD_ERR_OK) {
$allowed = ['jpg', 'jpeg', 'png', 'gif'];
$filename = $_FILES['gambar']['name'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowed)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Format gambar hanya JPG, PNG, GIF']);
exit;
}
// Buat folder uploads jika belum ada
if (!is_dir('uploads')) {
mkdir('uploads', 0755, true);
}
// Generate nama file unik
$gambar = 'uploads/' . time() . '_' . basename($filename);
if (!move_uploaded_file($_FILES['gambar']['tmp_name'], $gambar)) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Gagal upload gambar']);
exit;
}
}
$stmt = $conn->prepare("INSERT INTO jalan_rusak (latitude, longitude, jenis_kerusakan, deskripsi, severity, gambar) VALUES (?, ?, ?, ?, ?, ?)");
if (!$stmt) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $conn->error]);
exit;
}
$stmt->bind_param("ddssss", $latitude, $longitude, $jenis_kerusakan, $deskripsi, $severity, $gambar);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Laporan jalan rusak berhasil disimpan', 'id' => $stmt->insert_id]);
} else {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
$conn->close();
exit;
}
http_response_code(405);
echo json_encode(['status' => 'error', 'message' => 'Method tidak diizinkan']);
$conn->close();
?>
-80
View File
@@ -1,80 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
function distanceMeters($lat1, $lng1, $lat2, $lng2) {
$earthRadius = 6371000;
$toRadians = function ($value) {
return $value * M_PI / 180;
};
$deltaLat = $toRadians($lat2 - $lat1);
$deltaLng = $toRadians($lng2 - $lng1);
$a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($toRadians($lat1)) * cos($toRadians($lat2)) * sin($deltaLng / 2) * sin($deltaLng / 2);
return 2 * $earthRadius * atan2(sqrt($a), sqrt(1 - $a));
}
function findNearestRumahIbadah($conn, $lat, $lng) {
$result = $conn->query("SELECT id, nama, latitude, longitude FROM rumah_ibadah ORDER BY created_at DESC");
if (!$result || $result->num_rows === 0) {
return null;
}
$nearest = null;
while ($row = $result->fetch_assoc()) {
$distance = distanceMeters($lat, $lng, (float)$row['latitude'], (float)$row['longitude']);
if ($nearest === null || $distance < $nearest['distance']) {
$nearest = [
'id' => (int)$row['id'],
'nama' => $row['nama'],
'distance' => $distance
];
}
}
return $nearest;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$namaKetuaKk = trim($_POST['nama_ketua_kk'] ?? '');
$jumlahAnggota = (int)($_POST['jumlah_anggota'] ?? 0);
$lat = $_POST['latitude'] ?? null;
$lng = $_POST['longitude'] ?? null;
$rumahIbadahId = $_POST['rumah_ibadah_id'] ?? null;
$rumahIbadahNama = trim($_POST['rumah_ibadah_nama'] ?? '');
$jarak = $_POST['jarak_ke_rumah_ibadah_m'] ?? null;
if ($namaKetuaKk === '' || $jumlahAnggota <= 0 || $lat === null || $lng === null) {
echo json_encode(['status' => 'error', 'message' => 'Data penduduk miskin tidak lengkap']);
$conn->close();
exit;
}
$lat = (float)$lat;
$lng = (float)$lng;
$nearest = findNearestRumahIbadah($conn, $lat, $lng);
if (!$nearest) {
echo json_encode(['status' => 'error', 'message' => 'Tambahkan rumah ibadah terlebih dahulu']);
$conn->close();
exit;
}
$jarak = $nearest['distance'];
$rumahIbadahId = $nearest['id'];
$rumahIbadahNama = $nearest['nama'];
$stmt = $conn->prepare("INSERT INTO penduduk_miskin (nama_ketua_kk, jumlah_anggota, latitude, longitude, rumah_ibadah_id, rumah_ibadah_nama, jarak_ke_rumah_ibadah_m) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("siddisd", $namaKetuaKk, $jumlahAnggota, $lat, $lng, $rumahIbadahId, $rumahIbadahNama, $jarak);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Penduduk miskin berhasil disimpan']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-35
View File
@@ -1,35 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nama = trim($_POST['nama'] ?? '');
$alamat = trim($_POST['alamat'] ?? '');
$pic = trim($_POST['pic'] ?? '');
$lat = $_POST['latitude'] ?? null;
$lng = $_POST['longitude'] ?? null;
$radius = $_POST['radius_m'] ?? 1000;
if ($nama === '' || $alamat === '' || $pic === '' || $lat === null || $lng === null) {
echo json_encode(['status' => 'error', 'message' => 'Data rumah ibadah tidak lengkap']);
$conn->close();
exit;
}
$lat = (float)$lat;
$lng = (float)$lng;
$radius = max(50, (int)$radius);
$stmt = $conn->prepare("INSERT INTO rumah_ibadah (nama, alamat, pic, latitude, longitude, radius_m) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("sssddi", $nama, $alamat, $pic, $lat, $lng, $radius);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Rumah ibadah berhasil disimpan']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
+7 -7
View File
@@ -41,19 +41,19 @@
<div class="test-item"> <div class="test-item">
<h4>Load Rumah Ibadah Data</h4> <h4>Load Rumah Ibadah Data</h4>
<button onclick="testLoadRumahIbadah()">GET /get_rumah_ibadah.php</button> <button onclick="testLoadRumahIbadah()">GET /rancangan_sistem/get_rumah_ibadah.php</button>
<div id="rumahIbadahResult"></div> <div id="rumahIbadahResult"></div>
</div> </div>
<div class="test-item"> <div class="test-item">
<h4>Load Penduduk Miskin Data</h4> <h4>Load Penduduk Miskin Data</h4>
<button onclick="testLoadPendudukMiskin()">GET /get_penduduk_miskin.php</button> <button onclick="testLoadPendudukMiskin()">GET /rancangan_sistem/get_penduduk_miskin.php</button>
<div id="pendudukMiskinResult"></div> <div id="pendudukMiskinResult"></div>
</div> </div>
<div class="test-item"> <div class="test-item">
<h4>Load Jalan Rusak Data</h4> <h4>Load Jalan Rusak Data</h4>
<button onclick="testLoadJalanRusak()">GET /get_jalan_rusak.php</button> <button onclick="testLoadJalanRusak()">GET /fitur_jalan_parsel/get_jalan_rusak.php</button>
<div id="jalanRusakResult"></div> <div id="jalanRusakResult"></div>
</div> </div>
</div> </div>
@@ -158,7 +158,7 @@ async function testDatabase() {
async function testLoadRumahIbadah() { async function testLoadRumahIbadah() {
try { try {
const response = await fetch('get_rumah_ibadah.php'); const response = await fetch('rancangan_sistem/get_rumah_ibadah.php');
const text = await response.text(); const text = await response.text();
const data = JSON.parse(text); const data = JSON.parse(text);
@@ -171,7 +171,7 @@ async function testLoadRumahIbadah() {
async function testLoadPendudukMiskin() { async function testLoadPendudukMiskin() {
try { try {
const response = await fetch('get_penduduk_miskin.php'); const response = await fetch('rancangan_sistem/get_penduduk_miskin.php');
const text = await response.text(); const text = await response.text();
const data = JSON.parse(text); const data = JSON.parse(text);
@@ -184,7 +184,7 @@ async function testLoadPendudukMiskin() {
async function testLoadJalanRusak() { async function testLoadJalanRusak() {
try { try {
const response = await fetch('get_jalan_rusak.php'); const response = await fetch('fitur_jalan_parsel/get_jalan_rusak.php');
const text = await response.text(); const text = await response.text();
const data = JSON.parse(text); const data = JSON.parse(text);
@@ -205,7 +205,7 @@ async function testSaveRumahIbadah() {
formData.append('longitude', document.getElementById('lngRumah').value); formData.append('longitude', document.getElementById('lngRumah').value);
formData.append('radius_m', document.getElementById('radiusRumah').value); formData.append('radius_m', document.getElementById('radiusRumah').value);
const response = await fetch('save_rumah_ibadah.php', { const response = await fetch('rancangan_sistem/save_rumah_ibadah.php', {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
-45
View File
@@ -1,45 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
$nama = trim($_POST['nama'] ?? '');
$kategori = trim($_POST['kategori'] ?? '');
if ($kategori === 'Parsil Tanah') {
$kategori = 'Tanah';
}
$status = trim($_POST['status'] ?? '');
$type = trim($_POST['type'] ?? '');
$geometry = $_POST['geometry'] ?? '';
$nilai = (float)($_POST['nilai'] ?? 0);
if ($id <= 0 || $nama === '' || $kategori === '' || $status === '' || $type === '' || $geometry === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Data fitur tidak lengkap']);
$conn->close();
exit;
}
$stmt = $conn->prepare("UPDATE spatial_features SET nama_objek = ?, kategori = ?, status_objek = ?, type = ?, geometry_data = ?, nilai_ukur = ? WHERE id = ?");
if (!$stmt) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $conn->error]);
$conn->close();
exit;
}
$stmt->bind_param("sssssdi", $nama, $kategori, $status, $type, $geometry, $nilai, $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Fitur berhasil diperbarui']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-82
View File
@@ -1,82 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
function distanceMeters($lat1, $lng1, $lat2, $lng2) {
$earthRadius = 6371000;
$toRadians = function ($value) {
return $value * M_PI / 180;
};
$deltaLat = $toRadians($lat2 - $lat1);
$deltaLng = $toRadians($lng2 - $lng1);
$a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($toRadians($lat1)) * cos($toRadians($lat2)) * sin($deltaLng / 2) * sin($deltaLng / 2);
return 2 * $earthRadius * atan2(sqrt($a), sqrt(1 - $a));
}
function findNearestRumahIbadah($conn, $lat, $lng) {
$result = $conn->query("SELECT id, nama, latitude, longitude FROM rumah_ibadah ORDER BY created_at DESC");
if (!$result || $result->num_rows === 0) {
return null;
}
$nearest = null;
while ($row = $result->fetch_assoc()) {
$distance = distanceMeters($lat, $lng, (float)$row['latitude'], (float)$row['longitude']);
if ($nearest === null || $distance < $nearest['distance']) {
$nearest = [
'id' => (int)$row['id'],
'nama' => $row['nama'],
'distance' => $distance
];
}
}
return $nearest;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
$namaKetuaKk = trim($_POST['nama_ketua_kk'] ?? '');
$jumlahAnggota = (int)($_POST['jumlah_anggota'] ?? 0);
$lat = $_POST['latitude'] ?? null;
$lng = $_POST['longitude'] ?? null;
$rumahIbadahId = $_POST['rumah_ibadah_id'] ?? null;
$rumahIbadahNama = trim($_POST['rumah_ibadah_nama'] ?? '');
$jarak = $_POST['jarak_ke_rumah_ibadah_m'] ?? null;
if ($id <= 0 || $namaKetuaKk === '' || $jumlahAnggota <= 0 || $lat === null || $lng === null) {
echo json_encode(['status' => 'error', 'message' => 'Data penduduk miskin tidak lengkap']);
$conn->close();
exit;
}
$lat = (float)$lat;
$lng = (float)$lng;
$nearest = findNearestRumahIbadah($conn, $lat, $lng);
if (!$nearest) {
echo json_encode(['status' => 'error', 'message' => 'Tambahkan rumah ibadah terlebih dahulu']);
$conn->close();
exit;
}
$jarak = $nearest['distance'];
$rumahIbadahId = $nearest['id'];
$rumahIbadahNama = $nearest['nama'];
$stmt = $conn->prepare("UPDATE penduduk_miskin SET nama_ketua_kk = ?, jumlah_anggota = ?, latitude = ?, longitude = ?, rumah_ibadah_id = ?, rumah_ibadah_nama = ?, jarak_ke_rumah_ibadah_m = ? WHERE id = ?");
$stmt->bind_param("siddisdi", $namaKetuaKk, $jumlahAnggota, $lat, $lng, $rumahIbadahId, $rumahIbadahNama, $jarak, $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Data penduduk miskin berhasil diperbarui']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>
-36
View File
@@ -1,36 +0,0 @@
<?php
header('Content-Type: application/json');
include 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
$nama = trim($_POST['nama'] ?? '');
$alamat = trim($_POST['alamat'] ?? '');
$pic = trim($_POST['pic'] ?? '');
$lat = $_POST['latitude'] ?? null;
$lng = $_POST['longitude'] ?? null;
$radius = $_POST['radius_m'] ?? 1000;
if ($id <= 0 || $nama === '' || $alamat === '' || $pic === '' || $lat === null || $lng === null) {
echo json_encode(['status' => 'error', 'message' => 'Data rumah ibadah tidak lengkap']);
$conn->close();
exit;
}
$lat = (float)$lat;
$lng = (float)$lng;
$radius = max(50, (int)$radius);
$stmt = $conn->prepare("UPDATE rumah_ibadah SET nama = ?, alamat = ?, pic = ?, latitude = ?, longitude = ?, radius_m = ? WHERE id = ?");
$stmt->bind_param("sssddii", $nama, $alamat, $pic, $lat, $lng, $radius, $id);
if ($stmt->execute()) {
echo json_encode(['status' => 'success', 'message' => 'Rumah ibadah berhasil diperbarui']);
} else {
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
}
$stmt->close();
}
$conn->close();
?>