Empat pendekatan yang sering dianggap sama padahal beda konsep, dan kapan masing-masing dipakai, menggunakan package terra.
Daftar Isi
Empat pendekatan yang sering dianggap sama padahal beda konsep, dan kapan masing-masing dipakai, menggunakan package terra.
Setelah sebuah indeks raster selesai dihitung dan berbentuk nilai kontinu, ada beberapa teknik yang bisa dipakai untuk mengolahnya lebih lanjut berdasarkan nilai piksel: thresholding, reclassification, masking, dan clamping.
Keempatnya sering dibahas berdampingan karena sama-sama "membatasi" atau "mengelompokkan" raster berdasarkan nilai, tapi secara konsep berbeda dan menghasilkan raster dengan karakteristik berbeda pula.
Repo ini membahas keempat kategori teknik itu menggunakan package terra di R, dengan AWEI (Automated Water Extraction Index) sebagai studi kasus.
Sebagai konteks, AWEI adalah indeks kontinu yang bisa bernilai negatif maupun positif, dengan konvensi umum nilai positif cenderung piksel air dan nilai negatif cenderung non-air (Feyisa et al., 2014). Titik potongnya bisa dicek dari histogram data yang digunakan, dan tidak selalu tepat di angka 0.
Legend default dari plot() tidak selalu menampilkan tick yang mencerminkan sebaran nilai asli raster. Tick-nya bisa dihitung eksplisit dari nilai minimum dan maksimum aktual data.
library(terra)
r <- rast("D:/TUTOR AWEI/AWEI_sh.tif")
r_min <- minmax(r)[1, 1]
r_max <- minmax(r)[2, 1]
ticks <- seq(r_min, r_max, length.out = 10)
plot(r,
col = hcl.colors(50, "GnBu", rev = TRUE),
main = "AWEIsh — Raw Continuous Value",
plg = list(at = ticks, labels = round(ticks, 3)))
minmax(r) mengembalikan matriks dua baris (min, max) satu kolom per layer raster. Karena r cuma satu layer, minmax(r)[1, 1] mengambil nilai minimum aktual data, minmax(r)[2, 1] mengambil nilai maksimum aktualnya — bukan angka yang ditebak manual. seq(r_min, r_max, length.out = 10) membuat 10 titik tick yang terbagi rata dari nilai min ke max aktual.
Argumen plg (plot legend) pada plot() versi terra dipakai untuk mengatur tampilan color bar/legend: at menentukan posisi tick sesuai nilai ticks yang sudah dihitung, labels menentukan teks yang tampil di tiap tick (dibulatkan 3 desimal pakai round()). Hasilnya, legend menampilkan 10 label tick yang mencerminkan sebaran nilai asli raster, dari minimum sampai maksimum data.
classify() adalah fungsi reclassification: mengubah raster kontinu jadi raster kategorikal berdasarkan tabel rentang nilai. Threshold di sini berperan sebagai titik potong antar kelas, tapi hasil akhirnya bukan biner TRUE/FALSE — melainkan label kelas.
r_bin <- classify(
r,
rcl = matrix(c(-Inf, 0, 0,
0, Inf, 1),
ncol = 2, byrow = TRUE),
include.lowest = TRUE
)
plot(r_bin, col = c("lightgrey", "blue"))
Argumen rcl adalah matriks tiga kolom: batas bawah, batas atas, dan nilai kelas baru untuk rentang tersebut. Baris pertama berarti "semua nilai dari -Inf sampai 0 diubah jadi 0", baris kedua "semua nilai dari 0 sampai Inf diubah jadi 1". include.lowest = TRUE memastikan nilai persis di batas (0) ikut terhitung, bukan terlewat. Hasilnya, r_bin cuma berisi dua nilai: 0 dan 1.
classify() tidak terbatas pada dua kelas, bisa menghasilkan beberapa kelas sekaligus dalam satu langkah, dengan threshold sebagai titik potong antar tiap kelas.
r_multiclass <- classify(
r,
rcl = matrix(c(-Inf, -0.2, 1,
-0.2, 0.2, 2,
0.2, Inf, 3),
ncol = 3, byrow = TRUE),
include.lowest = TRUE
)
plot(r_multiclass, col = c("lightgray", "blue", "navy"),
main = "Reclassify 3 Kelas")
Di sini rcl punya tiga baris, jadi tiga rentang nilai dipetakan ke tiga kelas berbeda (1, 2, 3). Prinsipnya sama seperti reclassify biner, cuma jumlah barisnya menyesuaikan jumlah kelas yang diinginkan. Setelah reclassify, nilai asli setiap piksel tidak lagi tersimpan — yang tersisa hanya label kelas.
Operator perbandingan (>, <, >=, dll.) adalah bentuk thresholding paling langsung: satu nilai ambang, hasilnya biner. Diterapkan ke SpatRaster, operator ini menghasilkan raster baru bertipe logical.
r_logical <- r > 0
plot(r_logical, col = c("grey", "blue"),
main = "Perbandingan Langsung (TRUE/FALSE)")
class(values(r_logical))
r > 0 mengevaluasi setiap piksel: TRUE kalau nilainya lebih dari 0, FALSE kalau tidak. values(r_logical) mengambil nilai piksel sebagai vektor, dan class() menunjukkan tipe datanya berupa logical.
Secara nilai, ini setara dengan hasil reclassify biner (FALSE ≈ 0, TRUE ≈ 1), tapi didapat langsung dari satu ambang tanpa matriks reclassification.
Kalau raster logical ini mau disimpan sebagai output akhir, tipe datanya bisa dikonversi eksplisit ke numerik:
r_bin_from_logical <- as.numeric(r_logical)
as.numeric() di sini mengubah tipe piksel dari logical menjadi numerik (0/1), supaya kompatibel kalau dibaca software GIS lain yang tidak mengenali tipe logical.
ifel() juga bentuk thresholding, kondisinya tetap berupa perbandingan terhadap satu ambang, tapi nilai penggantinya tidak harus berupa label kelas. Nilai bisa dipertahankan tetap kontinu.
r_masked <- ifel(r > 0, r, NA)
plot(r_masked, col = hcl.colors(50, "RdBu", rev = TRUE))
ifel(kondisi, nilai_jika_benar, nilai_jika_salah) — di sini, kalau r > 0 benar, piksel mempertahankan nilai aslinya (r); kalau salah, piksel diisi NA. Berbeda dari classify(), tidak ada nilai yang diseragamkan menjadi label kelas.
Ambangnya bisa diganti sesuai kebutuhan, misalnya:
r_masked_strict <- ifel(r > 0.2, r, NA)
plot(r_masked_strict, col = hcl.colors(50, "RdBu"))
vect() membaca file vektor (shapefile) menjadi objek SpatVector. Tanpa argumen maskvalues, mask(r, aoi) secara default mempertahankan piksel yang berada di dalam geometri aoi dan menjadikan NA piksel di luarnya. Dengan demikian, raster r hanya akan mempertahankan nilai piksel yang berada di dalam batas Area of Interest (AOI) yang ditentukan oleh Sketches.shp. Pastikan Coordinate Reference System (CRS) antara raster dan AOI sesuai agar proses masking dilakukan pada lokasi yang tepat.
library(terra)
aoi <- vect("D:/TUTOR AWEI/Sketches.shp")
aoi <- project(aoi, crs(r))
r_masked_aoi <- mask(r, aoi)
plot(r_masked_aoi)
Argumen pertama (r) adalah raster yang mau di-mask, argumen kedua (r_logical) adalah raster acuan, dan maskvalues = FALSE berarti piksel pada raster acuan yang bernilai FALSE akan diubah jadi NA pada raster hasil. Perlu dicatat, r_logical di sini sendiri adalah hasil thresholding dari bagian sebelumnya, jadi mask() pada contoh ini hanya menerapkan hasil threshold yang sudah dibuat sebelumnya, bukan melakukan thresholding baru.
r_masked_alt <- mask(r, r_logical, maskvalues = FALSE)
plot(r_masked_alt)
clamp() juga bukan thresholding, ini clamping (kadang disebut capping atau winsorizing): menekan nilai piksel yang berada di luar rentang tertentu ke batas rentang itu, tanpa menghapus piksel maupun mengubahnya jadi label kelas.
r_clamped <- clamp(r, lower = 0, upper = 1, values = TRUE)
plot(r_clamped, col = hcl.colors(50, "RdBu"))
lower dan upper menentukan batas bawah dan atas rentang nilai. values = TRUE berarti piksel di luar rentang diganti dengan nilai batas terdekat; kalau values = FALSE, piksel di luar rentang akan jadi NA alih-alih dipotong ke batas.
Masih dalam kategori thresholding, tapi ambangnya tidak ditulis manual sebagai angka tetap — dihitung dari statistik raster yang sedang diproses.
q <- global(r, fun = quantile, probs = 0.75, na.rm = TRUE)[1, 1]
r_adaptive <- ifel(r > q, r, NA)
plot(r_adaptive, col = hcl.colors(50, "RdBu", rev = TRUE),
main = paste0("Threshold Adaptif (>Q75 = ", round(q, 3), ")"))
global() menghitung statistik ringkasan dari seluruh piksel raster; di sini fungsinya quantile dengan probs = 0.75, jadi menghasilkan nilai kuantil ke-75 dari sebaran nilai raster, dengan na.rm = TRUE mengabaikan piksel NA dalam perhitungan. Hasilnya berupa data frame satu baris satu kolom, diambil nilainya dengan [1, 1]. Nilai q ini kemudian dipakai sebagai ambang di ifel(), sehingga ambangnya menyesuaikan sebaran nilai pada raster yang sedang diproses, bukan angka yang sama untuk semua citra.
| Teknik | Fungsi terra | Kategori | Nilai kontinu? | Cakupan spasial |
|---|---|---|---|---|
| Reclassify 2 kelas | classify() |
Reclassification | Hilang | Penuh |
| Reclassify multi-kelas | classify() |
Reclassification | Hilang | Penuh |
| Operator perbandingan | >, <, dst. |
Thresholding | Hilang | Penuh |
| Filter kondisional | ifel() |
Thresholding | Dipertahankan | Menyempit (NA di luar ambang) |
| Mask referensi eksternal | mask() |
Masking | Dipertahankan | Sesuai raster/vektor acuan |
| Pembatasan rentang | clamp() |
Clamping | Dipertahankan | Penuh (tidak ada NA baru, kecuali values = FALSE) |
| Threshold adaptif | global() + ifel() |
Thresholding | Dipertahankan | Menyempit (NA di luar ambang) |
ifel(), dan threshold adaptif: piksel dievaluasi terhadap satu nilai ambang, hasilnya bisa biner (logical) atau tetap kontinu tergantung fungsinya.classify(): nilai kontinu dikelompokkan jadi label kelas berdasarkan rentang, threshold jadi salah satu komponen di dalamnya (titik potong antar kelas).mask(): piksel dipertahankan/disembunyikan berdasarkan kriteria dari raster atau vektor referensi lain, bukan dari pembandingan nilai raster itu sendiri.clamp(): rentang nilai dibatasi tanpa mengubah piksel jadi label kelas atau menyembunyikannya (kecuali diatur eksplisit).Feyisa, G. L., Meilby, H., Fensholt, R., & Proud, S. R. (2014). Automated Water Extraction Index: A new technique for surface water mapping using Landsat imagery. Remote Sensing of Environment, 140, 23–35. https://doi.org/10.1016/j.rse.2013.08.029
Hijmans, R. J., Brown, A., Barbosa, A. M., Cordano, E., & Dyba, K. (2026). terra: Spatial Data Analysis. R package version 1.9-40.
https://github.com/Defani/raster-logic-terra-r