Fonksiyonel programa giriş
Earth Engine, çok sayıda makinede hesaplama yapmak için paralel işleme sistemi kullanır. Earth Engine, bu tür bir işlemeyi etkinleştirmek için önemli optimizasyon ve verimlilik kazanımları sağlamak üzere referans şeffaflığı ve tembel değerlendirme gibi işlevsel diller tarafından yaygın olarak kullanılan standart tekniklerden yararlanır.
Fonksiyonel programlamayı prosedürel programlamadan ayıran temel kavram yan etkilerin olmamasıdır. Yazdığınız işlevlerin, işlevin dışında kalan verilere dayanmadığı veya bu verileri güncellemediği anlamına gelir. Aşağıdaki örneklerde de göreceğiniz gibi, sorununuzu yan etkileri olmayan işlevler kullanılarak çözülebilecek şekilde yeniden yapılandırmak mümkündür. Bu işlevler, paralel olarak yürütülmeye çok daha uygundur.
For Döngüleri
Earth Engine'de for döngülerinin kullanılması önerilmez. Aynı sonuçlar, her öğeye bağımsız olarak uygulanabilecek bir işlev belirttiğiniz map()
işlemi kullanılarak da elde edilebilir. Bu sayede sistem, işlemeyi farklı makinelere dağıtabilir.
Aşağıdaki örnekte, map()
kullanarak bir sayı listesini nasıl alıp her sayının karesini içeren başka bir liste oluşturacağınız gösterilmektedir:
Kod Düzenleyici (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]
Eğer/Değilse Koşulları
Prosedürel programlama paradigmasına alışkın yeni kullanıcıların karşılaştığı bir diğer yaygın sorun ise Earth Engine'de if/else koşullu operatörlerinin doğru şekilde kullanılmasıdır. API, ee.Algorithms.If()
algoritması sağlasa da map()
ve filtrelerin kullanıldığı daha işlevsel bir yaklaşım tercih edilmesi kesinlikle önerilir.
Earth Engine,
ertelenmiş yürütme kullanır. Bu, bir ifadenin değerlendirilmesinin, gerçek değeri gerçekten gerekene kadar ertelendiği anlamına gelir. Bazı durumlarda, bu tür bir yürütme modeli, ee.Algorithms.If()
ifadesinin hem doğru hem de yanlış alternatiflerini değerlendirir. Bu durum, ifadeler ve bunları yürütmek için gereken kaynaklara bağlı olarak ek hesaplama ve bellek kullanımına yol açabilir.
Yukarıdaki örneğin bir varyantını çözmek istediğinizi varsayalım. Bu varyantta görev, yalnızca tek sayıların karelerini hesaplamaktır. Bu sorunu if/else koşulları olmadan çözmeye yönelik işlevsel bir yaklaşım aşağıda gösterilmektedir:
Kod Düzenleyici (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]
Bu paradigma özellikle koleksiyonlarla çalışırken geçerlidir. Koleksiyona bazı koşullara göre farklı bir algoritma uygulamak istiyorsanız tercih edilen yöntem, önce koleksiyonu koşula göre filtrelemek ve ardından her bir alt kümeye farklı bir işlev map()
uygulamaktır. Bu, sistemin işlemi paralelleştirmesine olanak tanır. Örneğin:
Kod Düzenleyici (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());
Kümülatif yineleme
Her yinelemenin sonucunun sonraki yineleme tarafından kullanıldığı sıralı işlem yapmanız gerekebilir. Earth Engine, bu tür görevler için iterate()
yöntemi sunar. iterate()
'nın sıralı bir şekilde yürütüldüğünü ve bu nedenle büyük işlemler için yavaş olacağını unutmayın. Yalnızca map()
ve filtreleri kullanarak istediğiniz sonucu elde edemediğinizde kullanın.
iterate()
için iyi bir örnek, Fibonacci sayı dizisinin oluşturulmasıdır. Burada, serideki her sayı önceki 2 sayının toplamıdır. iterate()
işlevi, bir işlev (algoritma) ve bir başlangıç değeri olmak üzere 2 bağımsız değişken alır. İşlevin kendisine 2 değer iletilir:
iterasyondaki mevcut değer ve önceki iterasyonun sonucu. Aşağıdaki örnekte, Earth Engine'de Fibonacci dizisinin nasıl uygulanacağı gösterilmektedir.
Kod Düzenleyici (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]
JavaScript kavramlarını iyi anladığınıza göre, Earth Engine API'nin coğrafi uzamsal işlevlerine giriş yapmak için API Eğitimini inceleyebilirsiniz.