Files
webgis_geospesial/index.php
T

577 lines
28 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// ============================================================
// index.php Halaman Utama WebGIS
// ============================================================
include 'koneksi.php';
// Ambil semua data
$stmt = $pdo->query("SELECT * FROM points ORDER BY id DESC");
$points = $stmt->fetchAll();
$stmt = $pdo->query("SELECT * FROM jalan ORDER BY id DESC");
$jalan = $stmt->fetchAll();
$stmt = $pdo->query("SELECT * FROM polygon ORDER BY id DESC");
$polygons = $stmt->fetchAll();
$stmt = $pdo->query("SELECT * FROM fasilitas_publik ORDER BY id DESC");
$fasilitasPublik = $stmt->fetchAll();
$stmt = $pdo->query("SELECT pm.*, fp.nama AS fp_nama FROM penduduk_miskin pm LEFT JOIN fasilitas_publik fp ON pm.fasilitas_publik_id = fp.id ORDER BY pm.id DESC");
$pendudukMiskin = $stmt->fetchAll();
// Statistik dashboard
$totalFP = count($fasilitasPublik);
$totalPM = count($pendudukMiskin);
$ditangani = count(array_filter($pendudukMiskin, fn($p) => $p['status_jangkauan'] === 'Dalam Jangkauan'));
$belumDitangani = $totalPM - $ditangani;
$persen = $totalPM > 0 ? round(($ditangani / $totalPM) * 100, 1) : 0;
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGIS Sistem Analisis Geospasial Pengentasan Kemiskinan</title>
<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin="">
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- App CSS -->
<link rel="stylesheet" href="assets/css/style.css?v=1">
</head>
<body>
<!-- ═══════════════════════════════════════════════════════════
SIDEBAR
═══════════════════════════════════════════════════════════ -->
<aside class="sidebar" id="sidebar">
<!-- Header Sidebar -->
<div class="sidebar-header">
<div class="sidebar-logo">
<div class="logo-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" fill="currentColor" opacity=".9"/>
<circle cx="12" cy="9" r="2.5" fill="white"/>
</svg>
</div>
<div class="logo-text">
<span class="logo-title">WebGIS</span>
<span class="logo-sub">Analisis Spasial</span>
</div>
</div>
<button class="sidebar-toggle" id="sidebarToggle" title="Sembunyikan Sidebar">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M15 18l-6-6 6-6"/>
</svg>
</button>
</div>
<!-- Kotak Pencarian Baru -->
<div class="sidebar-search">
<div class="search-input-wrap">
<svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
<input type="text" id="searchInput" placeholder="Cari nama, NIK, atau lokasi..." autocomplete="off">
</div>
<div class="search-results hidden" id="searchResults"></div>
</div>
<!-- Dashboard Statistik -->
<div class="sidebar-section">
<div class="section-label">Dashboard Statistik</div>
<div class="stats-grid">
<div class="stat-card stat-blue">
<div class="stat-icon">🏢</div>
<div class="stat-body">
<div class="stat-value" id="statTotalRI"><?= $totalFP ?></div>
<div class="stat-label">Fasilitas Publik</div>
</div>
</div>
<div class="stat-card stat-amber">
<div class="stat-icon">👥</div>
<div class="stat-body">
<div class="stat-value" id="statTotalPM"><?= $totalPM ?></div>
<div class="stat-label">Penduduk Miskin</div>
</div>
</div>
<div class="stat-card stat-green">
<div class="stat-icon">✅</div>
<div class="stat-body">
<div class="stat-value" id="statDitangani"><?= $ditangani ?></div>
<div class="stat-label">Ditangani</div>
</div>
</div>
<div class="stat-card stat-red">
<div class="stat-icon">⚠️</div>
<div class="stat-body">
<div class="stat-value" id="statBelum"><?= $belumDitangani ?></div>
<div class="stat-label">Belum Ditangani</div>
</div>
</div>
</div>
<!-- Progress cakupan -->
<div class="coverage-bar-wrap">
<div class="coverage-bar-header">
<span>Cakupan Bantuan</span>
<strong id="statPersen"><?= $persen ?>%</strong>
</div>
<div class="coverage-bar-track">
<div class="coverage-bar-fill" id="statProgressBar" style="width: <?= $persen ?>%"></div>
</div>
</div>
<!-- Tools -->
<div class="sidebar-section">
<div class="section-label">Alat Peta</div>
<div class="tool-grid">
<button class="tool-btn active" id="btnToolPoint" data-mode="point" title="Tambah Titik">
<span class="tool-icon">📍</span>
<span>Titik</span>
</button>
<button class="tool-btn" id="btnToolJalan" data-mode="jalan" title="Gambar Jalan">
<span class="tool-icon">🛣️</span>
<span>Jalan</span>
</button>
<button class="tool-btn" id="btnToolPolygon" data-mode="polygon" title="Gambar Polygon">
<span class="tool-icon">⬜</span>
<span>Polygon</span>
</button>
<button class="tool-btn" id="btnToolFasilitasPublik" data-mode="fasilitas_publik" title="Fasilitas Publik">
<span class="tool-icon">🏢</span>
<span>Fasilitas</span>
</button>
<button class="tool-btn" id="btnToolPenduduk" data-mode="penduduk_miskin" title="Penduduk Miskin">
<span class="tool-icon">👥</span>
<span>Miskin</span>
</button>
<button class="tool-btn" id="btnToolLokasi" data-mode="lokasi" title="Lokasi Saya">
<span class="tool-icon">📡</span>
<span>Lokasi</span>
</button>
</div>
<div class="help-text" id="helpText">
Pilih alat lalu klik pada peta untuk menambahkan data.
</div>
</div>
<!-- Layer Control -->
<div class="sidebar-section">
<div class="section-label">Kontrol Layer</div>
<div class="layer-list" id="layerList">
<label class="layer-item">
<input type="checkbox" id="layerFasilitasPublik" checked>
<span class="layer-dot" style="background:#e53935"></span>
<span>Fasilitas Publik</span>
</label>
<label class="layer-item">
<input type="checkbox" id="layerPendudukDalam" checked>
<span class="layer-dot" style="background:#e53935;border:2px solid #333"></span>
<span>Penduduk Ditangani</span>
</label>
<label class="layer-item">
<input type="checkbox" id="layerPendudukLuar" checked>
<span class="layer-dot" style="background:#2e7d32"></span>
<span>Penduduk Luar Jangkauan</span>
</label>
<label class="layer-item">
<input type="checkbox" id="layerTitik"><span class="layer-dot" style="background:#78909c"></span><span>Titik Lokasi (Data)</span></label><label class="layer-item"><input type="checkbox" id="layerJalan"><span class="layer-dot" style="background:#f57c00"></span><span>Jalan (Data)</span></label><label class="layer-item"><input type="checkbox" id="layerPolygon"><span class="layer-dot" style="background:#ba68c8"></span><span>Polygon (Data)</span></label><label class="layer-item"><input type="checkbox" id="layerGeoJalan">
<span class="layer-dot" style="background:#d32f2f"></span>
<span>Jaringan Jalan</span>
</label>
<label class="layer-item">
<input type="checkbox" id="layerKecamatan">
<span class="layer-dot" style="background:#ef6c00;border-radius:2px"></span>
<span>Batas Kecamatan</span>
</label>
<label class="layer-item">
<input type="checkbox" id="layerSungai">
<span class="layer-dot" style="background:#0d47a1"></span>
<span>Sungai Besar</span>
</label>
</div>
</div>
<!-- Legenda -->
<div class="sidebar-section">
<div class="section-label">Legenda</div>
<div class="legend-list">
<div class="legend-item">
<span class="legend-marker marker-ri"></span>
<span>Fasilitas Publik + Radius</span>
</div>
<div class="legend-item">
<span class="legend-circle" style="background:rgba(229,57,53,0.2);border:2px solid #e53935"></span>
<span>Penduduk Ditangani</span>
</div>
<div class="legend-item">
<span class="legend-circle" style="background:rgba(46,125,50,0.2);border:2px solid #2e7d32"></span>
<span>Penduduk Luar Jangkauan</span>
</div>
<div class="legend-item">
<span class="legend-line" style="background:#d32f2f"></span>
<span>Jalan Nasional</span>
</div>
<div class="legend-item">
<span class="legend-line" style="background:#f57c00"></span>
<span>Jalan Provinsi</span>
</div>
<div class="legend-item">
<span class="legend-line" style="background:#388e3c"></span>
<span>Jalan Kabupaten</span>
</div>
</div>
</div>
<!-- Footer -->
<div class="sidebar-footer">
<span>© 2025 WebGIS Spasial</span>
</div>
</aside>
<!-- Sidebar collapsed toggle -->
<button class="sidebar-open-btn hidden" id="sidebarOpenBtn" title="Buka Sidebar">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M9 18l6-6-6-6"/>
</svg>
</button>
<!-- ═══════════════════════════════════════════════════════════
MAP
═══════════════════════════════════════════════════════════ -->
<div id="mapContainer">
<div id="map"></div>
<!-- Notifikasi toast -->
<div class="toast-container" id="toastContainer"></div>
<!-- Loading overlay -->
<div class="map-loading" id="mapLoading">
<div class="loading-spinner"></div>
<span>Memuat peta...</span>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
MODALS
═══════════════════════════════════════════════════════════ -->
<!-- BACKDROP -->
<div class="modal-backdrop hidden" id="modalBackdrop"></div>
<!-- MODAL: Tambah/Edit Titik (Point) -->
<div class="modal hidden" id="pointModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#e3f2fd;color:#1565c0">📍</div>
<div>
<h3 class="modal-title" id="pointModalTitle">Tambah Titik</h3>
<p class="modal-subtitle">Klik peta untuk menentukan lokasi</p>
</div>
</div>
<button class="modal-close" id="closePointModal">✕</button>
</div>
<div class="modal-body">
<input type="hidden" id="point_id">
<div class="form-row">
<div class="form-group">
<label class="form-label">Nama <span class="req">*</span></label>
<input type="text" class="form-input" id="point_nama" placeholder="Nama titik...">
</div>
<div class="form-group">
<label class="form-label">No. WhatsApp <span class="req">*</span></label>
<input type="text" class="form-input" id="point_no_wa" placeholder="08xx...">
</div>
</div>
<div class="form-group">
<label class="form-label">Buka 24 Jam</label>
<div class="radio-tabs">
<label class="radio-tab">
<input type="radio" name="point_buka_24_jam" value="Ya">
<span>✓ Ya</span>
</label>
<label class="radio-tab">
<input type="radio" name="point_buka_24_jam" value="Tidak" checked>
<span>✗ Tidak</span>
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Latitude</label>
<input type="text" class="form-input mono" id="point_latitude" readonly placeholder="Klik peta">
</div>
<div class="form-group">
<label class="form-label">Longitude</label>
<input type="text" class="form-input mono" id="point_longitude" readonly placeholder="Klik peta">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelPointModal">Batal</button>
<button class="btn btn-primary" id="btnSavePoint">
<span>Simpan Titik</span>
</button>
</div>
</div>
<!-- MODAL: Jalan -->
<div class="modal hidden" id="jalanModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#fce4ec;color:#c62828">🛣️</div>
<div>
<h3 class="modal-title">Data Jalan</h3>
<p class="modal-subtitle">Klik beberapa titik, double-klik selesai</p>
</div>
</div>
<button class="modal-close" id="closeJalanModal">✕</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">Nama Jalan <span class="req">*</span></label>
<input type="text" class="form-input" id="nama_jalan" placeholder="Nama jalan...">
</div>
<div class="form-group">
<label class="form-label">Status Jalan <span class="req">*</span></label>
<select class="form-input" id="status_jalan">
<option value=""> Pilih Status </option>
<option value="Jalan Nasional">Jalan Nasional</option>
<option value="Jalan Provinsi">Jalan Provinsi</option>
<option value="Jalan Kabupaten">Jalan Kabupaten</option>
</select>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Panjang (meter)</label>
<input type="text" class="form-input mono" id="panjang_meter" readonly>
</div>
<div class="form-group">
<label class="form-label">Jumlah Titik</label>
<input type="text" class="form-input mono" id="jumlah_titik_jalan" readonly value="0">
</div>
</div>
<div class="form-group hidden">
<textarea class="form-input mono" id="koordinat_jalan" rows="4" readonly></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelJalanModal">Batal</button>
<button class="btn btn-primary" id="btnSaveJalan">Simpan Jalan</button>
</div>
</div>
<!-- MODAL: Polygon -->
<div class="modal hidden" id="polygonModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#f3e5f5;color:#6a1b9a">⬜</div>
<div>
<h3 class="modal-title">Data Parsil Tanah</h3>
<p class="modal-subtitle">Min. 3 titik untuk polygon</p>
</div>
</div>
<button class="modal-close" id="closePolygonModal">✕</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">Nama Parsil <span class="req">*</span></label>
<input type="text" class="form-input" id="nama_parsil" placeholder="Nama parsil tanah...">
</div>
<div class="form-group">
<label class="form-label">Status Kepemilikan <span class="req">*</span></label>
<select class="form-input" id="status_kepemilikan">
<option value=""> Pilih Status </option>
<option value="SHM">SHM Sertifikat Hak Milik</option>
<option value="HGB">HGB Hak Guna Bangunan</option>
<option value="HGU">HGU Hak Guna Usaha</option>
<option value="HP">HP Hak Pakai</option>
</select>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Luas (m²)</label>
<input type="text" class="form-input mono" id="luas_tanah" readonly>
</div>
<div class="form-group">
<label class="form-label">Jumlah Titik</label>
<input type="text" class="form-input mono" id="jumlah_titik_polygon" readonly value="0">
</div>
</div>
<div class="form-group hidden">
<textarea class="form-input mono" id="koordinat_polygon" rows="4" readonly></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelPolygonModal">Batal</button>
<button class="btn btn-primary" id="btnSavePolygon">Simpan Polygon</button>
</div>
</div>
<!-- MODAL: Fasilitas Publik -->
<div class="modal hidden" id="fasilitasPublikModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#e8f5e9;color:#2e7d32">🏢</div>
<div>
<h3 class="modal-title" id="fpModalTitle">Tambah Fasilitas Publik</h3>
<p class="modal-subtitle">Klik peta untuk menentukan lokasi</p>
</div>
</div>
<button class="modal-close" id="closefasilitasPublikModal">✕</button>
</div>
<div class="modal-body">
<input type="hidden" id="fp_id">
<div class="form-row">
<div class="form-group">
<label class="form-label">Nama Fasilitas Publik <span class="req">*</span></label>
<input type="text" class="form-input" id="fp_nama" placeholder="Nama...">
</div>
<div class="form-group">
<label class="form-label">Jenis</label>
<select class="form-input" id="fp_jenis">
<option value=""> Pilih Jenis </option>
<option value="Kantor Desa / Pemerintahan">Kantor Desa / Pemerintahan</option>
<option value="Fasilitas Kesehatan (Puskesmas)">Fasilitas Kesehatan (Puskesmas)</option>
<option value="Rumah Ibadah (Masjid/Gereja/dll)">Rumah Ibadah (Masjid/Gereja/dll)</option>
<option value="Posko / e-Warong">Posko / e-Warong</option>
<option value="Sekolah">Sekolah</option>
</select>
</div>
</div>
<div class="form-group">
<label class="form-label">Alamat <small>(otomatis dari koordinat)</small></label>
<div class="geocode-wrap">
<textarea class="form-input" id="fp_alamat" rows="2" placeholder="Klik peta untuk mendapatkan alamat otomatis..."></textarea>
<span class="geocode-status" id="geocodeStatus"></span>
</div>
</div>
<div class="form-group">
<label class="form-label">
Radius Pelayanan: <strong id="fp_radius_text">300</strong> meter
</label>
<div class="range-wrap">
<span class="range-min">100m</span>
<input type="range" class="range-input" id="fp_radius" min="100" max="3000" step="50" value="300">
<span class="range-max">3000m</span>
</div>
</div>
<div class="form-group">
<label class="form-label">Kontak</label>
<input type="text" class="form-input" id="fp_kontak" placeholder="No. HP / WA...">
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Latitude</label>
<input type="text" class="form-input mono" id="fp_latitude" readonly placeholder="Klik peta">
</div>
<div class="form-group">
<label class="form-label">Longitude</label>
<input type="text" class="form-input mono" id="fp_longitude" readonly placeholder="Klik peta">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelfasilitasPublikModal">Batal</button>
<button class="btn btn-primary" id="btnSaveFasilitasPublik">Simpan</button>
</div>
</div>
<!-- MODAL: Penduduk Miskin -->
<div class="modal hidden" id="pendudukModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#fff8e1;color:#e65100">👥</div>
<div>
<h3 class="modal-title" id="pmModalTitle">Tambah Penduduk Miskin</h3>
<p class="modal-subtitle">Klik peta untuk menentukan lokasi</p>
</div>
</div>
<button class="modal-close" id="closePendudukModal">✕</button>
</div>
<div class="modal-body">
<input type="hidden" id="pm_id">
<div class="form-row">
<div class="form-group">
<label class="form-label">Nama Lengkap <span class="req">*</span></label>
<input type="text" class="form-input" id="pm_nama" placeholder="Nama...">
</div>
<div class="form-group">
<label class="form-label">NIK</label>
<input type="text" class="form-input mono" id="pm_nik" placeholder="16 digit NIK...">
</div>
</div>
<div class="form-group">
<label class="form-label">Keterangan</label>
<textarea class="form-input" id="pm_keterangan" rows="2" placeholder="Kondisi ekonomi, pekerjaan, dll..."></textarea>
</div>
<!-- Status Jangkauan (auto) -->
<div class="status-jangkauan-card" id="statusJangkauanCard">
<div class="sj-label">Status Jangkauan</div>
<div class="sj-value" id="pm_status">—</div>
<div class="sj-ditangani" id="pm_ditangani"></div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Latitude</label>
<input type="text" class="form-input mono" id="pm_latitude" readonly placeholder="Klik peta">
</div>
<div class="form-group">
<label class="form-label">Longitude</label>
<input type="text" class="form-input mono" id="pm_longitude" readonly placeholder="Klik peta">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelPendudukModal">Batal</button>
<button class="btn btn-primary" id="btnSavePenduduk">Simpan</button>
</div>
</div>
<!-- MODAL: Konfirmasi Hapus -->
<div class="modal modal-sm hidden" id="deleteModal">
<div class="modal-header">
<div class="modal-title-wrap">
<div class="modal-icon" style="background:#ffebee;color:#c62828">🗑️</div>
<div>
<h3 class="modal-title">Konfirmasi Hapus</h3>
</div>
</div>
</div>
<div class="modal-body">
<p id="deleteMessage">Apakah Anda yakin ingin menghapus data ini?</p>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelDelete">Batal</button>
<button class="btn btn-danger" id="confirmDelete">Hapus</button>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
DATA PHP → JS
═══════════════════════════════════════════════════════════ -->
<script>
const APP_DATA = {
points: <?= json_encode($points, JSON_UNESCAPED_UNICODE) ?>,
jalan: <?= json_encode($jalan, JSON_UNESCAPED_UNICODE) ?>,
polygons: <?= json_encode($polygons, JSON_UNESCAPED_UNICODE) ?>,
fasilitasPublik: <?= json_encode($fasilitasPublik, JSON_UNESCAPED_UNICODE) ?>,
pendudukMiskin:<?= json_encode($pendudukMiskin, JSON_UNESCAPED_UNICODE) ?>,
};
</script>
<!-- Leaflet JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script>
<!-- App JS -->
<script src="assets/js/app.js?v=1"></script>
</body>
</html>