# -*- coding: utf-8 -*-
# Penulis: Badar Mubarok Yogaswara. Membuat model "Areal Efektif" lewat Python (setara dengan menyusunnya di Model Designer).
# Jalankan di Python Console QGIS. Hasil: berkas areal_efektif.model3 di folder HASIL.
from qgis.core import (QgsProcessingModelAlgorithm, QgsProcessingModelParameter, QgsProcessingModelChildAlgorithm,
                       QgsProcessingModelChildParameterSource, QgsProcessingModelOutput,
                       QgsProcessingParameterFeatureSource, QgsProcessingParameterNumber, QgsProcessing)

HASIL = r"C:\latihan\hasil"      # ubah sesuai komputer Anda; folder dibuat bila belum ada
import os
os.makedirs(HASIL, exist_ok=True)

m = QgsProcessingModelAlgorithm()
m.setName("areal_efektif")
m.setGroup("Latihan I1")

# --- Masukan model (yang diisi pengguna saat menjalankan)
p = QgsProcessingParameterFeatureSource("PETAK", "Petak", [QgsProcessing.TypeVectorPolygon])
m.addModelParameter(p, QgsProcessingModelParameter("PETAK"))
p = QgsProcessingParameterFeatureSource("SUNGAI", "Sungai", [QgsProcessing.TypeVectorLine])
m.addModelParameter(p, QgsProcessingModelParameter("SUNGAI"))
p = QgsProcessingParameterFeatureSource("PERMUKIMAN", "Permukiman", [QgsProcessing.TypeVectorPolygon])
m.addModelParameter(p, QgsProcessingModelParameter("PERMUKIMAN"))
p = QgsProcessingParameterNumber("JARAK_SUNGAI", "Jarak aman sungai (m)", QgsProcessingParameterNumber.Double, 25)
m.addModelParameter(p, QgsProcessingModelParameter("JARAK_SUNGAI"))
p = QgsProcessingParameterNumber("JARAK_PERMUKIMAN", "Jarak aman permukiman (m)", QgsProcessingParameterNumber.Double, 20)
m.addModelParameter(p, QgsProcessingModelParameter("JARAK_PERMUKIMAN"))

MP = QgsProcessingModelChildParameterSource


def langkah(id_, alg, deskripsi, params):
    c = QgsProcessingModelChildAlgorithm(alg)
    c.setChildId(id_)
    c.setDescription(deskripsi)
    for k, v in params.items():
        c.addParameterSources(k, [v])
    return c


# --- Langkah 1 dan 2: buffer sungai dan permukiman (dengan dissolve)
m.addChildAlgorithm(langkah("buf_sungai", "native:buffer", "Buffer sungai", {
    "INPUT": MP.fromModelParameter("SUNGAI"), "DISTANCE": MP.fromModelParameter("JARAK_SUNGAI"),
    "DISSOLVE": MP.fromStaticValue(True)}))
m.addChildAlgorithm(langkah("buf_kampung", "native:buffer", "Buffer permukiman", {
    "INPUT": MP.fromModelParameter("PERMUKIMAN"), "DISTANCE": MP.fromModelParameter("JARAK_PERMUKIMAN"),
    "DISSOLVE": MP.fromStaticValue(True)}))
# --- Langkah 3: petak dikurangi sempadan sungai
m.addChildAlgorithm(langkah("kurang_sungai", "native:difference", "Petak dikurangi sempadan", {
    "INPUT": MP.fromModelParameter("PETAK"), "OVERLAY": MP.fromChildOutput("buf_sungai", "OUTPUT")}))
# --- Langkah 4: hasilnya dikurangi zona permukiman (keluaran model: Petak_Efektif)
c4 = langkah("petak_efektif", "native:difference", "Dikurangi zona permukiman", {
    "INPUT": MP.fromChildOutput("kurang_sungai", "OUTPUT"), "OVERLAY": MP.fromChildOutput("buf_kampung", "OUTPUT")})
c4.setModelOutputs({"Petak_Efektif": QgsProcessingModelOutput("Petak_Efektif", "Petak_Efektif")})
c4.modelOutput("Petak_Efektif").setChildId("petak_efektif")
c4.modelOutput("Petak_Efektif").setChildOutputName("OUTPUT")
m.addChildAlgorithm(c4)
# --- Langkah 5: dissolve per jenis (keluaran model: Efektif_per_Jenis)
c5 = langkah("per_jenis", "native:dissolve", "Dissolve per jenis", {
    "INPUT": MP.fromChildOutput("petak_efektif", "OUTPUT"), "FIELD": MP.fromStaticValue(["JENIS"])})
c5.setModelOutputs({"Efektif_per_Jenis": QgsProcessingModelOutput("Efektif_per_Jenis", "Efektif_per_Jenis")})
c5.modelOutput("Efektif_per_Jenis").setChildId("per_jenis")
c5.modelOutput("Efektif_per_Jenis").setChildOutputName("OUTPUT")
m.addChildAlgorithm(c5)

berkas = os.path.join(HASIL, "areal_efektif.model3")
print("Simpan model:", m.toFile(berkas), berkas)
print("Langkah:", [c.description() for c in m.childAlgorithms().values()])
