Skip to content

Feat: Peta Gabungan Geospasial & DataSpasial - #1311

Open
pandigresik wants to merge 32 commits into
rilis-devfrom
2507-peta-gabungan-dashboard
Open

pandigresik wants to merge 32 commits into
rilis-devfrom
2507-peta-gabungan-dashboard

Conversation

@pandigresik

Copy link
Copy Markdown
Contributor

Description

Menambahkan menu Peta Gabungan yang menyatukan data geospasial lama (sekolah, fasilitas kesehatan, tempat ibadah, dll.) dan data DataSpasial ke dalam satu peta Leaflet. Halaman memakai tata letak dua blok — blok filter (kiri) dan blok peta (kanan) — dengan panel Lapisan yang menyalakan/mematikan tiap kategori/peta sehingga konteks DataSpasial ditentukan oleh lapisan yang dipilih (tanpa pemilih sektor terpisah). Seluruh data dibaca lewat proxy DataSpasialApiService ke API Satu Data (GET /api/v1/dataspasial/geojson), sehingga perubahan filter memuat ulang peta tanpa reload halaman dan kegagalan API tidak pernah menampilkan halaman error.

Changes made:

  1. Feature: PetaGabunganController dirombak dari kerangka menjadi halaman penuh — index() menyajikan tata letak dua blok, data() menjadi endpoint proxy JSON (selalu HTTP 200) yang meneruskan filter sektor, kode_kabupaten, kode_kecamatan, kode_desa, periode, lalu menurunkan meta.layers, meta.periods, meta.filters, dan meta.popup_isian dari skema sektor aktif.
  2. Feature: Filter isian (filter[kode]=nilai) disaring di sisi server via applyIsianFilters(), mencocokkan nilai numerik/teks pada dataspasial.nilai_map/nilai (fitur tanpa nilai dibuang).
  3. Feature: Tampilan resources/views/dataspasial/peta/index.blade.php + filter.blade.php — kartu filter/panel lapisan di kiri (col-md-3) dan peta lebar penuh di kanan (col-md-9), pemuat kecamatan dan filter dinamis (select/angka/teks) berbasis fetch dengan penjaga request basi (lastRequestId).
  4. Feature: public/js/dataspasial/peta-gabungan.js (vanilla, tanpa jQuery) — basemap OSM, batas wilayah, L.markerClusterGroup (chunkedLoading, removeOutsideVisibleBounds) per lapisan (legacy:/data:), popup pada hover + klik, ikon marker lokal, serta auto-fit bounds ke wilayah yang berisi data (dan reset ke tampilan Indonesia jika kosong).
  5. Fix: Path service geojsonGabungan() dikoreksi dari geojson-gabungan menjadi geojson agar sesuai kontrak API-04.
  6. Fix: CSP (CustomCspPreset) diperluas untuk Leaflet.markercluster (CSS/JS) dan https://unpkg.com/ pada img-src sehingga ikon marker tampil.
  7. Test: tests/Feature/DataSpasial/PetaGabunganControllerTest.php (12 kasus: tata letak, tanpa pemilih sektor, layers/filters/popup, unavailable/empty, filter isian, filter kecamatan diteruskan) + tests/Browser/SmokePetaGabunganTest.php (kerangka halaman, pesan unavailable, tidak overflow di ponsel).
  8. Docs: Spesifikasi/plan/tasks/contracts pada specs/2507-peta-gabungan-dashboard/ dan fixture tests/Feature/DataSpasial/Fixtures.php diperbarui (fixture GeoJSON gabungan & skema isian bertanda filter/popup).

Reason for change:

  • Satu layar analisis: Analis OPD perlu menghubungkan sebaran lokasi (titik) dengan angka kapasitas (nilai DataSpasial) tanpa berpindah halaman.
  • Tanpa reload: Filter dan pergantian lapisan harus memperbarui peta dalam satu sesi; endpoint proxy + penjaga request basi menjamin hanya hasil pilihan terakhir yang tampil.
  • Tahan gangguan: API Satu Data bisa tak tersedia; proxy mengembalikan meta.unavailable dan UI menampilkan pesan generik ("Data sementara tidak tersedia") tanpa stack trace.
  • Konsistensi kontrak: Perbaikan path geojson menyelaraskan OpenKab dengan API-04.

Impact of change:

✅ Analisis: Data geospasial lama dan DataSpasial tampil bersama dengan popup identitas + isian bertanda popup beserta satuan, sumber, dan tanggal pembaruan.
✅ Performa: Klaster dengan chunkedLoading + removeOutsideVisibleBounds menjaga interaksi tetap lancar pada dataset besar, dan peta fokus otomatis ke wilayah berisi data.
✅ Ketahanan: Gagal API tidak memecah halaman; otorisasi memakai izin dataspasial-peta-read yang sudah ada.

Related Issue

#1299

Steps to Reproduce

Before (kerangka):

  1. Buka menu DataSpasial → Peta Gabungan.
  2. Hanya tampil kartu "kerangka menu" dengan jumlah lapisan FeatureCollection.
  3. ❌ Tidak ada peta, popup, filter, maupun panel lapisan.

