Spesifikasi Kamera GeoTag & Sensor
⚙️ SPESIFIKASI TEKNIS: MODUL KAMERA GEOTAG & EKOSISTEM SENSOR SPASIAL
Rekayasa Perangkat Lunak Sisi Klien untuk Pembuktian Forensik Digital Anti-Fraud (Grand Standard 2026.2)#
BUMDes Bolulango — Kabupaten Boalemo, Gorontalo
Single Source of Truth Arsitektur Komponen: components/ui/GeoTagCamera.tsx & components/ui/MultiPhotoGeoTagUploader.tsx
🏛️ 1. Visi Arsitektur & Filosofi Desain#
Modul Kamera GeoTag BUMDes dirancang dengan filosofi "Client-Side Zero-Server-Overhead". Dalam operasional lapangan pedesaan dengan infrastruktur internet terbatas (intermittent 3G/4G connectivity), pemrosesan grafis dan kalkulasi sensor tidak boleh bergantung pada latensi jaringan (roundtrip network lag) atau infrastruktur komputasi awan yang mahal.
Memuat diagram alur...
Prinsip-Prinsip Utama:
- Zero-Latency Watermarking: Seluruh penggabungan layer visual (compositing) dilakukan secara langsung di memori GPU ponsel melalui
HTMLCanvasElementdanCanvasRenderingContext2D. - Dual-Layer Anti-Tampering: Perlindungan foto disediakan dalam dua lapis:
- Visual Layer: Watermark grafis permanen yang menyatu ke dalam matriks piksel foto.
- Binary Layer: Metadata biner EXIF/TIFF yang disisipkan ke struktur file header.
- CORS Taint Immunity: Mengeliminasi kegagalan rendering kanvas (SecurityError: The operation is insecure) melalui penegakan
img.crossOrigin = "anonymous"dan pembersihan memori instanURL.revokeObjectURL().
🛰️ 2. Sensor Harvesting & Pipeline Pre-Warming Cache#
Untuk mencegah jeda waktu (freeze) saat tombol bidik kamera ditekan, modul menerapkan arsitektur Sensor Pre-Warming yang aktif secara asinkron sejak komponen terpasang pada DOM (component mount).
2.1. GPS & Sensor Ketinggian Geolocation
Sensor lokasi dikelola melalui navigator.geolocation.watchPosition() dengan konfigurasi presisi tinggi:
enableHighAccuracy: true(Mengaktifkan modul GNSS GPS satelit, bukan sekadar Cell-ID/WiFi triangulasi).maximumAge: 30000(Menggunakan cache lokasi maksimal 30 detik untuk menghemat baterai ponsel).timeout: 10000(Batas waktu pembacaan sensor 10 detik sebelum beralih ke toleransi terdekat).
Metadata yang ditangkap:
- Latitude & Longitude: Derajat desimal presisi 6 angka di belakang koma.
- Accuracy Radius: Derajat ketidakpastian dalam satuan meter.
- Hijau (Akurasi Tinggi): Jarak toleransi <= 15 meter.
- Kuning (Akurasi Sedang): Jarak toleransi 15 meter - 50 meter.
- Merah (Akurasi Rendah): Jarak toleransi > 50 meter.
- Altitude (Elevasi dpl): Ketinggian fisik perangkat di atas permukaan laut. Jika sistem operasi ponsel mengembalikan
nullatau0, modul secara otomatis memicu fallback topografi Desa Bandungan (120 m dpl).
2.2. Optical Compass & Azimuth Normalization
Pola pembacaan sensor kompas diimplementasikan pada file lib/utils/optical-compass.ts:
- Deteksi Lintas Platform:
- Platform iOS (WebKit): Membaca langsung properti
event.webkitCompassHeading(0° = True North). - Platform Android (Chromium): Menghitung nilai azimuth dari orientasi Euler alpha:
azimuth = (360 - event.alpha) % 360 - Normalisasi Sudut:
normalizedHeading = ((heading % 360) + 360) % 360 - Konversi 8 Arah Mata Angin Baku:
Rentang derajat azimuth dipetakan ke dalam 8 sektor sudut berjarak masing-masing 45 derajat dengan pergeseran offset 22.5 derajat:
index = floor(((heading + 22.5) % 360) / 45)
| Indeks | Derajat Azimuth | Singkatan Arah | Nama Arah Lengkap |
|---|---|---|---|
| 0 | 337.5° - 022.5° | U | Utara (North) |
| 1 | 022.5° - 067.5° | TL | Timur Laut (North-East) |
| 2 | 067.5° - 112.5° | T | Timur (East) |
| 3 | 112.5° - 157.5° | TG | Tenggara (South-East) |
| 4 | 157.5° - 202.5° | S | Selatan (South) |
| 5 | 202.5° - 247.5° | BD | Barat Daya (South-West) |
| 6 | 247.5° - 292.5° | B | Barat (West) |
| 7 | 292.5° - 337.5° | BL | Barat Laut (North-West) |
🗺️ 3. Algoritma Geospasial Luring (Offline Toponymy Engine)#
Untuk menjamin ketersediaan data administratif saat koneksi internet terputus, modul kamera menyematkan pustaka toponimi luring yang tidak memerlukan panggilan API keluar:
3.1. Ray-Casting Point-in-Polygon (PIP)
Algoritma memeriksa apakah titik koordinat kamera (x, y) berada di dalam poligon tertutup dusun dengan menembakkan sinar horizontal imaginer ke arah kanan (x -> tak terhingga):
- Variabel penentu:
inside = false - Untuk setiap sisi poligon dari titik
ike titikj: Kondisi perpotongan terjadi jika:((y_i > y) != (y_j > y)) && (x < (x_j - x_i) * (y - y_i) / (y_j - y_i) + x_i)Jika kondisi terpenuhi, nilaiinsidedibalik (inside = !inside). - Jika jumlah perpotongan sinar ganjil, titik berada di dalam poligon.
3.2. Formula Haversine untuk Penentuan Dusun Terdekat
Jika operator berada di luar batas poligon definitif desa, sistem menghitung jarak lengkung lingkaran besar (great-circle distance) ke setiap titik sentral dusun:
- Jari-jari Bumi baku:
R = 6371000 meter - Rumus Haversine:
Δlat = (lat2 - lat1) * π / 180Δlon = (lon2 - lon1) * π / 180a = sin²(Δlat / 2) + cos(lat1 * π / 180) * cos(lat2 * π / 180) * sin²(Δlon / 2)c = 2 * atan2(√a, √(1 - a))jarak = R * c - Dusun dengan nilai
jarakterkecil ditetapkan sebagai toponimi aktif.
💾 4. Rekayasa Biner EXIF & TIFF Header Injection#
Modul mengimplementasikan binary encoder mandiri tanpa ketergantungan pustaka eksternal (zero-dependency) untuk menyematkan metadata forensik ke dalam file JPEG dan WebP.
4.1. Struktur TIFF Header Little-Endian (II)
Header TIFF berukuran 8 byte:
- Byte 0-1:
0x49 0x49(Tanda ASCII'II'= Little-Endian, Intel format). - Byte 2-3:
0x002A(Angka magis TIFF = 42). - Byte 4-7:
0x00000008(Offset ke IFD 0 = 8 byte).
4.2. Matriks Tag EXIF GPS Sub-IFD
Format konversi koordinat desimal ke format rasional Degrees-Minutes-Seconds (DMS) 32-bit:
derajat = floor(desimal)menit = floor((desimal - derajat) * 60)detik = round((desimal - derajat - (menit / 60)) * 3600 * 100) / 100- Setiap komponen direpresentasikan sebagai pasangan 2 bilangan bulat 32-bit:
[pembilang, penyebut](contoh detik:[detik * 100, 100]).
Tag Biner yang Ditanamkan:
0x0001-GPSLatitudeRef: ASCII'N'atau'S'.0x0002-GPSLatitude: RATIONAL x 3 (Derajat/1, Menit/1, Detik/100).0x0003-GPSLongitudeRef: ASCII'E'atau'W'.0x0004-GPSLongitude: RATIONAL x 3 (Derajat/1, Menit/1, Detik/100).0x0005-GPSAltitudeRef: BYTE0(0 = Di atas permukaan laut).0x0006-GPSAltitude: RATIONAL (Elevasi * 100 / 100).0x0010-GPSImgDirectionRef: ASCII'T'(True North).0x0011-GPSImgDirection: RATIONAL (Derajat Kompas * 100 / 100).0x9286-UserComment: Undefined Block berisi string terenkode:JSON: {"token":"GT-SAP0-...","unit":"...","toponimi":"Dusun I","azimuth":45.2,"altitude":120}
4.3. Mekanisme Injeksi JPEG APP1 Segment (0xFFE1)
- Membaca 2 byte pertama berkas JPEG untuk memverifikasi penanda
SOI(0xFF 0xD8). - Menghitung panjang keseluruhan segmen EXIF:
panjangSegmen = 2 (panjang) + 6 ('Exif\0\0') + panjangTIFF. - Merangkai buffer biner:
[0xFF, 0xE1, (panjangSegmen >> 8), (panjangSegmen & 0xFF), 'E', 'x', 'i', 'f', 0, 0, ...payloadTIFF]. - Menyisipkan segmen APP1 tepat setelah penanda
SOIsebelum penanda frame berikutnya.
4.4. Mekanisme Injeksi WebP RIFF Chunk ('EXIF')
- Memverifikasi 4 byte pertama file:
'RIFF', dan tipe format pada byte 8-11:'WEBP'. - Jika file berupa format sederhana
'VP8 'atau'VP8L', header dielevasi menjadi format kontainer'VP8X'untuk mendukung metadata eksternal. - Menulis chunk EXIF:
FourCC: 'EXIF'(4 byte),Ukuran: payloadTIFF.length(4 byte little-endian),Data: payloadTIFF. - Jika ukuran chunk ganjil, ditambahkan 1 byte padding
0x00sesuai spesifikasi WebP Container RIFF. - Memperbarui total panjang file pada header RIFF (byte 4-7).
🔍 5. Pipeline Computer Vision & OCR Struk Kasir#
Pada Slot 1 (Nota/Kwitansi), sistem mempekerjakan Tesseract.js Worker yang berjalan pada thread latar belakang (Web Worker) tanpa memblokir antarmuka pengguna:
5.1. Binarisasi Kanvas Adaptif
Sebelum teks diekstraksi, gambar melalui filter pra-pemrosesan:
- Skala abu-abu (grayscale conversion):
Luminansi = 0.299 * R + 0.587 * G + 0.114 * B - Thresholding Otsu/Adaptif:
Piksel dengan
Luminansi < 128diubah menjadi hitam pekat (#000000), dan sisanya diubah menjadi putih bersih (#ffffff). - Peningkatan kontras ini mengeliminasi bayangan lipatan kertas nota dan noda minyak pada struk kasir.
5.2. Indonesian Currency Regex Parser
Output teks mentah dari Tesseract diurai menggunakan aturan NLP bertingkat:
- Pendeteksian Anchor Kata Kunci:
Regex mencari pola:
/(?:TOTAL|JUMLAH|TAGIHAN|BAYAR|TUNAI|NETTO)s*[:=]?s*(?:RP\.?|IDR)?s*([0-9.,]+)/i. - Sanitasi Format Angka Indonesia:
- Menghilangkan titik ribuan (
150.000->150000). - Mengonversi koma desimal ke format standar floating point (
150000,00->150000.00). - Skor Keyakinan (Confidence Score): Hanya hasil dengan keyakinan OCR >= 60% yang disajikan ke antarmuka pengguna.
5.3. State Machine Rekonsiliasi Otomatis
Memuat diagram alur...
🔐 6. Mesin Kriptografi & Token Anti-Tampering#
Untuk mencegah manipulasi foto di luar sistem, setiap jepretan kamera menghasilkan tanda tangan digital FNV-1a (Fowler-Noll-Vo 32-bit Hash).
6.1. Algoritma FNV-1a Hash
- Offset Basis FNV:
2166136261(0x811C9DC5) - Prima FNV 32-bit:
16777619(0x01000193) - Alur komputasi karakter per karakter:
hash = hash XOR charCodehash = (hash * 16777619) & 0xFFFFFFFF - String Masukan Kanonik:
canonicalString = lat.toFixed(5) + "|" + lng.toFixed(5) + "|" + timestampISO + "|" + unitCode
6.2. Format Token Resmi
GT-SAP0-YYYYMMDD-XXXXXX
GT: Prefix identitas GeoTag.SAP0: Kode enkripsi arsitektur SAK EP BUMDes Bolulango.YYYYMMDD: Tanggal pemotretan terverifikasi.XXXXXX: 6 karakter heksadesimal representasi digest FNV-1a.
6.3. Verifikasi Terbuka via Portal Publik
Token ini dicetak ke dalam QR Code berukuran 48x48 piksel pada sudut panel watermark. URL tujuan verifikasi:
https://erp.bumdesbolulango.id/verify/evidence?token=GT-SAP0-20260916-A1B2C3
Auditor eksternal atau inspektorat dapat memindai QR Code ini menggunakan kamera ponsel standar untuk melihat status validitas transaksi di portal publik tanpa perlu akun kredensial login ERP.
🎨 7. Canvas HUD Engine & Desain Visual Mawar Kompas#
Mesin perenderan kanvas (CanvasRenderingContext2D) menangani pembuatan elemen visual beresolusi tinggi dengan performa 60 FPS:
7.1. Trigonometri Dial Mawar Kompas Taktis
Dial Mawar Kompas digambar pada posisi koordinat kanvas (cx, cy) dengan radius r = 18px:
- Simpan matriks transformasi:
ctx.save(). - Pindahkan titik pusat translasi:
ctx.translate(cx, cy). - Putar bidang kanvas berlawanan arah hadap:
rotasiRadian = -heading * Math.PI / 180ctx.rotate(rotasiRadian). - Lukis Jarum Panah Utara:
- Titik puncak:
(0, -r + 2)berwarna merah menyala (#ef4444). - Titik sayap kiri:
(-4, 0)dan sayap kanan(4, 0).
- Lukis Jarum Panah Selatan:
- Titik ujung bawah:
(0, r - 2)berwarna abu-abu terang (#e2e8f0).
- Lukis cincin luar bercahaya (glow border) dan huruf penanda mata angin
'U'. - Kembalikan matriks transformasi:
ctx.restore().
Hasilnya adalah jarum kompas yang selalu tegak menunjuk arah magnetik bumi yang sesungguhnya secara instan dan presisi.
7.2. Auto-Compressor Bertingkat
Kamera ponsel cerdas modern menghasilkan resolusi gambar 4000x3000 piksel yang membebani kuota pengunggahan. Kanvas menerapkan reduksi cerdas:
- Batas dimensi maksimum:
1600 pikselpada sisi terpanjang dengan mempertahankan rasio aspek (aspect ratio preservation). - Kualitas kompresi kanvas:
canvas.toDataURL("image/webp", 0.82)(Jika peramban mendukung WebP)canvas.toDataURL("image/jpeg", 0.85)(Fallback JPEG). - Menghasilkan bobot berkas rata-rata 160 KB hingga 190 KB dengan kualitas visual tajam dan siap cetak dokumen audit A4.
🧪 8. Matriks Kepatuhan Audit & Testing Otomatis#
Keandalan seluruh lapisan rekayasa perangkat lunak ini dijamin melalui test suite otomatis berbasis Node.js yang memverifikasi 178 asersi tanpa kegagalan:
| Berkas Pengujian | Dimensi yang Diuji | Jumlah Asersi | Status |
|---|---|---|---|
scripts/test_geotag_qr_verifier.cjs | Algoritma FNV-1a, format token resmi, dictionary 25 unit BUMDes, dan URL portal verifikasi publik. | 31 | 100% PASS |
scripts/test_geotag_tahap_b.cjs | Ray-Casting PIP Dusun I-III, Haversine, struktur biner Little-Endian TIFF, injeksi JPEG APP1, dan injeksi WebP RIFF chunk. | 22 | 100% PASS |
scripts/test_geotag_tahap_c.cjs | Regex parsing mata uang Indonesia, sanitasi OCR, binarisasi kanvas, dan state machine 3-tier rekonsiliasi. | 27 | 100% PASS |
scripts/test_geotag_tahap_d.cjs | Normalisasi sudut kompas, 8 arah mata angin, trigonometri jarum mawar kompas, elevasi meter dpl, dan EXIF direction tag (0x0010/0x0011). | 29 | 100% PASS |
| Suite Tes Regresi Tambahan | Kompresi kanvas, proteksi memori blob URL, dan format cetak voucher 2 halaman. | 69 | 100% PASS |
| TOTAL ASERSI OTOMATIS | Seluruh Ekosistem Kamera GeoTag & Sensor | 178 | 100% PASS |
Dokumen Spesifikasi Teknis Resmi BUMDes Bolulango — Divisi Rekayasa Perangkat Lunak & Tata Kelola Spasial GIS.