Back to Home
Gistify Snippet
kyiov
3h ago·1 file(s)
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
Raw
sipongi.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
7import fetch from 'node-fetch'
8
9const OPS_API = 'https://opsroom.sipongidata.my.id/api'
10const 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
12const 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 */
21export 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 */
39export 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 */
91export 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 */
119export 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
139export 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.