ข้อมูลเบื้องต้นเกี่ยวกับการเขียนโปรแกรมเชิงฟังก์ชัน
Earth Engine ใช้ระบบการประมวลผลแบบขนานเพื่อทำการคำนวณในเครื่องจำนวนมาก Earth Engine ใช้เทคนิคมาตรฐานที่ภาษาฟังก์ชันใช้กันโดยทั่วไป เช่น ความโปร่งใสในการอ้างอิงและการประเมินแบบเลื่อนเวลา เพื่อให้การเพิ่มประสิทธิภาพและประสิทธิภาพเพิ่มขึ้นอย่างมาก
แนวคิดหลักที่ทำให้การเขียนโปรแกรมเชิงฟังก์ชันแตกต่างจากการเขียนโปรแกรมเชิงกระบวนการคือการไม่มีผลข้างเคียง ซึ่งหมายความว่าฟังก์ชันที่คุณเขียนจะไม่ขึ้นอยู่กับหรือ อัปเดตข้อมูลที่อยู่นอกฟังก์ชัน ดังที่คุณจะเห็นในตัวอย่างด้านล่าง คุณสามารถ จัดโครงสร้างปัญหาใหม่เพื่อให้แก้ปัญหาได้โดยใช้ฟังก์ชันที่ไม่มีผลข้างเคียง ซึ่ง เหมาะกับการดำเนินการแบบขนานมากกว่า
สำหรับ Loops
ไม่แนะนำให้ใช้ลูป for ใน Earth Engine คุณสามารถได้ผลลัพธ์เดียวกันโดยใช้map()
การดำเนินการที่คุณระบุฟังก์ชันที่ใช้กับแต่ละองค์ประกอบได้อย่างอิสระ
ซึ่งจะช่วยให้ระบบกระจายการประมวลผลไปยัง
เครื่องต่างๆ ได้
ตัวอย่างด้านล่างแสดงวิธีใช้รายการตัวเลขและสร้างรายการอื่นที่มี
กำลังสองของแต่ละหมายเลขโดยใช้ map()
โปรแกรมแก้ไขโค้ด (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]
เงื่อนไข If/Else
ปัญหาที่พบบ่อยอีกอย่างสำหรับผู้ใช้ใหม่ที่คุ้นเคยกับกระบวนการ
รูปแบบการเขียนโปรแกรมคือการใช้โอเปอเรเตอร์แบบมีเงื่อนไข if/else อย่างเหมาะสมใน Earth Engine แม้ว่า API
จะมีee.Algorithms.If()
อัลกอริทึม แต่เราไม่แนะนำให้ใช้
และสนับสนุนให้ใช้วิธีการที่ใช้งานได้จริงมากกว่าโดยใช้ map()
และตัวกรอง
Earth Engine ใช้
การดำเนินการที่เลื่อนออกไป ซึ่งหมายความว่าการประเมินนิพจน์จะล่าช้าจนกว่าจะมีการ
ต้องใช้ค่าจริง ในบางกรณี รูปแบบการดำเนินการประเภทนี้จะประเมิน
ทั้งทางเลือกที่เป็นจริงและเท็จของคำสั่ง ee.Algorithms.If()
ซึ่งอาจ
ส่งผลให้มีการคำนวณและการใช้หน่วยความจำเพิ่มเติม ทั้งนี้ขึ้นอยู่กับนิพจน์และทรัพยากร
ที่จำเป็นต่อการดำเนินการ
สมมติว่าคุณต้องการแก้โจทย์ที่คล้ายกับตัวอย่างข้างต้น โดยงานคือการคำนวณกำลังสองของ เฉพาะจำนวนคี่ วิธีการแก้ปัญหานี้โดยใช้ฟังก์ชันโดยไม่มีเงื่อนไข if/else แสดงไว้ ด้านล่าง
โปรแกรมแก้ไขโค้ด (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]
โดยเฉพาะอย่างยิ่งเมื่อทำงานกับคอลเล็กชัน หากต้องการใช้
อัลกอริทึมอื่นกับคอลเล็กชันตามเงื่อนไขบางอย่าง วิธีที่แนะนำคือกรอง
คอลเล็กชันตามเงื่อนไขก่อน แล้วจึงใช้map()
ฟังก์ชันอื่นกับ
ชุดย่อยแต่ละชุด ซึ่งจะช่วยให้ระบบดำเนินการแบบขนานได้ ตัวอย่าง
โปรแกรมแก้ไขโค้ด (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());
การทำซ้ำแบบสะสม
คุณอาจต้องดำเนินการตามลำดับ โดยการวนซ้ำครั้งถัดไปจะใช้ผลลัพธ์ของ
การวนซ้ำแต่ละครั้ง Earth Engine มีเมธอด iterate()
สำหรับงานดังกล่าว โปรดทราบว่า iterate()
จะดำเนินการตามลำดับและ
จึงจะช้าสำหรับการดำเนินการขนาดใหญ่ ใช้เฉพาะในกรณีที่คุณใช้ map()
และตัวกรองเพื่อให้ได้เอาต์พุตที่ต้องการไม่ได้
ตัวอย่างที่ดีของ iterate()
คือการสร้างลำดับตัวเลขฟีโบนักชี ในที่นี้ ตัวเลขแต่ละตัวในลำดับคือผลรวมของตัวเลข 2 ตัวก่อนหน้า ฟังก์ชัน iterate()
มีอาร์กิวเมนต์ 2 รายการ
คือฟังก์ชัน (อัลกอริทึม) และค่าเริ่มต้น ฟังก์ชันจะส่งค่า 2 ค่า
ค่าปัจจุบันในการวนซ้ำ และผลลัพธ์ของการวนซ้ำก่อนหน้า ตัวอย่างต่อไปนี้
แสดงวิธีใช้ลำดับฟีโบนัชชีใน Earth Engine
โปรแกรมแก้ไขโค้ด (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 เป็นอย่างดีแล้ว คุณสามารถดูบทแนะนำเกี่ยวกับ API เพื่อดูข้อมูลเบื้องต้นเกี่ยวกับฟังก์ชันการทำงานด้านภูมิสารสนเทศของ Earth Engine API