Files
Athallah Ghathfan Aqila 6215b4367a Initial commit — WebGIS UAS GeoMiskin
Sistem WebGIS analisis sebaran penduduk miskin dan jangkauan rumah ibadah.
Fitur: peta interaktif Leaflet.js, CRUD rumah ibadah & penduduk miskin,
auto-kategorisasi haversine, heatmap, export PDF/CSV, dashboard analitik,
manajemen pengguna (superadmin/admin), login sistem.

Teknologi: PHP, MySQL, Leaflet.js, OpenStreetMap, Nominatim Geocoding, mPDF.

Catatan: jalankan `composer install` di folder uas/ untuk install dependencies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 13:31:33 +07:00

93 lines
4.2 KiB
PHP

<?php
header('Content-Type: application/json');
include '../koneksi.php';
include '../auth.php';
requireLogin();
$kk_nama = esc($conn, $_POST['kk_nama'] ?? '');
$nik = esc($conn, $_POST['nik'] ?? '');
$alamat = esc($conn, $_POST['alamat'] ?? '');
$kecamatan = esc($conn, $_POST['kecamatan'] ?? '');
$kelurahan = esc($conn, $_POST['kelurahan'] ?? '');
$lat = (float)($_POST['lat'] ?? 0);
$lng = (float)($_POST['lng'] ?? 0);
$jumlah = max(1, (int)($_POST['jumlah_anggota'] ?? 1));
$status_allowed = ['belum_dibantu','sudah_dibantu','menunggu_verifikasi'];
$status = in_array($_POST['status_bantuan'] ?? '', $status_allowed) ? $_POST['status_bantuan'] : 'belum_dibantu';
$jenis_bantuan = esc($conn, $_POST['jenis_bantuan'] ?? '');
$tanggal = $_POST['tanggal_bantuan'] ?? '';
$tanggal_sql = ($tanggal && preg_match('/^\d{4}-\d{2}-\d{2}$/', $tanggal)) ? "'$tanggal'" : 'NULL';
if (!$kk_nama || !$alamat || !$lat || !$lng) {
echo json_encode(['status' => 'error', 'message' => 'Data tidak lengkap.']);
exit;
}
// --- Find nearest rumah ibadah ---
$ibadah_res = mysqli_query($conn, "SELECT id, lat, lng, radius FROM rumah_ibadah");
$nearest_id = null;
$nearest_dist = PHP_FLOAT_MAX;
while ($row = mysqli_fetch_assoc($ibadah_res)) {
$d = haversine($lat, $lng, (float)$row['lat'], (float)$row['lng']);
if ($d <= (float)$row['radius'] && $d < $nearest_dist) {
$nearest_dist = $d;
$nearest_id = $row['id'];
}
}
// If no ibadah covers, find nearest anyway
if (!$nearest_id) {
mysqli_data_seek($ibadah_res, 0);
while ($row = mysqli_fetch_assoc($ibadah_res)) {
$d = haversine($lat, $lng, (float)$row['lat'], (float)$row['lng']);
if ($d < $nearest_dist) { $nearest_dist = $d; $nearest_id = $row['id']; }
}
}
$jarak = $nearest_id ? round($nearest_dist, 2) : 'NULL';
$ibadah_id_sql = $nearest_id ? $nearest_id : 'NULL';
$jarak_sql = is_numeric($jarak) ? $jarak : 'NULL';
// --- Handle file upload ---
$bukti_file = '';
if (!empty($_FILES['bukti_file']['name']) && $_FILES['bukti_file']['error'] === UPLOAD_ERR_OK) {
$ext = strtolower(pathinfo($_FILES['bukti_file']['name'], PATHINFO_EXTENSION));
$allowed = ['jpg','jpeg','png','webp','pdf','doc','docx'];
if (in_array($ext, $allowed) && $_FILES['bukti_file']['size'] <= 5 * 1024 * 1024) {
$dir = __DIR__ . '/../uploads/bukti/';
if (!is_dir($dir)) mkdir($dir, 0755, true);
$fname = 'bukti_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
if (move_uploaded_file($_FILES['bukti_file']['tmp_name'], $dir . $fname)) {
$bukti_file = $fname;
}
}
}
$bukti_sql = $bukti_file ? "'".esc($conn,$bukti_file)."'" : 'NULL';
// --- Insert penduduk ---
$q = "INSERT INTO penduduk_miskin (kk_nama,nik,alamat,kecamatan,kelurahan,lat,lng,jumlah_anggota,rumah_ibadah_id,jarak_meter,status_bantuan,jenis_bantuan,tanggal_bantuan,bukti_file)
VALUES ('$kk_nama','$nik','$alamat','$kecamatan','$kelurahan',$lat,$lng,$jumlah,$ibadah_id_sql,$jarak_sql,'$status','$jenis_bantuan',$tanggal_sql,$bukti_sql)";
if (!mysqli_query($conn, $q)) {
echo json_encode(['status' => 'error', 'message' => mysqli_error($conn)]);
exit;
}
$pid = mysqli_insert_id($conn);
// --- Insert anggota keluarga ---
$anggota = json_decode($_POST['anggota'] ?? '[]', true) ?: [];
foreach ($anggota as $a) {
if (empty($a['nama'])) continue;
$an = esc($conn,$a['nama']); $ah = esc($conn,$a['hubungan'] ?? '');
$au = (int)($a['umur'] ?? 0); $ap = esc($conn,$a['pekerjaan'] ?? ''); $ak = esc($conn,$a['keterangan'] ?? '');
mysqli_query($conn, "INSERT INTO anggota_keluarga (penduduk_id,nama,hubungan,umur,pekerjaan,keterangan) VALUES ($pid,'$an','$ah',$au,'$ap','$ak')");
}
echo json_encode(['status' => 'success', 'id' => $pid, 'rumah_ibadah_id' => $nearest_id, 'jarak_meter' => $jarak]);
function haversine($lat1, $lon1, $lat2, $lon2) {
$R = 6371000;
$d1 = deg2rad($lat1 - $lat2); $d2 = deg2rad($lon1 - $lon2);
$a = sin($d1/2)**2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($d2/2)**2;
return $R * 2 * atan2(sqrt($a), sqrt(1-$a));
}