After (fitur):

  1. Login sebagai peran dengan izin dataspasial-peta-read (mis. Analis OPD).
  2. Buka DataSpasial → Peta Gabungan.
  3. Peta tampil dengan basemap, batas wilayah, dan titik terklaster; panel Lapisan berisi grup "Geospasial Lama" dan "DataSpasial".
  4. Nyalakan/matikan lapisan → peta berubah tanpa reload dan otomatis fokus ke data yang terlihat.
  5. Hover/klik titik → popup identitas + isian bertanda popup (satuan, sumber, tanggal pembaruan).
  6. Pilih Kecamatan dan/atau isian bertanda filter lalu Tampilkan → peta diperbarui tanpa reload.
  7. ✅ Kombinasi tanpa data menampilkan "Tidak ada data untuk pilihan ini"; API mati menampilkan "Data sementara tidak tersedia".

Testing on related features:

  • Menu/izin DataSpasial (KAB-01) ✅ Tidak terpengaruh
  • Halaman skema/dasbor/impor DataSpasial ✅ Tidak terpengaruh (rute terpisah)

Checklist

  • I have complied with script writing rules
  • I have followed pull request review process
  • I have created unit test/integration test to verify the feature
  • Manual testing has been done in development environment
  • No console errors or warnings
  • Code has been reviewed by at least 1 person

Technical Details

Technical Explanation

Alur permintaan:

Browser (peta) → GET /dataspasial/peta/data?sektor=&kode_kecamatan=&filter[k]=v
              → PetaGabunganController::data()
              → DataSpasialApiService::geojsonGabungan()  → API Satu Data /api/v1/dataspasial/geojson
              ← FeatureCollection (titik + poligon)
              → applyIsianFilters()  (filter[kode] di sisi server)
              → deriveMeta()         (layers, periods, filters, popup_isian)
              ← JSON 200 { type, features, meta }

DataSpasialApiService::listSkema(['sektor' => kode]) dipakai membaca isian skema terbit untuk menentukan tampil_filter dan tampil_popup. Proxy selalu membalas HTTP 200 dengan penanda meta.unavailable / meta.empty supaya UI menampilkan pesan yang bersahabat alih-alih error.

Struktur lapisan (JS): kunci legacy:<kategori> untuk geospasial lama dan data:<sektor_kode> untuk DataSpasial; tiap kunci punya markerClusterGroup sendiri. Bounds tiap lapisan dikumpulkan agar fitToVisible() memfokuskan peta ke wilayah berisi data.

Rute & izin:

Route::get('peta', [PetaGabunganController::class, 'index'])->middleware('permission:dataspasial-peta-read')->name('dataspasial.peta');
Route::get('peta/data', [PetaGabunganController::class, 'data'])->middleware('permission:dataspasial-peta-read')->name('dataspasial.peta.data');

Configuration changes

  • CSP app/Policies/CustomCspPreset.php: img-src menambah https://unpkg.com/; style/script Leaflet.markercluster 1.5.3 ditambahkan.

Dependencies added

  • No new dependencies (Leaflet 1.9.4 + Leaflet.markercluster 1.5.3 via CDN unpkg; sudah diizinkan CSP).

Testing

Manual Testing

  • Halaman dirender dengan tata letak dua blok tanpa pemilih sektor
  • Panel lapisan menyalakan/mematikan lapisan legacy & DataSpasial tanpa reload
  • Popup hover + klik menampilkan identitas, isian bertanda popup, satuan, sumber, tanggal
  • Filter kecamatan & filter isian memperbarui peta tanpa reload
  • Kombinasi kosong menampilkan "Tidak ada data untuk pilihan ini"
  • API tak tersedia menampilkan "Data sementara tidak tersedia" tanpa stack trace
  • Peta fokus ke wilayah berisi data
  • Regression: menu DataSpasial lain tetap berjalan

Automated Testing

  • Feature Test: tests/Feature/DataSpasial/PetaGabunganControllerTest.php (12 passed)
  • Browser Test: tests/Browser/SmokePetaGabunganTest.php (kerangka, unavailable, mobile no-overflow)

Screenshots / Video

image

Before:

Kartu "kerangka menu" tanpa peta.

After:

Peta gabungan dua blok dengan panel lapisan di kiri (di bawah filter), popup titik, dan filter kecamatan/dinamis. Screenshot disertakan sebagai lampiran PR.

Breaking Changes

None

Migration Guide

Not required (tanpa tabel/migrasi baru; seluruh data ds_* tetap di API Satu Data).

References


…-dashboard)\n\n- spec.md with US1–US5, FR-001–FR-017, SC-001–SC-007 (no reload, tanpa data!=nol, clustering, popup flags)\n- plan.md + research.md + data-model.md + quickstart.md + contracts/view-contract.md\n- requirements checklist all pass
…asial sectors); no sektor picker; kecamatan-only filter
…/click popup, kecamatan-only filter, no sektor picker
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1311

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant