ไคลเอ็นต์กับเซิร์ฟเวอร์

ไลบรารีของไคลเอ็นต์ Earth Engine สำหรับ Python และ JavaScript จะแปลการวิเคราะห์เชิงพื้นที่ที่ซับซ้อนเป็นคำขอ Earth Engine โค้ดที่คุณเขียนสําหรับไลบรารีของไคลเอ็นต์อาจมีทั้งการอ้างอิงออบเจ็กต์และตัวแปรฝั่งไคลเอ็นต์ที่แสดงถึงออบเจ็กต์ฝั่งเซิร์ฟเวอร์

คุณควรแยกออบเจ็กต์ Earth Engine ออกจากออบเจ็กต์ Python หรือ JavaScript อื่นๆ หรือออบเจ็กต์พื้นฐานที่อาจอยู่ในโค้ด คุณสามารถดําเนินการกับออบเจ็กต์ในเซิร์ฟเวอร์ได้โดยดําเนินการกับออบเจ็กต์ "พร็อกซี" ฝั่งไคลเอ็นต์ในสคริปต์ คุณจดจำออบเจ็กต์พร็อกซีได้โดยใช้ชื่อที่ขึ้นต้นด้วย ee ออบเจ็กต์พร็อกซีของ Earth Engine เหล่านี้ไม่มีข้อมูลจริงและเป็นเพียงแฮนเดิลสำหรับออบเจ็กต์บนเซิร์ฟเวอร์ ในการเริ่มต้น ให้พิจารณาออบเจ็กต์สตริงฝั่งไคลเอ็นต์ (ซึ่งไม่ใช่ออบเจ็กต์พร็อกซี) ดังนี้

เครื่องมือแก้ไขโค้ด (JavaScript)

var clientString = 'I am a String';
print(typeof clientString);  // string

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

client_string = 'I am a String'
print(type(client_string))  # str

ดูจากเอาต์พุตว่าไคลเอ็นต์ (เว็บเบราว์เซอร์หรือโน้ตบุ๊ก) ได้ตีความโค้ดนี้และเรียกใช้ โดยระบุว่าตัวแปรเป็นประเภท string สมมติว่าคุณต้องการให้ Earth Engine ทําบางอย่างกับสตริงนี้ ซึ่งคุณจะต้องรวมสตริงไว้ในคอนเทนเนอร์ที่เหมาะสมแล้วส่งไปยัง Google คอนเทนเนอร์ดังกล่าวคือออบเจ็กต์พร็อกซี เช่น

เครื่องมือแก้ไขโค้ด (JavaScript)

var serverString = ee.String('I am not a String!');
print(typeof serverString);  // object
print('Is this an EE object?',
    serverString instanceof ee.ComputedObject);  // true

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

server_string = ee.String('I am not a String!')
print(type(server_string))  # ee.ee_string.String
print(
    'Is this an EE object?', isinstance(server_string, ee.ee_string.String)
)  # True

ดูจากเอาต์พุตว่า ee.String เป็น object ไม่ใช่ string กล่าวอย่างเจาะจงคือ ee.computedObject ซึ่งหมายความว่าออบเจ็กต์นี้เป็นพร็อกซีออบเจ็กต์สำหรับข้อมูลบางอย่างในเซิร์ฟเวอร์ ให้คิดว่า ee.Thing เป็นวิธีใส่สิ่งต่างๆ ลงในคอนเทนเนอร์เพื่อส่งไปยัง Google ลูกค้าไม่ทราบว่ามีสิ่งใดอยู่ในคอนเทนเนอร์ แต่คุณสามารถดูข้อมูลดังกล่าวได้โดยพิมพ์คอนเทนเนอร์

เครื่องมือแก้ไขโค้ด (JavaScript)

print(serverString);  // I am not a String

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

print(server_string.getInfo())  # I am not a String

หากต้องการดูลักษณะของคอนเทนเนอร์ ให้พิมพ์การแสดงสตริงของออบเจ็กต์ ดังนี้

เครื่องมือแก้ไขโค้ด (JavaScript)

print(serverString.toString());  // ee.String("I am not a String!")

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

print(server_string)  # ee.String({"constantValue": "I am not a String!"})

หากด้วยเหตุผลใดก็ตาม คุณต้องใช้ Python หรือ JavaScript ที่ทำงานในไคลเอ็นต์เพื่อจัดการกับสิ่งที่อยู่ในคอนเทนเนอร์ ให้ใช้ getInfo() เพื่อรับเนื้อหาของคอนเทนเนอร์และกำหนดให้กับตัวแปร ดังนี้

เครื่องมือแก้ไขโค้ด (JavaScript)

var someString = serverString.getInfo();
var strings = someString + '  Am I?';
print(strings);  // I am not a String!  Am I?

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

some_string = server_string.getInfo()
strings = some_string + '  Am I?'
print(strings)  # I am not a String!  Am I?

การวนซ้ำ

เนื่องจากไคลเอ็นต์ไม่ทราบสิ่งที่อยู่ในออบเจ็กต์ ee.Thing ฝั่งเซิร์ฟเวอร์ การดำเนินการฝั่งไคลเอ็นต์ เช่น เงื่อนไขและวงวน for จึงใช้กับออบเจ็กต์ดังกล่าวไม่ได้ ด้วยเหตุนี้และเพื่อหลีกเลี่ยงการเรียก getInfo() แบบซิงค์ ให้ใช้ฟังก์ชันเซิร์ฟเวอร์เท่าที่เป็นไปได้ ตัวอย่างเช่น ลองดูการสร้างรายการ 2 วิธีต่อไปนี้

ไม่แนะนำ — ลูป for ฝั่งไคลเอ็นต์

เครื่องมือแก้ไขโค้ด (JavaScript)

var clientList = [];
for(var i = 0; i < 8; i++) {
  clientList.push(i + 1);
}
print(clientList);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

client_list = []
for i in range(8):
  client_list.append(i + 1)
print(client_list)

แนะนํา — การแมปฝั่งเซิร์ฟเวอร์

เครื่องมือแก้ไขโค้ด (JavaScript)

var serverList = ee.List.sequence(0, 7);
serverList = serverList.map(function(n) {
  return ee.Number(n).add(1);
});
print(serverList);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

server_list = ee.List.sequence(0, 7)
server_list = server_list.map(lambda n: ee.Number(n).add(1))
print(server_list.getInfo())

ตัวอย่างการแมปฝั่งเซิร์ฟเวอร์ดูตลกๆ หน่อยเพราะคุณสร้างรายการเดียวกันได้ง่ายๆ ด้วย ee.List.sequence(1, 8) แต่ตัวอย่างนี้แสดงแนวคิดที่สําคัญบางอย่าง แนวคิดแรกคือ map() ซึ่งใช้ฟังก์ชันเดียวกันกับทุกรายการในลิสต์ เนื่องจากฟังก์ชันนี้จะทำงานบนเซิร์ฟเวอร์ ฟังก์ชันฝั่งไคลเอ็นต์ เช่น getInfo() และ print() จึงจะไม่ทํางานในฟังก์ชันที่แมป ด้วยเหตุนี้ คุณจึงต้องแทนที่โค้ด i + 1 ด้วยโค้ดฝั่งเซิร์ฟเวอร์ที่เทียบเท่า ซึ่งก็คือ ee.Number(n).add(1) สิ่งสำคัญคือ n เป็นออบเจ็กต์ที่มีอยู่ในเซิร์ฟเวอร์เท่านั้น เนื่องจากฟังก์ชันไม่ทราบประเภทของอาร์กิวเมนต์ จึงต้องมีการแคสต์เป็น ee.Number

(ดูคำอธิบายฟังก์ชันที่ทำงานบนไคลเอ็นต์ได้ที่ส่วนฟังก์ชันไคลเอ็นต์และเซิร์ฟเวอร์)

นอกจากนี้ โปรดทราบว่าบางครั้งฟังก์ชันการทำงานฝั่งไคลเอ็นต์ก็สะดวกดี เช่น สามารถใช้ลูป for ก่อนหน้าเพื่อสร้างรายการและรวมเข้ากับออบเจ็กต์ฝั่งเซิร์ฟเวอร์ได้ ดังนี้

เครื่องมือแก้ไขโค้ด (JavaScript)

var toServerList = ee.List(clientList);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

to_server_list = ee.List(client_list)

โปรดทราบว่าการประมวลผลฝั่งไคลเอ็นต์จะดำเนินการในโน้ตบุ๊คหรือเบราว์เซอร์ ซึ่งเป็น CPU ของเครื่องโฮสต์ จึงอาจมีประสิทธิภาพน้อยกว่าการใช้ Earth Engine ทำงานในเซิร์ฟเวอร์ นอกจากนี้ เราขอแนะนำให้หลีกเลี่ยงการผสมฟังก์ชันการทำงานของไคลเอ็นต์และเซิร์ฟเวอร์ในสคริปต์เพื่อหลีกเลี่ยงผลลัพธ์ที่อาจทำให้เกิดความประหลาดใจ ส่วนเงื่อนไขจะแสดงตัวอย่างของผลลัพธ์ที่อาจเกิดขึ้นโดยไม่ตั้งใจ

เงื่อนไข

ออบเจ็กต์ฝั่งเซิร์ฟเวอร์ไม่จำเป็นต้องทำงานร่วมกับฟังก์ชันฝั่งไคลเอ็นต์ และในทางกลับกัน ตัวอย่างเช่น ลองพิจารณากรณีตัวแปรบูลีนฝั่งเซิร์ฟเวอร์

เครื่องมือแก้ไขโค้ด (JavaScript)

var myList = ee.List([1, 2, 3]);
var serverBoolean = myList.contains(5);
print(serverBoolean);  // false

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

my_list = ee.List([1, 2, 3])
server_boolean = my_list.contains(5)
print(server_boolean.getInfo())  # False

ดังที่แสดงในตัวอย่างต่อไปนี้ ตัวแปรจะไม่ทํางานแบบเงื่อนไขฝั่งไคลเอ็นต์เนื่องจากเป็นออบเจ็กต์ฝั่งเซิร์ฟเวอร์ หากต้องการตรวจสอบบูลีนฝั่งเซิร์ฟเวอร์อย่างถูกต้อง ให้ใช้ฟังก์ชันฝั่งเซิร์ฟเวอร์ ดังนี้

ไม่แนะนำ — เงื่อนไขฝั่งไคลเอ็นต์

เครื่องมือแก้ไขโค้ด (JavaScript)

var clientConditional;
if (serverBoolean) {
  clientConditional = true;
} else {
  clientConditional = false;
}
print('Should be false:', clientConditional);  // True!

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

if server_boolean:
  client_conditional = True
else:
  client_conditional = False
print('Should be False:', client_conditional)  # True!

แนะนํา — เงื่อนไขฝั่งเซิร์ฟเวอร์

เครื่องมือแก้ไขโค้ด (JavaScript)

var serverConditional = ee.Algorithms.If(serverBoolean, 'True!', 'False!');
print('Should be false:', serverConditional);  // False!

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

server_conditional = ee.Algorithms.If(server_boolean, 'True!', 'False!')
print('Should be False:', server_conditional.getInfo())  # False!

ฟังก์ชันไคลเอ็นต์และเซิร์ฟเวอร์

ส่วนก่อนหน้านี้อธิบายเหตุผลหลายประการว่าทำไมการผสมออบเจ็กต์และฟังก์ชันของเซิร์ฟเวอร์และไคลเอ็นต์จึงทําให้มีประสิทธิภาพต่ำหรือไม่สมเหตุสมผล ออบเจ็กต์และฟังก์ชันใดบ้างที่เป็นฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ โดยทั่วไปแล้ว ทุกอย่างที่เริ่มต้นเป็น ee.Thing จะถือเป็นออบเจ็กต์เซิร์ฟเวอร์ และเมธอดใดก็ตามบนออบเจ็กต์ ee.Thing.method() จะเป็นฟังก์ชันเซิร์ฟเวอร์ ออบเจ็กต์และฟังก์ชันที่ปรากฏในข้อมูลอ้างอิง Python หรือ JavaScript จะอยู่ฝั่งไคลเอ็นต์ ดังที่กล่าวไว้ก่อนหน้านี้ คุณสามารถใช้ฟังก์ชันฝั่งไคลเอ็นต์เพื่อสร้างออบเจ็กต์ จากนั้นรวมออบเจ็กต์ฝั่งไคลเอ็นต์เข้ากับตัวสร้างของ Earth Engine เช่น ee.String()