Lewati ke isi
Profil penulisSeri Buku GIS Kehutanan dan Pertanian/ M4
Tampilkan bagian untuk:

BAB 2: Resep Sekali Tulis, Dipakai Berkali-kali: Processing Script

#Studi kasus: "Petak mana yang paling rawan?"

Musim kemarau tiba. Kepala Seksi minta daftar petak dengan jumlah titik panas dan kerapatannya, dan permintaan itu akan datang tiap minggu. Analis Muda tidak mau mengulang langkah yang sama secara manual. Ia menulis satu alat yang menerima layer petak dan layer titik, lalu mengembalikan petak lengkap dengan kolom jumlah titik, kerapatan, dan tanda rawan. Alat itu tampil di Processing Toolbox, sama seperti alat bawaan.

#Konsep: Processing script dalam tiga kalimat

Processing script adalah berkas Python yang mendaftarkan sebuah algoritma baru ke Processing Toolbox QGIS. Bayangkan resep standar dengan formulir bahan: siapa pun yang mengisi formulir (parameter) akan mendapat hasil yang sama. Karena bentuknya algoritma Processing, alat Anda otomatis bisa dipakai di Toolbox, Modeler, mode batch, dan Python.

Ilustrasi 2.1: Kerangka Processing script
Skema tiga tahap: initAlgorithm memasang parameter, processAlgorithm bekerja, keluaran berupa layer baru

#Anatomi sebuah script

Lima istilah baru, semuanya bagian dari kerangka yang sama:

  • QgsProcessingAlgorithm: kelas induk semua algoritma Processing.
  • Parameter: isian formulir, misalnya layer masukan atau angka batas.
  • Sink: tempat keluaran ditulis. Pengguna memilih layer sementara atau berkas.
  • Feedback: saluran untuk mengirim kemajuan dan pesan ke pengguna.
  • Spatial index: indeks yang mempercepat pencarian titik di dalam poligon.

Metode wajib kelas algoritma: createInstance, name, displayName, initAlgorithm, dan processAlgorithm. Metode group, groupId, dan shortHelpString bersifat pilihan (dokumentasi pengguna QGIS tentang Processing script). Dokumentasi yang sama menganjurkan agar script tidak memuat layer hasil sendiri, tetapi menyerahkannya ke Processing.

#Bagian A: QGIS

#Bagian A: Script Kerapatan Titik Panas di QGIS

Berkas lengkap: skrip/kerapatan_hotspot.py.

  1. Pada panel Processing Toolbox, buka menu Scripts (ikon Python), lalu pilih Create New Script from Template. Templat ini memberi kerangka kosong. [CEK]
  2. Daftarkan parameter di initAlgorithm. Tiga masukan dan satu keluaran:
kerapatan_hotspot.py
def initAlgorithm(self, config=None):
    self.addParameter(QgsProcessingParameterFeatureSource(
        self.PETAK, "Layer petak (poligon)", [QgsProcessing.SourceType.TypeVectorPolygon]))
    self.addParameter(QgsProcessingParameterFeatureSource(
        self.TITIK, "Layer titik panas (titik)", [QgsProcessing.SourceType.TypeVectorPoint]))
    self.addParameter(QgsProcessingParameterNumber(
        self.BATAS, "Batas rawan (titik per hektare)",
        type=QgsProcessingParameterNumber.Type.Double, defaultValue=2.0, minValue=0.0))
    self.addParameter(QgsProcessingParameterFeatureSink(self.HASIL, "Petak dengan kerapatan"))
  1. Di processAlgorithm, samakan CRS titik ke CRS petak, lalu bangun spatial index dari titik:
kerapatan_hotspot.py
ke_petak = QgsCoordinateTransform(titik.sourceCrs(), petak.sourceCrs(), context.transformContext())
indeks = QgsSpatialIndex()
geom = {}
for i, f in enumerate(titik.getFeatures()):
    g = f.geometry()
    g.transform(ke_petak)
    fb = QgsFeature(i)
    fb.setGeometry(g)
    indeks.addFeature(fb)
    geom[i] = g
  1. Masih di processAlgorithm, hitung titik di tiap petak dan tulis ke sink:
kerapatan_hotspot.py
for n, f in enumerate(petak.getFeatures()):
    pg = f.geometry()
    kandidat = indeks.intersects(pg.boundingBox())
    jumlah = sum(1 for k in kandidat if pg.contains(geom[k]))
    luas_ha = pg.area() / 10000.0
    kerapatan = jumlah / luas_ha if luas_ha > 0 else 0.0
    baru = QgsFeature(kolom)
    baru.setGeometry(pg)
    baru.setAttributes(f.attributes() + [jumlah, round(kerapatan, 3), 1 if kerapatan > batas else 0])
    sink.addFeature(baru, QgsFeatureSink.Flag.FastInsert)
    feedback.setProgress(100.0 * (n + 1) / total)

Spatial index mencari titik kandidat lewat kotak pembatas petak. Pengecekan contains lalu memastikan titik benar-benar di dalam poligon.

  1. Simpan berkas di folder scripts profil Anda. Jalurnya %APPDATA%\QGIS\QGIS4\profiles\default\processing\scripts (jalur dicek ada). Alat muncul di Toolbox, grup Kehutanan. [CEK: kemunculan di Toolbox lewat antarmuka tidak dicek]
  2. Jalankan alat dengan Petak_KPH dan Hotspot_Nasional, batas 2. Hasilnya: 16 petak, 12 titik terhitung, dan 1 petak rawan, yaitu P-07 dengan 3 titik per hektare.

Hasilnya: daftar petak lengkap dengan jumlah titik. Per KPH: KPH Alpha 2 titik, KPH Beta 5 titik, KPH Gamma 5 titik.

Ilustrasi 2.2: Satu script, banyak cara memanggil
Skema berkas script masuk ke Processing Toolbox lalu dipanggil dari Modeler, Batch, atau Python

#Memanggil script dari tempat lain

Karena script adalah algoritma Processing, ia bisa dipanggil dengan beberapa cara. Berikut dua yang diuji.

  1. Dari baris perintah dengan qgis_process, memberi jalur berkas script:
qgis_process
qgis_process-qgis.bat run kerapatan_hotspot.py -- PETAK=Petak_KPH.gpkg TITIK=Hotspot_Nasional.gpkg BATAS=2 HASIL=hasil.gpkg
  1. Dari Python (PyQGIS) setelah script didaftarkan ke sebuah provider, seperti di skrip/uji_processing.py:
uji_processing.py
r = processing.run("m4:kerapatan_hotspot", {"PETAK": petak, "TITIK": titik, "BATAS": 0.5, "HASIL": "memory:"})

#Cara ringkas: dekorator @alg

Untuk alat sederhana, QGIS menyediakan dekorator @alg yang menggantikan kelas panjang. Berkas skrip/tambah_luas_ha.py memakainya untuk menambah kolom luas hektare:

tambah_luas_ha.py
@alg(name="tambah_luas_ha", label="Tambah kolom luas (hektare)", group="kehutanan", group_label="Kehutanan")
@alg.input(type=alg.SOURCE, name="INPUT", label="Layer poligon", types=[2])
@alg.input(type=alg.SINK, name="OUTPUT", label="Hasil")
def tambah_luas_ha(instance, parameters, context, feedback, inputs):
    ...

Angka 2 pada types berarti poligon.

Hasil uji: script ini dimuat dari sebuah folder scripts uji, lalu dijalankan dengan Petak_KPH. Keluarannya 16 objek dengan jumlah kolom luas 16,000 ha. Catatan: qgis_process run dengan jalur berkas hanya berhasil untuk script berbentuk kelas. Untuk script @alg, qgis_process menjawab "Algorithm script:tambah_luas_ha not found" pada percobaan penulis; ia perlu berada di folder scripts yang dikenal profil.

#Bagian B: ArcGIS Pro

#Bagian B: ArcGIS Pro

Padanan Processing script adalah script tool atau Python toolbox (Bab 1). Alur menurut dokumentasi Esri: buat toolbox .atbx, klik kanan, pilih New ► Script, lalu arahkan ke berkas Python. [CEK]

Inti pekerjaan yang sama (hitung titik per petak) bisa ditulis dengan alat bawaan:

script_tool.py
import arcpy

petak = arcpy.GetParameterAsText(0)
titik = arcpy.GetParameterAsText(1)
hasil = arcpy.GetParameterAsText(2)

arcpy.analysis.SpatialJoin(petak, titik, hasil, join_operation="JOIN_ONE_TO_ONE",
                           match_option="CONTAINS")
arcpy.management.AddField(hasil, "Titik_per_Ha", "DOUBLE")
arcpy.management.CalculateField(hasil, "Titik_per_Ha", "!Join_Count! / (!Luas_Ha!)", "PYTHON3")
  1. Buat script tool dan tambahkan tiga parameter: layer petak, layer titik, dan keluaran. [CEK]
  2. Hubungkan berkas Python tadi, lalu jalankan dengan data latihan. [CEK]

Hasil yang diharapkan: kolom Join_Count berisi jumlah titik per petak. Bandingkan dengan angka di Bagian A (total 12 titik). [CEK: nama kolom bawaan dan sintaks parameter belum dicocokkan dengan Pro]

#Bagian C: ArcMap 10.8

#Bagian C: ArcMap 10.8

ArcMap mengenal script tool juga, dengan penamaan alat gaya lama dan Python 2.7. Contoh padanan baris SpatialJoin di ArcMap: arcpy.SpatialJoin_analysis(petak, titik, hasil, "JOIN_ONE_TO_ONE", "KEEP_ALL", "", "CONTAINS"). [CEK]

  1. Klik kanan sebuah toolbox, lalu pilih Add ► Script. [CEK]
  2. Ikuti wizard: nama alat, berkas skrip, lalu parameter. [CEK]
  3. Jalankan, lalu cocokkan angka dengan Bagian A. [CEK]

#Cek paham

  1. Apa fungsi initAlgorithm dan processAlgorithm?
  2. Mengapa titik disamakan CRS-nya dengan petak sebelum dihitung?
  3. Apa untungnya script dibuat sebagai algoritma Processing, bukan skrip biasa?

Jawaban:

  1. initAlgorithm memasang parameter. processAlgorithm melakukan pekerjaannya dan mengembalikan keluaran.
  2. Perbandingan "titik di dalam poligon" hanya benar bila keduanya memakai CRS yang sama.
  3. Alat otomatis bisa dipakai di Toolbox, Modeler, batch, dan Python tanpa menulis ulang.

#Kesalahan umum

  • Script tidak muncul di Toolbox. Berkas tidak berada di folder scripts yang dikenal, atau ada galat sintaks. Cek jalur folder dan baca pesan galat.
  • Hasil nol di semua petak. CRS titik dan petak berbeda dan tidak disamakan. Tambahkan transformasi seperti di langkah 3.
  • Script lambat untuk titik banyak. Setiap petak dibandingkan dengan setiap titik. Pakai spatial index.
  • Layer hasil tidak termuat otomatis. Itu wajar. Script cukup mengembalikan sink; Processing yang memuatnya.

#Ringkasan dan latihan

Ringkasan: Processing script adalah algoritma Python yang tampil di Toolbox. Kerangkanya: parameter, pekerjaan, keluaran. Sekali ditulis, ia bisa dipanggil dari Toolbox, Modeler, batch, qgis_process, dan Python.

Latihan: Tambahkan parameter ketiga berupa pilihan KPH (misalnya KPH Gamma) supaya hasil hanya memuat petak KPH itu. (Petunjuk: filter di dalam loop petak; untuk KPH Gamma hasilnya 8 petak dengan total 5 titik.)

#Tabel perbandingan: alat analisis kustom

HalQGISArcGIS ProArcMap 10.8
Bentuk alatProcessing scriptScript tool atau Python toolboxScript tool atau Python toolbox
Tempat tampilProcessing ToolboxPanel GeoprocessingArcToolbox
Dipanggil dari Pythonprocessing.runarcpy.<modul>.<Alat>arcpy.<Alat>_<modul>
Dipanggil dari baris perintahqgis_processTidak ada padanan setara [CEK]Tidak ada padanan setara [CEK]