Pengantar pemrograman fungsional
Earth Engine menggunakan sistem pemrosesan paralel untuk melakukan komputasi di sejumlah besar mesin. Untuk mengaktifkan pemrosesan tersebut, Earth Engine memanfaatkan teknik standar yang umumnya digunakan oleh bahasa fungsional, seperti transparansi referensial dan evaluasi lambat, untuk mendapatkan pengoptimalan dan efisiensi yang signifikan.
Konsep utama yang membedakan pemrograman fungsional dari pemrograman prosedural adalah tidak adanya efek samping. Artinya, fungsi yang Anda tulis tidak bergantung pada atau memperbarui data yang berada di luar fungsi. Seperti yang akan Anda lihat dalam contoh di bawah, Anda dapat menyusun ulang masalah sehingga dapat diselesaikan menggunakan fungsi tanpa efek samping, yang lebih cocok untuk dieksekusi secara paralel.
Loop For
Penggunaan loop for tidak disarankan di Earth Engine. Hasil yang sama dapat dicapai menggunakan operasi
map()
dengan menentukan fungsi yang
dapat diterapkan secara independen ke setiap elemen. Hal ini memungkinkan sistem mendistribusikan pemrosesan ke
mesin yang berbeda.
Contoh di bawah mengilustrasikan cara mengambil daftar angka dan membuat daftar lain dengan
kuadrat setiap angka menggunakan map()
:
Code Editor (JavaScript)
// This generates a list of numbers from 1 to 10. var myList = ee.List.sequence(1, 10); // The map() operation takes a function that works on each element independently // and returns a value. You define a function that can be applied to the input. var computeSquares = function(number) { // We define the operation using the EE API. return ee.Number(number).pow(2); }; // Apply your function to each item in the list by using the map() function. var squares = myList.map(computeSquares); print(squares); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
Kondisi If/Else
Masalah umum lain yang dihadapi oleh pengguna baru yang terbiasa dengan paradigma
pemrograman prosedural adalah penggunaan operator kondisional if/else yang tepat di Earth Engine. Meskipun API
menyediakan algoritma ee.Algorithms.If()
, penggunaannya sangat tidak disarankan
dan lebih baik menggunakan pendekatan yang lebih fungsional menggunakan map()
dan filter.
Earth Engine menggunakan
eksekusi tertunda, yang berarti evaluasi ekspresi ditunda hingga
nilai yang direalisasikan benar-benar diperlukan. Dalam beberapa kasus, jenis model eksekusi ini akan mengevaluasi
alternatif benar dan salah dari pernyataan ee.Algorithms.If()
. Hal ini dapat
menyebabkan penggunaan komputasi dan memori tambahan, bergantung pada ekspresi dan resource
yang diperlukan untuk mengeksekusinya.
Misalnya, Anda ingin menyelesaikan varian contoh di atas, dengan tugas menghitung kuadrat hanya bilangan ganjil. Pendekatan fungsional untuk menyelesaikan masalah ini tanpa kondisi if/else, ditunjukkan di bawah:
Code Editor (JavaScript)
// The following function determines if a number is even or odd. The mod(2) // function returns 0 if the number is even and 1 if it is odd (the remainder // after dividing by 2). The input is multiplied by this remainder so even // numbers get set to 0 and odd numbers are left unchanged. var getOddNumbers = function(number) { number = ee.Number(number); // Cast the input to a Number so we can use mod. var remainder = number.mod(2); return number.multiply(remainder); }; var newList = myList.map(getOddNumbers); // Remove the 0 values. var oddNumbers = newList.removeAll([0]); var squares = oddNumbers.map(computeSquares); print(squares); // [1, 9, 25, 49, 81]
Paradigma ini sangat berlaku saat bekerja dengan koleksi. Jika Anda ingin menerapkan
algoritma yang berbeda ke koleksi berdasarkan beberapa kondisi, cara yang lebih disukai adalah dengan
memfilter koleksi berdasarkan kondisi terlebih dahulu, lalu map()
fungsi yang berbeda ke
setiap subset. Hal ini memungkinkan sistem memparalelkan operasi. Contoh:
Code Editor (JavaScript)
// Import Landsat 8 TOA collection and filter to 2018 images. var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterDate('2018-01-01', '2019-01-01'); // Divide the collection into 2 subsets and apply a different algorithm on them. var subset1 = collection.filter(ee.Filter.lt('SUN_ELEVATION', 40)); var subset2 = collection.filter(ee.Filter.gte('SUN_ELEVATION', 40)); // Multiply all images in subset1 collection by 2; // do nothing to subset2 collection. var processed1 = subset1.map(function(image) { return image.multiply(2); }); var processed2 = subset2; // Merge the collections to get a single collection. var final = processed1.merge(processed2); print('Original collection size', collection.size()); print('Processed collection size', final.size());
Iterasi Kumulatif
Anda mungkin perlu melakukan operasi berurutan, di mana hasil setiap iterasi digunakan oleh iterasi berikutnya. Earth Engine menyediakan metode iterate()
untuk tugas tersebut. Ingatlah bahwa iterate()
dieksekusi secara berurutan dan
oleh karena itu akan lambat untuk operasi besar. Gunakan hanya jika Anda tidak dapat menggunakan map()
dan filter untuk mendapatkan output yang diinginkan.
Contoh yang baik dari iterate()
adalah pembuatan deret bilangan Fibonacci. Di sini, setiap
angka dalam deret adalah jumlah dari 2 angka sebelumnya. Fungsi iterate()
menggunakan 2
argumen, fungsi (algoritma) dan nilai awal. Fungsi itu sendiri meneruskan 2 nilai,
nilai saat ini dalam iterasi, dan hasil iterasi sebelumnya. Contoh berikut
menunjukkan cara menerapkan deret fibonacci di Earth Engine.
Code Editor (JavaScript)
var algorithm = function(current, previous) { previous = ee.List(previous); var n1 = ee.Number(previous.get(-1)); var n2 = ee.Number(previous.get(-2)); return previous.add(n1.add(n2)); }; // Compute 10 iterations. var numIteration = ee.List.repeat(1, 10); var start = [0, 1]; var sequence = numIteration.iterate(algorithm, start); print(sequence); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Setelah memahami konsep javascript dengan baik, Anda dapat melihat Tutorial API untuk pengantar fungsionalitas geospasial Earth Engine API.