Files
2026-06-13 11:24:58 +07:00

52 lines
2.0 KiB
PHP

<?php
/**
* api/proximity.php — Jarak warga ke fasilitas publik terdekat (KF-21).
* GET ?radius=METER (default 1000) [&jenis=sekolah|puskesmas|pasar|...]
* Mengembalikan GeoJSON warga + fasilitas terdekat + jarak + flag terisolasi.
*/
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);
$radius = (float)($_GET['radius'] ?? 1000);
$jenis = $_GET['jenis'] ?? '';
$jenisFilter = $jenis !== '' ? "WHERE fp.jenis = " . $pdo->quote($jenis) : "";
$sql = "
SELECT w.id, w.nama_kk, ST_AsGeoJSON(w.geom) AS geojson,
(SELECT ST_Distance_Sphere(w.geom, fp.geom) FROM fasilitas_publik fp $jenisFilter
ORDER BY ST_Distance_Sphere(w.geom, fp.geom) LIMIT 1) AS jarak_m,
(SELECT fp.nama FROM fasilitas_publik fp $jenisFilter
ORDER BY ST_Distance_Sphere(w.geom, fp.geom) LIMIT 1) AS fasilitas,
(SELECT fp.jenis FROM fasilitas_publik fp $jenisFilter
ORDER BY ST_Distance_Sphere(w.geom, fp.geom) LIMIT 1) AS fasilitas_jenis
FROM warga_miskin w
ORDER BY jarak_m DESC
";
$stmt = $pdo->query($sql);
$features = [];
$terisolasi = 0;
while ($r = $stmt->fetch()) {
$jarak = $r['jarak_m'] !== null ? round((float)$r['jarak_m']) : null;
$iso = ($jarak !== null && $jarak > $radius);
if ($iso) $terisolasi++;
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($r['geojson']),
'properties' => [
'id' => (int)$r['id'], 'nama_kk' => $r['nama_kk'],
'jarak_m' => $jarak, 'jarak_km' => $jarak !== null ? round($jarak / 1000, 2) : null,
'fasilitas' => $r['fasilitas'], 'fasilitas_jenis' => $r['fasilitas_jenis'],
'terisolasi' => $iso,
],
];
}
sendSuccess([
'type' => 'FeatureCollection', 'features' => $features,
'radius_m' => $radius, 'jumlah_terisolasi' => $terisolasi, 'total' => count($features),
], 'Proximity Analysis');