Back to Home
Gistify Snippet
Public
SiPongi+ KLHK Realtime Karhutla & Hotspot Monitor
Sistem pemantau kebakaran hutan & lahan (Karhutla) realtime Kementerian Lingkungan Hidup dan Kehutanan (KLHK). Menyediakan tracking titik panas (Hotspot satelit NASA-MODIS, SNPP, NOAA20), sebaran provinsi, operasi pemadaman Manggala Agni, dan berita bencana resmi.
#sipongi#karhutla#hotspot#klhk#indonesia#gis#scraper#javascript
2
Rawsipongi.jsjavascript
145 lines| 1 | /** |
| 2 | * SiPongi+ Scraper & Realtime Karhutla Monitor |
| 3 | * Base: https://sipongi.gakkum.kehutanan.go.id / https://opsroom.sipongidata.my.id |
| 4 | * Data: Titik Panas (Hotspot), Sebaran Karhutla, Indikasi Luas Kebakaran, Daops Pemadaman, Berita Terkini |
| 5 | */ |
| 6 | |
| 7 | import fetch from 'node-fetch' |
| 8 | |
| 9 | const OPS_API = 'https://opsroom.sipongidata.my.id/api' |
| 10 | const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' |
| 11 | |
| 12 | const defaultHeaders = { |
| 13 | 'User-Agent': USER_AGENT, |
| 14 | 'Accept': 'application/json, text/plain, */*', |
| 15 | 'Referer': 'https://sipongi.gakkum.kehutanan.go.id/' |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * Mengambil ringkasan statistik kebakaran nasional |
| 20 | */ |
| 21 | export async function getSummaryKebakaran() { |
| 22 | try { |
| 23 | const res = await fetch(`${OPS_API}/getSummaryKebakaran`, { headers: defaultHeaders }) |
| 24 | if (!res.ok) throw new Error(`HTTP Error ${res.status}`) |
| 25 | return await res.json() |
| 26 | } catch (e) { |
| 27 | console.error('[SiPongi getSummaryKebakaran Error]:', e.message) |
| 28 | return null |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * Mengambil data titik panas (Hotspot) realtime dari satelit NASA-MODIS, SNPP, & NOAA20 |
| 34 | * @param {Object} options |
| 35 | * @param {number} options.late Jam terakhir (default: 24 jam) |
| 36 | * @param {Array<string>} options.satelit Satelit pemantau |
| 37 | * @param {Array<string>} options.confidence Tingkat kepercayaan ('low', 'medium', 'high') |
| 38 | */ |
| 39 | export async function getRealtimeHotspots({ late = 24, satelit = ['NASA-MODIS', 'NASA-SNPP', 'NASA-NOAA20'], confidence = ['low', 'medium', 'high'] } = {}) { |
| 40 | try { |
| 41 | const params = new URLSearchParams({ |
| 42 | wilayah: 'IN', |
| 43 | filterperiode: 'false', |
| 44 | late: String(late) |
| 45 | }) |
| 46 | satelit.forEach(s => params.append('satelit[]', s)) |
| 47 | confidence.forEach(c => params.append('confidence[]', c)) |
| 48 | |
| 49 | const res = await fetch(`${OPS_API}/opsroom/indoHotspot?${params.toString()}`, { headers: defaultHeaders }) |
| 50 | if (!res.ok) throw new Error(`HTTP Error ${res.status}`) |
| 51 | const geojson = await res.json() |
| 52 | |
| 53 | const features = geojson.features || [] |
| 54 | const provinceCounts = {} |
| 55 | const confidenceCounts = { low: 0, medium: 0, high: 0 } |
| 56 | const satelliteCounts = {} |
| 57 | |
| 58 | features.forEach(f => { |
| 59 | const p = f.properties || {} |
| 60 | const prov = p.nama_provinsi || p.provinsi || 'Lainnya' |
| 61 | const conf = (p.confidence_level || 'low').toLowerCase() |
| 62 | const sat = p.sumber || 'Unknown' |
| 63 | |
| 64 | provinceCounts[prov] = (provinceCounts[prov] || 0) + 1 |
| 65 | confidenceCounts[conf] = (confidenceCounts[conf] || 0) + 1 |
| 66 | satelliteCounts[sat] = (satelliteCounts[sat] || 0) + 1 |
| 67 | }) |
| 68 | |
| 69 | // Sort provinsi berdasarkan titik panas terbanyak |
| 70 | const topProvinces = Object.entries(provinceCounts) |
| 71 | .sort((a, b) => b[1] - a[1]) |
| 72 | .map(([provinsi, count]) => ({ provinsi, count })) |
| 73 | |
| 74 | return { |
| 75 | total_hotspots: features.length, |
| 76 | periode_jam: late, |
| 77 | satellite_counts: satelliteCounts, |
| 78 | confidence_counts: confidenceCounts, |
| 79 | top_provinces: topProvinces, |
| 80 | features |
| 81 | } |
| 82 | } catch (e) { |
| 83 | console.error('[SiPongi getRealtimeHotspots Error]:', e.message) |
| 84 | return null |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Mengambil operasi pemadaman terkini oleh Manggala Agni / Daops |
| 90 | */ |
| 91 | export async function getDaopsPemadaman() { |
| 92 | try { |
| 93 | const res = await fetch(`${OPS_API}/daops/pemadaman`, { headers: defaultHeaders }) |
| 94 | if (!res.ok) throw new Error(`HTTP Error ${res.status}`) |
| 95 | const json = await res.json() |
| 96 | const features = json?.data?.features || [] |
| 97 | return { |
| 98 | total_operasi: features.length, |
| 99 | operations: features.map(f => ({ |
| 100 | id: f.properties?.id, |
| 101 | daops: f.properties?.nama_daops || f.properties?.daops, |
| 102 | provinsi: f.properties?.nama_provinsi || f.properties?.provinsi, |
| 103 | status: f.properties?.status, |
| 104 | tanggal: f.properties?.tanggal, |
| 105 | luas_terbakar: f.properties?.luas_terbakar, |
| 106 | lokasi: f.properties?.lokasi, |
| 107 | koordinat: f.geometry?.coordinates |
| 108 | })) |
| 109 | } |
| 110 | } catch (e) { |
| 111 | console.error('[SiPongi getDaopsPemadaman Error]:', e.message) |
| 112 | return null |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * Mengambil daftar berita terkini Karhutla KLHK / Kemenhut |
| 118 | */ |
| 119 | export async function getBeritaKarhutla(page = 1, perPage = 6) { |
| 120 | try { |
| 121 | const res = await fetch(`${OPS_API}/listBerita?direction=desc&sortBy=created_at&page=${page}&per_page=${perPage}`, { headers: defaultHeaders }) |
| 122 | if (!res.ok) throw new Error(`HTTP Error ${res.status}`) |
| 123 | const json = await res.json() |
| 124 | const items = json.data || [] |
| 125 | return items.map(item => ({ |
| 126 | id: item.id, |
| 127 | title: item.title, |
| 128 | slug: item.slug, |
| 129 | date: item.created_at ? item.created_at.split('T')[0] : '', |
| 130 | image: item.image ? (item.image.startsWith('http') ? item.image : `https://opsroom.sipongidata.my.id/storage/${item.image}`) : null, |
| 131 | content: item.content ? item.content.replace(/<[^>]+>/g, '').trim() : '' |
| 132 | })) |
| 133 | } catch (e) { |
| 134 | console.error('[SiPongi getBeritaKarhutla Error]:', e.message) |
| 135 | return [] |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | export default { |
| 140 | getSummaryKebakaran, |
| 141 | getRealtimeHotspots, |
| 142 | getDaopsPemadaman, |
| 143 | getBeritaKarhutla |
| 144 | } |
| 145 | |
Discussion & Comments0
No comments yet — be the first to leave feedback or start a code discussion.
Sign in with your GitHub account to write comments and join the discussion.