BAB 6: Modeler Lanjut: Mesin dengan Tombol Pengaturan
#Studi kasus: "Sempadan 20, 30, atau 50 meter?"
Kepala Seksi belum memutuskan lebar sempadan sungai. "Coba 20 meter, 30 meter, lalu 50 meter, dan tunjukkan luasnya." Anda ingin satu mesin yang menerima lebar sebagai isian. Rekan Anda juga harus bisa memakainya tanpa menyentuh kode, dan mesin itu harus menolak isian yang tidak masuk akal, misalnya lebar nol.
#Konsep: model lanjut dalam tiga kalimat
Model adalah alur kerja bergambar: kotak masukan, kotak alat, dan panah di antaranya. Model lanjut punya isian (parameter) yang bisa diubah, ekspresi di dalamnya, dan penjaga yang menghentikan model bila masukan tidak layak. Bayangkan mesin cuci dengan tombol pengaturan: mesinnya satu, tetapi hasilnya berbeda menurut pengaturan.
Istilah baru bab ini:
- Masukan model: isian yang diisi pengguna saat model dijalankan.
- Langkah: satu alat di dalam model.
- Penjaga: langkah yang memeriksa syarat dan menghentikan model bila syarat gagal.
- Berkas model (
.model3): berkas tempat model disimpan. - Ekspor skrip: mengubah model menjadi skrip Python.

