fitur kelola bantuan melalui rumah ibadah
This commit is contained in:
@@ -0,0 +1,385 @@
|
||||
# 📍 PANDUAN FITUR GIS PONTIANAK
|
||||
|
||||
## Setup Awal
|
||||
|
||||
### 1. Inisialisasi Database
|
||||
|
||||
```bash
|
||||
# Buka di browser:
|
||||
http://localhost/web-gis/create_tables.php
|
||||
```
|
||||
|
||||
**Respons berhasil:**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "Tabel berhasil dibuat atau sudah ada"
|
||||
}
|
||||
```
|
||||
|
||||
Ini akan membuat 3 tabel baru:
|
||||
|
||||
- `rumah_ibadah` - Lokasi tempat ibadah
|
||||
- `penduduk_miskin` - Lokasi keluarga kurang mampu
|
||||
- `jalan_rusak` - Laporan jalan rusak
|
||||
|
||||
---
|
||||
|
||||
## Fitur 1: RUMAH IBADAH (Tempat Ibadah)
|
||||
|
||||
### Cara Menggunakan:
|
||||
|
||||
**Step 1:** Buka GIS Interface
|
||||
|
||||
```
|
||||
http://localhost/web-gis/index.html
|
||||
```
|
||||
|
||||
**Step 2:** Klik tombol "Rumah Ibadah" di toolbar
|
||||
|
||||
- Ikon: 🏛️ (bangunan dengan tanda plus)
|
||||
- Di toolbar utama sebelah atas map
|
||||
|
||||
**Step 3:** Klik di mana saja di peta
|
||||
|
||||
- Status akan berubah: "Klik Peta untuk menambah lokasi..."
|
||||
- Modal dialog akan muncul
|
||||
|
||||
**Step 4:** Isi form:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ INPUT RUMAH IBADAH │
|
||||
├─────────────────────────────────────┤
|
||||
│ Nama : [Masjid Al-Nur] │
|
||||
│ Alamat : [Auto-fill] │ ← Otomatis dari koordinat
|
||||
│ PIC (Nama) : [Pengurus] │
|
||||
│ Radius Pencarian: [1000] meter │ ← Geser slider
|
||||
│ Koordinat : -0.1234, 109.3456 │
|
||||
│ │
|
||||
│ [SIMPAN] [BATAL] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Field Penjelasan:**
|
||||
|
||||
- **Nama:** Nama tempat ibadah (Masjid/Gereja/dll)
|
||||
- **Alamat:** Otomatis terisi pakai Nominatim (Reverse Geocoding)
|
||||
- Tunggu pesan "Mencari alamat..." hingga selesai
|
||||
- **PIC:** Nama Pengurus/Koordinator
|
||||
- **Radius:** Jarak pencarian untuk keluarga miskin sekitar (default 1000m)
|
||||
|
||||
**Step 5:** Klik "SIMPAN"
|
||||
|
||||
- Marker teal + lingkaran akan muncul di peta
|
||||
- Data tersimpan di database
|
||||
|
||||
### Interaksi Lanjutan:
|
||||
|
||||
**Edit:**
|
||||
|
||||
1. Klik marker di peta
|
||||
2. Popup muncul → Klik "Edit"
|
||||
3. Modal akan terbuka dengan data lama
|
||||
4. Ubah dan klik "Simpan"
|
||||
|
||||
**Hapus:**
|
||||
|
||||
1. Klik marker
|
||||
2. Popup → Klik "Hapus"
|
||||
3. Konfirmasi → Data terhapus
|
||||
|
||||
**Cari:**
|
||||
|
||||
- Gunakan Registry Drawer (kanan peta)
|
||||
- Filter: Input Type = "Rumah Ibadah"
|
||||
- Cari nama atau ketik untuk filter
|
||||
|
||||
---
|
||||
|
||||
## Fitur 2: PENDUDUK MISKIN (Keluarga Kurang Mampu)
|
||||
|
||||
### Cara Menggunakan:
|
||||
|
||||
**Step 1:** Klik tombol "Penduduk Miskin" di toolbar
|
||||
|
||||
- Ikon: 👤 (orang dengan tanda plus)
|
||||
|
||||
**Step 2:** Klik di peta untuk lokasi keluarga miskin
|
||||
|
||||
**Step 3:** Isi form:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ INPUT PENDUDUK MISKIN │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ Nama Ketua KK : [Nama Kepala Keluarga]│
|
||||
│ Jumlah Anggota : [5] │
|
||||
│ Rumah Ibadah Terdekat: [OTOMATIS] │
|
||||
│ Nama : Masjid Al-Nur │ ← Sistem mencari
|
||||
│ Jarak : 234 meter │ otomatis
|
||||
│ Koordinat : -0.1234, 109.3456 │
|
||||
│ │
|
||||
│ [SIMPAN] [BATAL] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Field Penjelasan:**
|
||||
|
||||
- **Nama Ketua KK:** Nama kepala keluarga yang bertanggung jawab
|
||||
- **Jumlah Anggota:** Total orang dalam keluarga termasuk ketua
|
||||
- **Rumah Ibadah Terdekat:** Sistem otomatis menemukan tempat ibadah terdekat
|
||||
- Nama dan jarak ditampilkan (berdasarkan radius yang Anda set di rumah ibadah)
|
||||
- TIDAK perlu isi manual
|
||||
|
||||
**Step 4:** Klik "SIMPAN"
|
||||
|
||||
- Marker merah akan muncul
|
||||
- Data tersimpan beserta referensi rumah ibadah terdekat
|
||||
|
||||
### Fitur Khusus: Pencarian Miskin Sekitar Rumah Ibadah
|
||||
|
||||
**Gunakan tombol di popup Rumah Ibadah:**
|
||||
|
||||
1. Klik marker Rumah Ibadah di peta
|
||||
2. Di popup klik: **"Cari Miskin"**
|
||||
3. Semua keluarga miskin dalam radius akan ter-zoom
|
||||
4. Map akan fit ke cluster keluarga miskin
|
||||
|
||||
---
|
||||
|
||||
## Fitur 3: CHOROPLETH KECAMATAN (Peta Populasi)
|
||||
|
||||
### Cara Menggunakan:
|
||||
|
||||
**Step 1:** Klik tombol "Choropleth" di toolbar
|
||||
|
||||
- Ikon: 🗺️ (peta)
|
||||
|
||||
**Step 2:** Peta akan berubah
|
||||
|
||||
- Menampilkan 6 kecamatan Pontianak
|
||||
- Warna berbeda sesuai populasi
|
||||
|
||||
**Gradasi Warna:**
|
||||
|
||||
```
|
||||
🔴 Merah Tua = Populasi > 120,000 jiwa
|
||||
🟥 Merah Terang = Populasi > 100,000 jiwa
|
||||
🟨 Merah Muda = Populasi > 80,000 jiwa
|
||||
🟧 Merah Pucat = Populasi ≤ 80,000 jiwa
|
||||
```
|
||||
|
||||
**Step 3:** Klik salah satu kecamatan
|
||||
|
||||
- Panel di kanan bawah muncul:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ Choropleth Kecamatan Pontianak │
|
||||
├──────────────────────────────────┤
|
||||
│ PONTIANAK BARAT │
|
||||
│ 148,800 jiwa │
|
||||
│ │
|
||||
│ Kepadatan: 2,500 jiwa/km² │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Data Populasi (BPS 2025):**
|
||||
|
||||
| # | Kecamatan | Populasi | Warna |
|
||||
| --- | ------------------ | -------- | ----- |
|
||||
| 1 | Pontianak Barat | 148,800 | 🔴 |
|
||||
| 2 | Pontianak Selatan | 133,600 | 🔴 |
|
||||
| 3 | Pontianak Utara | 129,200 | 🔴 |
|
||||
| 4 | Pontianak Timur | 121,500 | 🔴 |
|
||||
| 5 | Pontianak Kota | 98,500 | 🟥 |
|
||||
| 6 | Pontianak Tenggara | 52,900 | 🟧 |
|
||||
|
||||
**Fitur Interaksi:**
|
||||
|
||||
- **Hover:** Kecamatan akan highlight
|
||||
- **Klik:** Info populasi muncul di panel
|
||||
- **Keluar Mode:** Klik tombol lain atau click tombol Choropleth lagi
|
||||
|
||||
---
|
||||
|
||||
## Layer Control (Kontrol Visibilitas)
|
||||
|
||||
### Tombol Layer (atas kiri map):
|
||||
|
||||
Klik ikon **☰** untuk membuka layer control.
|
||||
|
||||
```
|
||||
✓ Choropleth Kecamatan
|
||||
✓ Rumah Ibadah
|
||||
✓ Penduduk Miskin
|
||||
✓ Jalan Rusak
|
||||
✓ Lokasi SPBU
|
||||
... (layer lainnya)
|
||||
```
|
||||
|
||||
**Toggle on/off:**
|
||||
|
||||
- Centang untuk tampilkan layer
|
||||
- Uncheck untuk sembunyikan
|
||||
|
||||
**Catatan:** Saat aktif mode Choropleth, layer lain otomatis disembunyikan untuk fokus pada peta kecamatan.
|
||||
|
||||
---
|
||||
|
||||
## Registry / Pencarian
|
||||
|
||||
### Buka Registry Drawer:
|
||||
|
||||
Klik tombol **📋** di toolbar atau panel kanan.
|
||||
|
||||
### Cara Mencari:
|
||||
|
||||
**1. Filter by Type (Dropdown atas):**
|
||||
|
||||
```
|
||||
Input Type:
|
||||
▼ Semua
|
||||
□ Point
|
||||
□ Polyline
|
||||
□ Polygon
|
||||
□ Rumah Ibadah ← Pilih ini
|
||||
□ Penduduk Miskin ← atau ini
|
||||
□ Jalan Rusak
|
||||
```
|
||||
|
||||
**2. Filter by Registry (Dropdown bawah):**
|
||||
|
||||
```
|
||||
Registry Type:
|
||||
▼ Semua
|
||||
□ Jalan Nasional
|
||||
□ Parkir
|
||||
□ Rumah Ibadah
|
||||
□ Penduduk Miskin
|
||||
```
|
||||
|
||||
**3. Cari (Kolom input):**
|
||||
|
||||
```
|
||||
Cari nama: [Masjid] 🔍
|
||||
|
||||
Hasil:
|
||||
┌─────────────────────────────┐
|
||||
│ ✓ Masjid Al-Nur │
|
||||
│ Rumah Ibadah │
|
||||
│ -0.1234, 109.3456 │
|
||||
├─────────────────────────────┤
|
||||
│ ✓ Masjid Besar Pontianak │
|
||||
│ Rumah Ibadah │
|
||||
│ -0.1245, 109.3467 │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
**Klik hasil → Map akan:**
|
||||
|
||||
- Zoom ke lokasi
|
||||
- Buka popup
|
||||
- Highlight marker
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### ❌ Tombol tidak muncul
|
||||
|
||||
**Solusi:**
|
||||
|
||||
- Refresh browser (Ctrl+F5)
|
||||
- Clear cache
|
||||
- Cek console (F12) untuk error
|
||||
|
||||
### ❌ Alamat tidak terisi (Reverse Geocode gagal)
|
||||
|
||||
**Penyebab:** Tidak ada koneksi internet atau Nominatim API timeout
|
||||
**Solusi:**
|
||||
|
||||
- Pastikan internet terhubung
|
||||
- Coba refresh modal
|
||||
- Manual isi alamat
|
||||
|
||||
### ❌ Rumah Ibadah tidak ditemukan saat input miskin
|
||||
|
||||
**Penyebab:** Belum ada data rumah ibadah, atau lokasi terlalu jauh
|
||||
**Solusi:**
|
||||
|
||||
- Tambahkan rumah ibadah terlebih dahulu di mode Rumah Ibadah
|
||||
- Pastikan radius rumah ibadah cukup besar
|
||||
|
||||
### ❌ Choropleth tidak tampil
|
||||
|
||||
**Penyebab:** File GeoJSON tidak ditemukan
|
||||
**Solusi:**
|
||||
|
||||
- Cek file ada di: `data/pontianak-kecamatan.geojson`
|
||||
- Cek console untuk error message
|
||||
|
||||
### ❌ Database error
|
||||
|
||||
**Solusi:**
|
||||
|
||||
- Jalankan ulang `create_tables.php`
|
||||
- Cek koneksi database di `db_config.php`
|
||||
|
||||
---
|
||||
|
||||
## Tips & Trik
|
||||
|
||||
### 💡 Shortcut
|
||||
|
||||
- **Double-click** marker untuk langsung edit
|
||||
- **Scroll zoom** di map untuk zoom in/out
|
||||
- **Drag** untuk geser peta
|
||||
- **Ctrl+A** di search untuk select all results
|
||||
|
||||
### 📊 Export Data
|
||||
|
||||
Semua data tersimpan di database MySQL. Untuk export:
|
||||
|
||||
```sql
|
||||
SELECT * FROM rumah_ibadah;
|
||||
SELECT * FROM penduduk_miskin;
|
||||
```
|
||||
|
||||
### 🎨 Customize Warna
|
||||
|
||||
Edit di `index.html` function:
|
||||
|
||||
- `getPopulationFill()` - Ubah warna choropleth
|
||||
- `createRumahIbadahIcon()` - Ubah marker rumah ibadah
|
||||
- `createPendudukMiskinIcon()` - Ubah marker miskin
|
||||
|
||||
---
|
||||
|
||||
## File Penting
|
||||
|
||||
```
|
||||
web-gis/
|
||||
├── index.html ← Main GIS Interface
|
||||
├── create_tables.php ← Init database
|
||||
├── db_config.php ← Database config
|
||||
│
|
||||
├── api/
|
||||
│ ├── save_rumah_ibadah.php
|
||||
│ ├── get_rumah_ibadah.php
|
||||
│ ├── delete_rumah_ibadah.php
|
||||
│ ├── save_penduduk_miskin.php
|
||||
│ ├── get_penduduk_miskin.php
|
||||
│ └── delete_penduduk_miskin.php
|
||||
│
|
||||
└── data/
|
||||
├── pontianak-kecamatan.geojson ← Choropleth data
|
||||
└── Export_Output_2.json ← Road network data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Versi:** 2025-04-20
|
||||
**Status:** Production Ready ✅
|
||||
+46
-7
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
// Script untuk membuat tabel jalan_rusak jika belum ada
|
||||
// Script untuk membuat tabel utama jika belum ada
|
||||
include 'db_config.php';
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS jalan_rusak (
|
||||
$statements = [
|
||||
"CREATE TABLE IF NOT EXISTS jalan_rusak (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
latitude DECIMAL(10, 8) NOT NULL,
|
||||
longitude DECIMAL(11, 8) NOT NULL,
|
||||
@@ -12,13 +13,51 @@ $sql = "CREATE TABLE IF NOT EXISTS jalan_rusak (
|
||||
gambar VARCHAR(255),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_coords (latitude, longitude)
|
||||
)";
|
||||
)",
|
||||
"CREATE TABLE IF NOT EXISTS rumah_ibadah (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama VARCHAR(255) NOT NULL,
|
||||
alamat TEXT NOT NULL,
|
||||
pic VARCHAR(255) NOT NULL,
|
||||
latitude DECIMAL(10, 8) NOT NULL,
|
||||
longitude DECIMAL(11, 8) NOT NULL,
|
||||
radius_m INT NOT NULL DEFAULT 1000,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_rumah_ibadah_coords (latitude, longitude)
|
||||
)",
|
||||
"CREATE TABLE IF NOT EXISTS penduduk_miskin (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nama_ketua_kk VARCHAR(255) NOT NULL,
|
||||
jumlah_anggota INT NOT NULL,
|
||||
latitude DECIMAL(10, 8) NOT NULL,
|
||||
longitude DECIMAL(11, 8) NOT NULL,
|
||||
rumah_ibadah_id INT DEFAULT NULL,
|
||||
rumah_ibadah_nama VARCHAR(255) DEFAULT NULL,
|
||||
jarak_ke_rumah_ibadah_m DECIMAL(10, 2) DEFAULT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_penduduk_coords (latitude, longitude),
|
||||
INDEX idx_penduduk_rumah_ibadah (rumah_ibadah_id)
|
||||
)"
|
||||
];
|
||||
|
||||
if ($conn->query($sql) === TRUE) {
|
||||
echo json_encode(['status' => 'success', 'message' => 'Tabel jalan_rusak berhasil dibuat atau sudah ada']);
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => $conn->error]);
|
||||
foreach ($statements as $sql) {
|
||||
if ($conn->query($sql) !== TRUE) {
|
||||
echo json_encode(['status' => 'error', 'message' => $conn->error]);
|
||||
$conn->close();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$alterStatements = [
|
||||
"ALTER TABLE penduduk_miskin ADD COLUMN bantuan_status VARCHAR(20) NOT NULL DEFAULT 'belum' AFTER jarak_ke_rumah_ibadah_m",
|
||||
"ALTER TABLE penduduk_miskin ADD COLUMN bantuan_catatan TEXT DEFAULT NULL AFTER bantuan_status",
|
||||
"ALTER TABLE penduduk_miskin ADD COLUMN bantuan_updated_at TIMESTAMP NULL DEFAULT NULL AFTER bantuan_catatan"
|
||||
];
|
||||
|
||||
foreach ($alterStatements as $alterSql) {
|
||||
$conn->query($alterSql);
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'success', 'message' => 'Tabel berhasil dibuat atau sudah ada']);
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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();
|
||||
?>
|
||||
+1381
-26
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,278 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test GIS Features</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: system-ui, sans-serif; background: #f1f5f9; padding: 20px; }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.test-section { background: white; margin-bottom: 20px; padding: 20px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
||||
h2 { color: #1e293b; margin-bottom: 15px; border-bottom: 2px solid #3b82f6; padding-bottom: 10px; }
|
||||
.test-item { margin: 15px 0; padding: 15px; background: #f8fafc; border-left: 4px solid #3b82f6; border-radius: 4px; }
|
||||
.status { font-weight: bold; padding: 5px 10px; border-radius: 4px; display: inline-block; margin-top: 10px; }
|
||||
.success { background: #dcfce7; color: #166534; }
|
||||
.error { background: #fee2e2; color: #991b1b; }
|
||||
.info { background: #dbeafe; color: #1e40af; }
|
||||
button { background: #3b82f6; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-weight: bold; margin: 5px; }
|
||||
button:hover { background: #2563eb; }
|
||||
.response { background: #1e293b; color: #10b981; padding: 15px; border-radius: 4px; font-family: monospace; font-size: 12px; margin-top: 10px; max-height: 300px; overflow-y: auto; white-space: pre-wrap; word-wrap: break-word; }
|
||||
input { padding: 8px; margin: 5px; border: 1px solid #cbd5e1; border-radius: 4px; width: 100%; max-width: 400px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1 style="margin-bottom: 30px; color: #1e293b;">🔍 GIS Features Debug & Test</h1>
|
||||
|
||||
<!-- Test 1: Database -->
|
||||
<div class="test-section">
|
||||
<h2>📊 Test 1: Database Connection</h2>
|
||||
<div class="test-item">
|
||||
<button onclick="testDatabase()">Test Database Connection</button>
|
||||
<div id="dbResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test 2: PHP Endpoints -->
|
||||
<div class="test-section">
|
||||
<h2>🔗 Test 2: Fetch PHP Endpoints</h2>
|
||||
|
||||
<div class="test-item">
|
||||
<h4>Load Rumah Ibadah Data</h4>
|
||||
<button onclick="testLoadRumahIbadah()">GET /get_rumah_ibadah.php</button>
|
||||
<div id="rumahIbadahResult"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-item">
|
||||
<h4>Load Penduduk Miskin Data</h4>
|
||||
<button onclick="testLoadPendudukMiskin()">GET /get_penduduk_miskin.php</button>
|
||||
<div id="pendudukMiskinResult"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-item">
|
||||
<h4>Load Jalan Rusak Data</h4>
|
||||
<button onclick="testLoadJalanRusak()">GET /get_jalan_rusak.php</button>
|
||||
<div id="jalanRusakResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test 3: Save Operations -->
|
||||
<div class="test-section">
|
||||
<h2>💾 Test 3: Save Operations</h2>
|
||||
|
||||
<div class="test-item">
|
||||
<h4>Test Save Rumah Ibadah</h4>
|
||||
<input type="text" id="namaRumah" placeholder="Nama Rumah Ibadah" value="Test Masjid">
|
||||
<input type="text" id="alamatRumah" placeholder="Alamat" value="Jl. Test No. 1">
|
||||
<input type="text" id="picRumah" placeholder="Nama PIC" value="Test PIC">
|
||||
<input type="number" id="latRumah" placeholder="Latitude" value="-0.012345" step="0.000001">
|
||||
<input type="number" id="lngRumah" placeholder="Longitude" value="109.345678" step="0.000001">
|
||||
<input type="number" id="radiusRumah" placeholder="Radius (m)" value="1000">
|
||||
<button onclick="testSaveRumahIbadah()">Save Test Rumah Ibadah</button>
|
||||
<div id="saveRumahResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test 4: DOM Elements -->
|
||||
<div class="test-section">
|
||||
<h2>🎨 Test 4: DOM Elements Check</h2>
|
||||
|
||||
<div class="test-item">
|
||||
<button onclick="testDOMElements()">Check HTML Elements</button>
|
||||
<div id="domResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test 5: Console Monitoring -->
|
||||
<div class="test-section">
|
||||
<h2>📝 Test 5: Event Listener Test</h2>
|
||||
|
||||
<div class="test-item">
|
||||
<h4>Click Buttons and Check Console</h4>
|
||||
<p>Tombol di bawah akan log ke console jika event listener berfungsi:</p>
|
||||
<button id="testBtnRumahIbadah" onclick="console.log('✓ Rumah Ibadah button clicked')">Test: Rumah Ibadah</button>
|
||||
<button id="testBtnPendudukMiskin" onclick="console.log('✓ Penduduk Miskin button clicked')">Test: Penduduk Miskin</button>
|
||||
<button id="testBtnChoropleth" onclick="console.log('✓ Choropleth button clicked')">Test: Choropleth</button>
|
||||
<p style="margin-top: 10px; color: #666; font-size: 12px;">✓ F12 → Console untuk lihat hasil</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary -->
|
||||
<div class="test-section" style="background: #f0fdf4; border: 2px solid #22c55e;">
|
||||
<h2 style="border-bottom-color: #22c55e;">✅ Summary</h2>
|
||||
<div id="summary">Jalankan semua test di atas untuk diagnosis lengkap.</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let testResults = {};
|
||||
|
||||
function setResult(id, title, status, message, response = '') {
|
||||
const resultDiv = document.getElementById(id);
|
||||
let html = `<div class="status ${status}">${status.toUpperCase()}</div>`;
|
||||
html += `<div style="margin-top: 10px;"><strong>${title}</strong></div>`;
|
||||
html += `<div style="margin-top: 5px; color: #666;">${message}</div>`;
|
||||
if (response) {
|
||||
html += `<div class="response">${response}</div>`;
|
||||
}
|
||||
resultDiv.innerHTML = html;
|
||||
|
||||
testResults[id] = status;
|
||||
updateSummary();
|
||||
}
|
||||
|
||||
function updateSummary() {
|
||||
const summary = document.getElementById('summary');
|
||||
const results = Object.values(testResults);
|
||||
const successCount = results.filter(r => r === 'success').length;
|
||||
const errorCount = results.filter(r => r === 'error').length;
|
||||
|
||||
let html = `<p><strong>Results:</strong> ✅ ${successCount} passed | ❌ ${errorCount} failed | Total: ${results.length}</p>`;
|
||||
|
||||
if (errorCount > 0) {
|
||||
html += `<p style="color: #991b1b; margin-top: 10px;">⚠️ Ada ${errorCount} test yang gagal. Cek detail di atas.</p>`;
|
||||
} else if (successCount === results.length && results.length > 0) {
|
||||
html += `<p style="color: #166534; margin-top: 10px;">✅ Semua test berhasil! Fitur seharusnya berfungsi.</p>`;
|
||||
}
|
||||
|
||||
summary.innerHTML = html;
|
||||
}
|
||||
|
||||
async function testDatabase() {
|
||||
try {
|
||||
const response = await fetch('create_tables.php', { method: 'GET' });
|
||||
const text = await response.text();
|
||||
|
||||
if (text.includes('success')) {
|
||||
setResult('dbResult', 'Database & Tables', 'success', 'Database connection OK & tables exist', text.substring(0, 500));
|
||||
} else {
|
||||
setResult('dbResult', 'Database & Tables', 'error', 'Response tidak mengindikasikan success', text.substring(0, 500));
|
||||
}
|
||||
} catch (error) {
|
||||
setResult('dbResult', 'Database & Tables', 'error', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function testLoadRumahIbadah() {
|
||||
try {
|
||||
const response = await fetch('get_rumah_ibadah.php');
|
||||
const text = await response.text();
|
||||
const data = JSON.parse(text);
|
||||
|
||||
setResult('rumahIbadahResult', 'Load Rumah Ibadah', 'success',
|
||||
`Loaded ${data.length} records`, JSON.stringify(data, null, 2).substring(0, 1000));
|
||||
} catch (error) {
|
||||
setResult('rumahIbadahResult', 'Load Rumah Ibadah', 'error', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function testLoadPendudukMiskin() {
|
||||
try {
|
||||
const response = await fetch('get_penduduk_miskin.php');
|
||||
const text = await response.text();
|
||||
const data = JSON.parse(text);
|
||||
|
||||
setResult('pendudukMiskinResult', 'Load Penduduk Miskin', 'success',
|
||||
`Loaded ${data.length} records`, JSON.stringify(data, null, 2).substring(0, 1000));
|
||||
} catch (error) {
|
||||
setResult('pendudukMiskinResult', 'Load Penduduk Miskin', 'error', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function testLoadJalanRusak() {
|
||||
try {
|
||||
const response = await fetch('get_jalan_rusak.php');
|
||||
const text = await response.text();
|
||||
const data = JSON.parse(text);
|
||||
|
||||
setResult('jalanRusakResult', 'Load Jalan Rusak', 'success',
|
||||
`Loaded ${data.length} records`, JSON.stringify(data, null, 2).substring(0, 1000));
|
||||
} catch (error) {
|
||||
setResult('jalanRusakResult', 'Load Jalan Rusak', 'error', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function testSaveRumahIbadah() {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('nama', document.getElementById('namaRumah').value);
|
||||
formData.append('alamat', document.getElementById('alamatRumah').value);
|
||||
formData.append('pic', document.getElementById('picRumah').value);
|
||||
formData.append('latitude', document.getElementById('latRumah').value);
|
||||
formData.append('longitude', document.getElementById('lngRumah').value);
|
||||
formData.append('radius_m', document.getElementById('radiusRumah').value);
|
||||
|
||||
const response = await fetch('save_rumah_ibadah.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
const text = await response.text();
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (data.status === 'success') {
|
||||
setResult('saveRumahResult', 'Save Rumah Ibadah', 'success',
|
||||
`Data berhasil disimpan. ID: ${data.id}`, JSON.stringify(data, null, 2));
|
||||
} else {
|
||||
setResult('saveRumahResult', 'Save Rumah Ibadah', 'error',
|
||||
data.message, JSON.stringify(data, null, 2));
|
||||
}
|
||||
} catch (error) {
|
||||
setResult('saveRumahResult', 'Save Rumah Ibadah', 'error', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function testDOMElements() {
|
||||
const elements = [
|
||||
'modeRumahIbadahBtn',
|
||||
'modePendudukMiskinBtn',
|
||||
'modeChoroplethBtn',
|
||||
'rumahIbadahModal',
|
||||
'pendudukMiskinModal',
|
||||
'choroplethPanel',
|
||||
'map',
|
||||
'registryDrawer'
|
||||
];
|
||||
|
||||
let html = '<div style="margin: 10px 0;"><strong>Checking HTML Elements in index.html:</strong></div>';
|
||||
|
||||
try {
|
||||
const response = await fetch('index.html', { cache: 'no-store' });
|
||||
if (!response.ok) {
|
||||
throw new Error(`Gagal memuat index.html (HTTP ${response.status})`);
|
||||
}
|
||||
|
||||
const source = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(source, 'text/html');
|
||||
|
||||
let allFound = true;
|
||||
|
||||
elements.forEach(id => {
|
||||
const elem = doc.getElementById(id);
|
||||
const status = elem ? '✅' : '❌';
|
||||
const color = elem ? '#166534' : '#991b1b';
|
||||
html += `<div style="color: ${color}; margin: 5px 0;">${status} #${id}</div>`;
|
||||
if (!elem) allFound = false;
|
||||
});
|
||||
|
||||
if (allFound) {
|
||||
setResult('domResult', 'DOM Elements', 'success', 'Semua elements ditemukan di index.html.', html);
|
||||
} else {
|
||||
setResult('domResult', 'DOM Elements', 'error', 'Ada elements yang tidak ditemukan di index.html.', html);
|
||||
}
|
||||
} catch (error) {
|
||||
setResult('domResult', 'DOM Elements', 'error', `Gagal validasi DOM index.html: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto check on load
|
||||
window.addEventListener('load', () => {
|
||||
console.log('✅ Test page loaded');
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include 'db_config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Metode tidak diizinkan']);
|
||||
$conn->close();
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$status = strtolower(trim($_POST['bantuan_status'] ?? 'belum'));
|
||||
$catatan = trim($_POST['bantuan_catatan'] ?? '');
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']);
|
||||
$conn->close();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!in_array($status, ['belum', 'proses', 'sudah'], true)) {
|
||||
$status = 'belum';
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE penduduk_miskin SET bantuan_status = ?, bantuan_catatan = ?, bantuan_updated_at = CURRENT_TIMESTAMP WHERE id = ?");
|
||||
$stmt->bind_param("ssi", $status, $catatan, $id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$updatedAtResult = $conn->query("SELECT bantuan_updated_at FROM penduduk_miskin WHERE id = " . (int)$id . " LIMIT 1");
|
||||
$updatedAt = null;
|
||||
if ($updatedAtResult && $updatedAtResult->num_rows > 0) {
|
||||
$row = $updatedAtResult->fetch_assoc();
|
||||
$updatedAt = $row['bantuan_updated_at'] ?? null;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'message' => 'Status bantuan berhasil diperbarui',
|
||||
'bantuan_updated_at' => $updatedAt
|
||||
]);
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => $stmt->error]);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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();
|
||||
?>
|
||||
Reference in New Issue
Block a user