ספריות הלקוח של Earth Engine ל-Python ול-JavaScript מתרגמות ניתוחים גיאו-מרחביים מורכבים לבקשות של Earth Engine. הקוד שאתם כותבים לספריית לקוח יכול להכיל שילוב של הפניות לאובייקטים בצד הלקוח ולמשתנים שמייצגים אובייקטים בצד השרת.
חשוב להבדיל בין אובייקטים של Earth Engine לבין אובייקטים אחרים של Python או JavaScript, או בין אובייקטים פרימיטיביים אחרים שעשויים להופיע בקוד. אפשר לבצע מניפולציות על אובייקטים בשרת על ידי מניפולציה על אובייקטים מסוג 'שנציג (proxy)' בצד הלקוח בסקריפט. אפשר לזהות אובייקט proxy ככל אובייקט שמתחיל ב-ee
. אובייקטי proxy של Earth Engine לא מכילים נתונים בפועל, אלא רק כינויים לאובייקטים בשרת. כדי להתחיל, נבחן אובייקט מחרוזת בצד הלקוח (שאינו אובייקט proxy):
Code Editor (JavaScript)
var clientString = 'I am a String'; print(typeof clientString); // string
import ee import geemap.core as geemap
Colab (Python)
client_string = 'I am a String' print(type(client_string)) # str
לפי הפלט, אפשר לראות שהלקוח (דפדפן האינטרנט או ה-notebook) פירש את הקוד הזה והפעיל אותו, וקבע שהמשתנה הוא מסוג string
. עכשיו נניח שאתם רוצים שמערכת Earth Engine תוכל לבצע פעולה כלשהי עם המחרוזת הזו. לשם כך, צריך לארוז את המחרוזת במארז נוח ולשלוח אותה ל-Google. הקונטיינר הזה הוא אובייקט proxy. לדוגמה:
Code Editor (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
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
, כלומר אובייקט proxy למשהו בשרת. אפשר לחשוב על ee.Thing
כדרך לשים משהו בקונטיינר כדי לשלוח אותו ל-Google. הלקוח לא יודע מה יש בקונטיינר, אבל אתם יכולים לבדוק מה יש בו על ידי הדפסה שלו:
Code Editor (JavaScript)
print(serverString); // I am not a String
import ee import geemap.core as geemap
Colab (Python)
print(server_string.getInfo()) # I am not a String
כדי לראות איך נראה המאגר עצמו, מדפיסים את ייצוג המחרוזת של האובייקט:
Code Editor (JavaScript)
print(serverString.toString()); // ee.String("I am not a String!")
import ee import geemap.core as geemap
Colab (Python)
print(server_string) # ee.String({"constantValue": "I am not a String!"})
אם מסיבה כלשהי אתם צריכים להשתמש ב-Python או ב-JavaScript שפועלים בלקוח כדי לבצע פעולות על התוכן בקונטיינר, תוכלו להשתמש ב-getInfo()
כדי לקבל את תוכן הקונטיינר ולהקצות אותו למשתנה:
Code Editor (JavaScript)
var someString = serverString.getInfo(); var strings = someString + ' Am I?'; print(strings); // I am not a String! Am I?
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-loops לא פועלות איתו. לכן, וכדי להימנע מבקשות סינכרניות ל-getInfo()
, כדאי להשתמש בפונקציות שרת ככל האפשר. לדוגמה, אלה שתי הדרכים ליצירת רשימה:
לא מומלץ – לולאת for מצד הלקוח
Code Editor (JavaScript)
var clientList = []; for(var i = 0; i < 8; i++) { clientList.push(i + 1); } print(clientList);
import ee import geemap.core as geemap
Colab (Python)
client_list = [] for i in range(8): client_list.append(i + 1) print(client_list)
מומלץ – מיפוי בצד השרת
Code Editor (JavaScript)
var serverList = ee.List.sequence(0, 7); serverList = serverList.map(function(n) { return ee.Number(n).add(1); }); print(serverList);
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 הקודם כדי ליצור רשימה ולעטוף אותה באובייקט בצד השרת:
Code Editor (JavaScript)
var toServerList = ee.List(clientList);
import ee import geemap.core as geemap
Colab (Python)
to_server_list = ee.List(client_list)
חשוב לזכור שהעיבוד בצד הלקוח מתבצע במחשב הנייד או בדפדפן, במעבד המרכזי (CPU) של המכונה המארחת, ולכן הוא עשוי להיות פחות יעיל מאשר שימוש ב-Earth Engine כדי לבצע את העבודה בשרת. בנוסף, כדי למנוע תוצאות מפתיעות, מומלץ להימנע מהשילוב של פונקציונליות של שרתים ושל לקוחות בסקריפטים. בקטע תנאים מופיעה דוגמה להשלכות לא מכוונות.
תנאים
אובייקטים בצד השרת לא פועלים בהכרח עם פונקציות בצד הלקוח ולהפך. לדוגמה, ניקח את המקרה של משתנה בוליאני בצד השרת:
Code Editor (JavaScript)
var myList = ee.List([1, 2, 3]); var serverBoolean = myList.contains(5); print(serverBoolean); // false
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
כפי שמוצג בדוגמה הבאה, המשתנה לא פועל בתנאים בצד הלקוח כי הוא אובייקט בצד השרת. כדי לבדוק בוליאני בצד השרת בצורה נכונה, צריך להשתמש בפונקציה בצד השרת:
לא מומלץ – תנאי מצד הלקוח
Code Editor (JavaScript)
var clientConditional; if (serverBoolean) { clientConditional = true; } else { clientConditional = false; } print('Should be false:', clientConditional); // True!
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!
מומלץ – תנאי בצד השרת
Code Editor (JavaScript)
var serverConditional = ee.Algorithms.If(serverBoolean, 'True!', 'False!'); print('Should be false:', serverConditional); // False!
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()
.