#Bagian A: QGIS
#Bagian A: Model Designer di QGIS
#A.1 Menyusun model dengan klik
Langkah-langkah ini mengikuti dokumentasi QGIS. Letak tombol di versi Anda bisa sedikit berbeda, dan tampilan visualnya perlu Anda cocokkan. [CEK]
- Buka Processing ► Model Designer. Pada versi lama, menu ini bernama Graphical Modeler. [CEK]
- Beri nama model, misalnya "Sempadan Sungai per KPH".
- Di panel Inputs, tambahkan tiga masukan: Vector Layer berjenis poligon (beri nama KPH), Vector Layer berjenis garis (SUNGAI), dan Number (JARAK) dengan nilai bawaan 30.
- Di panel Algorithms, tambahkan Buffer. Untuk parameter Input, pilih masukan SUNGAI. Untuk Distance, pilih masukan JARAK.
- Tambahkan Intersection. Masukannya KPH dan hasil Buffer.
- Tambahkan Field calculator untuk kolom
LUAS_HAdengan rumusround($area / 10000, 2). - Beri nama keluaran akhir, lalu simpan model sebagai berkas
.model3. - Jalankan dengan Model ► Run Model… (F5).
Hasilnya: sebuah model yang bisa dijalankan berulang dengan lebar berbeda hanya dengan mengubah satu isian.
#A.2 Isian model dan ekspresi
Nilai sebuah parameter langkah dapat berasal dari empat sumber. Nama di tabel adalah nama yang dipakai oleh Python API QGIS. Nama itu sudah dipakai dan terbukti jalan pada Skrip 6.1.
| Sumber nilai | Padanan di Python | Contoh |
|---|---|---|
| Nilai tetap | fromStaticValue(30) | Parameter DISSOLVE selalu benar |
| Masukan model | fromModelParameter("JARAK") | Jarak buffer diisi pengguna |
| Keluaran langkah lain | fromChildOutput(id, "OUTPUT") | Hasil Buffer menjadi masukan Intersection |
| Nilai hasil ekspresi | fromExpression("@JARAK * 2") | Satu angka dihitung dari isian model |
Menurut dokumentasi QGIS, masukan model tersedia sebagai variabel di dalam ekspresi (misalnya @JARAK), dan opsi Pre-calculated Value membuka Expression Builder. [CEK: letak opsi di antarmuka]
#A.3 Penjaga: menghentikan model dengan pesan jelas
Alat Raise exception menghentikan model dengan pesan buatan Anda. Alat ini punya dua parameter: pesan, dan syarat berupa ekspresi. Menurut keterangan alatnya, galat hanya dikeluarkan bila syarat bernilai benar. Pada model Anda, syaratnya @JARAK <= 0.
QGIS juga menyediakan Conditional branch (cabang bersyarat), yang membuat bagian model berjalan hanya bila ekspresinya benar. Kedua alat ini tidak tampil di Processing Toolbox, tetapi terdaftar di QGIS 4.0.2 dan dipakai di Model Designer. [CEK: letaknya di panel Algorithms] Cabang bersyarat diatur di antarmuka, dan perlu Anda coba sendiri.
#A.4 Membangun model lewat Python
Model hanyalah berkas yang bisa dibuat siapa saja, termasuk skrip. Skrip 6.1 membangun model yang sama dengan langkah A.1, lengkap dengan penjaga, lalu menyimpannya sebagai .model3. Salinan hasilnya tersedia di folder skrip/model.
# [SKRIP 6.1: Membangun model "Sempadan Sungai per KPH" lewat Python, simpan sebagai .model3]
# Penulis: Badar Mubarok Yogaswara
# Model ini sama dengan yang bisa Anda gambar di Graphical Modeler; ini hanya cara lain membuatnya.
import os
from qgis.core import (QgsProcessing, QgsProcessingModelAlgorithm, QgsProcessingModelChildAlgorithm,
QgsProcessingModelChildParameterSource as Sumber, QgsProcessingModelParameter,
QgsProcessingModelOutput, QgsProcessingModelChildDependency,
QgsProcessingParameterVectorLayer, QgsProcessingParameterNumber)
DATA = "D:/Latihan/paket-i4"
HASIL = "D:/Latihan/hasil_i4"
os.makedirs(HASIL, exist_ok=True)
m = QgsProcessingModelAlgorithm("Sempadan Sungai per KPH", "Kehutanan")
# --- Masukan model (yang diisi pengguna saat model dijalankan)
m.addModelParameter(QgsProcessingParameterVectorLayer(
"KPH", "Layer batas KPH", [QgsProcessing.TypeVectorPolygon]), QgsProcessingModelParameter("KPH"))
m.addModelParameter(QgsProcessingParameterVectorLayer(
"SUNGAI", "Layer sungai", [QgsProcessing.TypeVectorLine]), QgsProcessingModelParameter("SUNGAI"))
m.addModelParameter(QgsProcessingParameterNumber(
"JARAK", "Lebar sempadan (m)", QgsProcessingParameterNumber.Double, 30),
QgsProcessingModelParameter("JARAK"))
def anak(alat, deskripsi):
c = QgsProcessingModelChildAlgorithm(alat)
c.generateChildId(m)
c.setDescription(deskripsi)
return c
def dari_input(nama):
return [Sumber.fromModelParameter(nama)]
def nilai(v):
return [Sumber.fromStaticValue(v)]
def dari_anak(c, keluaran="OUTPUT"):
return [Sumber.fromChildOutput(c.childId(), keluaran)]
# --- Penjaga: bila JARAK tidak lebih dari 0, model berhenti dengan pesan jelas
henti = anak("native:raiseexception", "Hentikan bila jarak tidak sah")
henti.addParameterSources("MESSAGE", nilai("Lebar sempadan harus lebih dari 0 meter."))
henti.addParameterSources("CONDITION", [Sumber.fromExpression("@JARAK <= 0")])
m.addChildAlgorithm(henti)
# --- Langkah utama: baru berjalan sesudah penjaga lolos
buf = anak("native:buffer", "Penyangga sungai")
buf.addParameterSources("INPUT", dari_input("SUNGAI"))
buf.addParameterSources("DISTANCE", dari_input("JARAK"))
buf.addParameterSources("DISSOLVE", nilai(True))
buf.setDependencies([QgsProcessingModelChildDependency(henti.childId())])
m.addChildAlgorithm(buf)
iris = anak("native:intersection", "Irisan dengan KPH")
iris.addParameterSources("INPUT", dari_input("KPH"))
iris.addParameterSources("OVERLAY", dari_anak(buf))
m.addChildAlgorithm(iris)
luas = anak("native:fieldcalculator", "Hitung luas (ha)")
luas.addParameterSources("INPUT", dari_anak(iris))
luas.addParameterSources("FIELD_NAME", nilai("LUAS_HA"))
luas.addParameterSources("FIELD_TYPE", nilai(0))
luas.addParameterSources("FIELD_LENGTH", nilai(10))
luas.addParameterSources("FIELD_PRECISION", nilai(2))
# rumus dihitung per fitur, jadi diberikan sebagai nilai tetap (teks)
luas.addParameterSources("FORMULA", nilai("round($area / 10000, 2)"))
keluaran = QgsProcessingModelOutput("SEMPADAN", "Sempadan per KPH")
keluaran.setChildOutputName("OUTPUT")
luas.setModelOutputs({"SEMPADAN": keluaran})
m.addChildAlgorithm(luas)
berkas = HASIL + "/Sempadan_Sungai_per_KPH.model3"
print("Model tersimpan?", m.toFile(berkas))
print("Langkah:", [c.description() for c in m.childAlgorithms().values()])
print("Masukan:", [p.name() for p in m.parameterDefinitions()])Hasil uji di QGIS 4.0.2:
Model tersimpan? True
Langkah: ['Penyangga sungai', 'Hitung luas (ha)', 'Irisan dengan KPH', 'Hentikan bila jarak tidak sah']
Masukan: ['KPH', 'SUNGAI', 'JARAK', 'sempadan_per_kph']#A.5 Menjalankan model dari Python
Skrip 6.2 memuat berkas model, lalu menjalankannya tiga kali dengan lebar 20, 30, dan 50 meter. Terakhir, skrip mencoba lebar 0 untuk menguji penjaga.
# [SKRIP 6.2: Menjalankan model .model3 dari Python, berulang dengan jarak berbeda]
# Penulis: Badar Mubarok Yogaswara
# Prasyarat: jalankan SKRIP 6.1 dulu (atau simpan model dari Graphical Modeler dengan nama sama).
import processing
from qgis.core import QgsVectorLayer, QgsProcessingModelAlgorithm, QgsProcessingException
DATA = "D:/Latihan/paket-i4"
HASIL = "D:/Latihan/hasil_i4"
batas = QgsVectorLayer(DATA + "/Batas_KPH.gpkg", "Batas_KPH", "ogr")
sungai = QgsVectorLayer(DATA + "/Sungai.gpkg", "Sungai", "ogr")
# 1. Muat model dari berkas
model = QgsProcessingModelAlgorithm()
print("Model terbaca?", model.fromFile(HASIL + "/Sempadan_Sungai_per_KPH.model3"))
model.initAlgorithm({})
print("Nama model:", model.displayName())
print("Parameter:", [p.name() for p in model.parameterDefinitions()])
# 2. Jalankan berulang dengan tiga lebar sempadan. Model yang sama, angka berbeda.
for jarak in (20, 30, 50):
hasil = processing.run(model, {
"KPH": batas, "SUNGAI": sungai, "JARAK": jarak,
"sempadan_per_kph": "TEMPORARY_OUTPUT"})
lyr = hasil["sempadan_per_kph"]
total = sum(f["LUAS_HA"] for f in lyr.getFeatures())
print("Lebar %2d m -> %d potongan, total %.2f ha" % (jarak, lyr.featureCount(), total))
# 3. Jarak yang tidak sah: model berhenti dan memberi pesan
try:
processing.run(model, {"KPH": batas, "SUNGAI": sungai, "JARAK": 0,
"sempadan_per_kph": "TEMPORARY_OUTPUT"})
print("Jarak 0: model berjalan (tidak seharusnya)")
except QgsProcessingException as e:
print("Jarak 0: model berhenti ->", str(e).replace("\n", " | "))Hasil uji di QGIS 4.0.2:
Model terbaca? True
Nama model: Sempadan Sungai per KPH
Parameter: ['JARAK', 'KPH', 'SUNGAI', 'sempadan_per_kph']
Lebar 20 m -> 3 potongan, total 2.75 ha
Lebar 30 m -> 3 potongan, total 4.07 ha
Lebar 50 m -> 3 potongan, total 6.55 ha
Jarak 0: model berhenti -> Lebar sempadan harus lebih dari 0 meter.Angka dapat dicek silang dengan Bab 2: pada lebar 30 m, jumlah luas tiga petak adalah 1,18 + 1,39 + 1,50 = 4,07 ha, sama dengan hasil Skrip 2.2. Dengan lebar 0, penjaga menghentikan model dan pesannya terbaca jelas.
#A.6 Dari model ke skrip
Menu Model ► Export as Script Algorithm… mengubah model menjadi skrip algoritma Python yang bisa diedit. Bab ini tidak membahasnya lebih jauh. Skrip algoritma menjadi bahan seri M4.
#Bagian B: ArcGIS Pro
#Bagian B: ModelBuilder di ArcGIS Pro
ModelBuilder di Pro punya iterator, yaitu elemen perulangan. Daftarnya antara lain Iterate Feature Selection, Iterate Rasters, Iterate Field Values, Iterate Files, Iterate Datasets, Iterate Feature Classes, Iterate Fields, dan For. Menurut dokumentasi Esri, hanya satu iterator yang dapat dipakai per model. Hasil iterator dipakai sebagai variabel sisipan (misalnya %Name%) pada nama keluaran. [CEK]
Untuk isian, klik kanan variabel lalu jadikan Parameter. Untuk syarat, ModelBuilder punya Preconditions dan alat If Value Is. Model bisa diekspor menjadi skrip Python lewat menu Export. [CEK]
Padanan model Bab 6: Iterate Feature Selection mengulang per petak, sedangkan Buffer dan Intersect sama dengan alat QGIS. Skrip padanannya adalah Skrip 2.1-Pro dan 3.1-Pro. Alat Raise exception tidak ada padanan langsung; penjaga dibuat dengan alat If Value Is atau pemeriksaan di skrip. [CEK]
#Bagian C: ArcMap 10.8
#Bagian C: ModelBuilder di ArcMap 10.8
ModelBuilder di ArcMap juga punya iterator, misalnya Iterate Feature Selection dan Iterate Rasters. Hasilnya dipakai sebagai variabel sisipan seperti %Name% pada nama keluaran. Parameter model dibuat dengan klik kanan variabel. Ekspor ke skrip Python ada di menu Model. [CEK]
Skrip padanan model adalah Skrip 2.1-ArcMap dan 3.1-ArcMap. Penjaga dibuat lewat pemeriksaan di skrip (Skrip 4.1-ArcMap), karena padanan Raise exception tidak ditemukan di dokumentasi yang dibaca. [CEK]
#Cek paham
- Apa guna alat Raise exception di dalam model?
- Bagaimana nilai masukan model dipakai di dalam ekspresi?
- Mengapa menjalankan model dari Python berguna?
Jawaban:
- Menghentikan model dengan pesan jelas bila syarat (ekspresi) bernilai benar, misalnya jarak tidak sah.
- Sebagai variabel dengan awalan
@, misalnya@JARAK. - Agar model bisa diulang dengan banyak nilai dan disambung dengan skrip lain, seperti proyek terpadu di Bab 7.
#Kesalahan umum
- Rumus kolom dijadikan nilai pra-hitung. Berikan rumus per fitur sebagai nilai tetap, bukan hasil ekspresi.
- Salah nama kunci hasil. Nama keluaran model dibentuk dari nama keluaran, bukan selalu
OUTPUT. Periksa denganparameterDefinitions(). - Mencari Raise exception di Processing Toolbox. Alat ini tersembunyi dari toolbox. Cari di Model Designer. [CEK]
- Mengisi jarak pada layer berderajat. Satuan jarak mengikuti CRS layer, jadi pastikan metrik.
#Ringkasan dan latihan
Ringkasan: model lanjut punya masukan, ekspresi, dan penjaga. Model disimpan sebagai .model3, dibangun lewat klik atau Python, dan dijalankan dari Python dengan processing.run(model, parameter). Rumus per fitur diberikan sebagai nilai tetap.
Latihan:
- Ubah Skrip 6.1 agar model menolak
JARAKdi atas 200 (syarat@JARAK <= 0 OR @JARAK > 200). Jalankan dengan jarak 250 dan baca pesannya. - Pada Skrip 6.2, tambahkan jarak 100 m. Perhatikan apakah luas sempadan tiap petak tumbuh sebanding dengan lebarnya.
#Tabel perbandingan: model alur kerja
| Hal | QGIS | ArcGIS Pro | ArcMap 10.8 |
|---|---|---|---|
| Nama alat | Model Designer (dulu Graphical Modeler) [CEK] | ModelBuilder | ModelBuilder |
| Isian model | Masukan model | Parameter model [CEK] | Parameter model [CEK] |
| Perulangan dalam model | Tidak ada alat perulangan di daftar QGIS 4.0.2 | Iterator (satu per model) [CEK] | Iterator [CEK] |
| Penjaga | Raise exception, Conditional branch | Preconditions, If Value Is [CEK] | Preconditions [CEK] |
| Ekspor ke skrip | Export as Script Algorithm | Export ke Python [CEK] | Export ke Python [CEK] |
| Jalankan dari Python | processing.run(model, {...}) (diuji) | Alat model dipanggil seperti alat biasa [CEK] | Alat model dipanggil seperti alat biasa [CEK] |