مشتری در مقابل سرور

کتابخانه های مشتری Earth Engine برای پایتون و جاوا اسکریپت، تجزیه و تحلیل های پیچیده جغرافیایی را به درخواست های Earth Engine ترجمه می کنند. کدی که برای کتابخانه مشتری می نویسید ممکن است حاوی ترکیبی از ارجاعات به اشیاء سمت سرویس گیرنده و متغیرهایی باشد که اشیاء سمت سرور را نشان می دهند.

مهم است که اشیاء Earth Engine را از سایر اشیاء پایتون یا جاوا اسکریپت یا موارد اولیه که ممکن است در کد شما وجود داشته باشند متمایز کنید. شما می توانید با دستکاری اشیاء "پراکسی" سمت کلاینت در اسکریپت خود، اشیاء روی سرور را دستکاری کنید. شما می توانید یک شیء پراکسی را به عنوان هر چیزی که با ee شروع می شود تشخیص دهید. این اشیاء پراکسی Earth Engine حاوی هیچ داده واقعی نیستند و فقط دسته‌هایی برای اشیاء روی سرور هستند. برای شروع، یک شی رشته سمت کلاینت (که یک شی پراکسی نیست) را در نظر بگیرید:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

از خروجی مشاهده کنید که کلاینت (مرورگر وب یا نوت بوک) این کد را تفسیر کرده و آن را اجرا کنید و تعیین کنید که متغیر از نوع string است. حال فرض کنید می خواهید Earth Engine بتواند کاری با این رشته انجام دهد. برای انجام این کار، باید رشته را در یک ظرف خوب بپیچید و به Google ارسال کنید. آن ظرف شیء پراکسی است. در اینجا یک مثال است:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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 است. مشتری شما نمی داند چه چیزی در ظرف است، اما می توانید با چاپ آن متوجه شوید که چه چیزی در آن است:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

برای اینکه ببینید خود ظرف چگونه به نظر می رسد، نمایش رشته ای شی را چاپ کنید:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

اگر به دلایلی باید از پایتون یا جاوا اسکریپت در حال اجرا در کلاینت برای دستکاری هر آنچه در کانتینر است استفاده کنید، سپس از getInfo() برای دریافت محتویات کانتینر و اختصاص آن به یک متغیر استفاده کنید:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

حلقه زدن

از آنجایی که مشتری نمی داند در اشیاء ee.Thing سمت سرور چیست، عملیات سمت سرویس گیرنده مانند شرطی ها و حلقه های for با آنها کار نمی کند. به همین دلیل، و برای جلوگیری از تماس‌های همزمان با getInfo() ، تا حد امکان از توابع سرور استفاده کنید. به عنوان مثال، دو روش زیر را برای ایجاد یک لیست در نظر بگیرید:

توصیه نمی شود - حلقه for-side سمت مشتری

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

توصیه می شود - نقشه برداری سمت سرور

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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 فرستاده شود.

(برای توضیح اینکه کدام توابع روی کلاینت اجرا می شوند به بخش توابع Client و Server مراجعه کنید.)

همچنین شایان ذکر است که گاهی اوقات عملکرد سمت مشتری راحت است. به عنوان مثال، حلقه for قبلی می تواند برای ساخت یک لیست و بسته بندی آن با یک شی سمت سرور استفاده شود:

ویرایشگر کد (جاوا اسکریپت)

var toServerList = ee.List(clientList);

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

to_server_list = ee.List(client_list)

توجه داشته باشید که پردازش سمت کلاینت در نوت بوک یا مرورگر شما، یعنی CPU ماشین میزبان انجام می شود، بنابراین می تواند کارایی کمتری نسبت به استفاده از Earth Engine برای انجام کار روی سرور داشته باشد. همچنین، برای جلوگیری از نتایج بالقوه غافلگیرکننده، تمرین خوبی است که از ترکیب عملکرد سرویس گیرنده و سرور در اسکریپت های خود اجتناب کنید. بخش شرط ها نمونه ای از پیامدهای احتمالاً ناخواسته را ارائه می دهد.

شرایط

اشیاء سمت سرور لزوماً با توابع سمت سرویس گیرنده کار نمی کنند و بالعکس. به عنوان مثال، مورد یک متغیر Boolean سمت سرور را در نظر بگیرید:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

همانطور که در مثال زیر نشان داده شده است، متغیر در یک شرطی سمت کلاینت رفتار نمی کند زیرا یک شی سمت سرور است. برای بررسی صحیح یک Boolean سمت سرور، از یک تابع سمت سرور استفاده کنید:

توصیه نمی شود - مشروط سمت مشتری

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

توصیه می شود - شرطی سمت سرور

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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

توابع کلاینت و سرور

بخش‌های قبلی چندین دلیل را توضیح می‌دهند که چرا ترکیب کردن اشیا و توابع کلاینت و سرور ناکارآمد یا غیرمنطقی است. کدام اشیاء و توابع سمت کلاینت و کدام سمت سرور هستند؟ به طور کلی، هر چیزی که به عنوان ee.Thing مقداردهی اولیه شود، یک شی سرور است و هر متدی روی آن شی، ee.Thing.method() یک تابع سرور است. اشیاء و توابعی که در مرجع پایتون یا جاوا اسکریپت ظاهر می شوند سمت کلاینت هستند. همانطور که قبلا ذکر شد، می‌توانید از عملکرد سمت کلاینت برای ایجاد یک شی استفاده کنید، سپس آن را با ارائه شی سمت کلاینت به سازنده Earth Engine، به عنوان مثال ee.String() بپیچید.