35 Tinggi, >20 Sedang, selain itu Rendah. * GET → GeoJSON wilayah + properti skor/level/komponen. */ require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/helpers.php'; $pdo = Database::getConnection(); requireApiAnyRole(['operator', 'pimpinan']); if ($_SERVER['REQUEST_METHOD'] !== 'GET') sendError('Method not allowed', 405); $sql = " SELECT w.id, w.nama, w.jumlah_penduduk, ST_AsGeoJSON(w.geom) AS geojson, COUNT(DISTINCT wm.id) AS miskin, COUNT(DISTINCT CASE WHEN bs.id IS NOT NULL THEN wm.id END) AS dibantu FROM wilayah w LEFT JOIN warga_miskin wm ON ST_Contains(w.geom, wm.geom) LEFT JOIN bantuan_sosial bs ON bs.warga_id = wm.id AND bs.is_aktif = 1 GROUP BY w.id ORDER BY w.nama "; $stmt = $pdo->query($sql); $features = []; while ($r = $stmt->fetch()) { $penduduk = (int)$r['jumlah_penduduk']; $miskin = (int)$r['miskin']; $dibantu = (int)$r['dibantu']; $persen = $penduduk > 0 ? round($miskin / $penduduk * 100, 2) : 0; $cakupan = $miskin > 0 ? round($dibantu / $miskin * 100, 1) : 0; $gap = $miskin > 0 ? (100 - $cakupan) : 0; $skor = round($persen * 2 + $gap * 0.2 + $miskin * 1, 1); $level = $skor > 35 ? 'Tinggi' : ($skor > 20 ? 'Sedang' : 'Rendah'); $features[] = [ 'type' => 'Feature', 'geometry' => json_decode($r['geojson']), 'properties' => [ 'id' => (int)$r['id'], 'nama' => $r['nama'], 'jumlah_penduduk' => $penduduk, 'jumlah_miskin' => $miskin, 'dibantu' => $dibantu, 'persentase_miskin' => $persen, 'cakupan_bantuan' => $cakupan, 'skor' => $skor, 'level' => $level, ], ]; } // urутkan ranking by skor desc usort($features, fn($a, $b) => $b['properties']['skor'] <=> $a['properties']['skor']); foreach ($features as $i => &$f) $f['properties']['rank'] = $i + 1; sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Zona Prioritas');