تُحوِّل مكتبات عملاء Earth Engine لبرمجيتَي Python و JavaScript التحليلات الجغرافية المكانية المعقدة إلى طلبات Earth Engine. قد يحتوي الرمز البرمجي الذي تكتبه لأجل مكتبة العميل على مزيج من الإشارات إلى الكائنات والمتغيّرات من جهة العميل التي تمثّل الكائنات من جهة الخادم.
من المهم التمييز بين عناصر Earth Engine وعناصر Python أو JavaScript
أو العناصر الأساسية الأخرى التي قد تكون في الرمز البرمجي. يمكنك التلاعب بالعناصر على الخادم من خلال
التلاعب بعناصر "الوكيل" من جهة العميل في النص البرمجي. يمكنك التعرّف على وكيل
على أنّه أي شيء يبدأ بـ ee
. لا تحتوي عناصر الوكيل هذه في Earth Engine
على أي بيانات فعلية، بل هي مجرد أسماء معرِّفة للعناصر على الخادم. للبدء، ننصحك بالاطّلاع على
العنصر "سلسلة" من جهة العميل (الذي ليس عنصرًا وكيلاً):
محرِّر الرموز البرمجية (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
لاحظ من الإخراج أنّ العميل (متصفّح الويب أو دفتر الملاحظات) قد فسّر هذا الرمز
ونفّذه، وحدّد أنّ المتغيّر
هو من النوع 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
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
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!")
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?
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
من جهة الخادم،
لا تعمل العمليات من جهة العميل، مثل الشروط والدوالّ الحلقية، معها. لهذا السبب، ولتجنُّب إجراء مكالمات متزامنة إلى getInfo()
، استخدِم دوالّ
الخادم إلى أقصى حدّ ممكن. على سبيل المثال، إليك الطريقتان التاليتان ل
إنشاء قائمة:
إجراء غير مقترَح: حلقة for من جهة العميل
محرِّر الرموز البرمجية (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)
إجراء مقترَح: الربط من جهة الخادم
محرِّر الرموز البرمجية (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 السابقة لإنشاء قائمة وتغليفها بأحد عناصر برمجة التطبيقات من جهة الخادم:
محرِّر الرموز البرمجية (JavaScript)
var toServerList = ee.List(clientList);
import ee import geemap.core as geemap
Colab (Python)
to_server_list = ee.List(client_list)
يُرجى العِلم أنّ المعالجة من جهة العميل تتم في دفتر ملاحظاتك أو المتصفّح، أي في وحدة المعالجة المركزية للجهاز المضيف، لذا قد تكون أقل فعالية من استخدام Earth Engine لتنفيذ العمل على الخادم. بالإضافة إلى ذلك، لتجنُّب النتائج غير المتوقّعة، من الممارسات الجيدة تجنُّب خلط وظائف العميل والخادم في النصوص البرمجية. يقدّم قسم الشروط مثالاً على العواقب غير المقصودة المحتملة.
الشروط
لا تعمل العناصر من جهة الخادم بالضرورة مع الوظائف من جهة العميل والعكس صحيح. على سبيل المثال، لنفترض أنّ لدينا متغيّرًا منطقيًا على خادم:
محرِّر الرموز البرمجية (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
كما هو موضّح في المثال التالي، لا يتصرّف المتغيّر في شرط من جهة العميل لأنّه عنصر من جهة الخادم. للتحقّق بشكل صحيح من قيمة منطقية من جهة الخادم، استخدِم دالة من جهة الخادم:
غير مقترَح: الشروط على مستوى العميل
محرِّر الرموز البرمجية (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!
إجراء مقترَح: شرط من جهة الخادم
محرِّر الرموز البرمجية (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()
.