Klient a serwer

Biblioteki klienta Earth Engine w PythonJavaScript przekształcają złożone analizy geoprzestrzenne w żądania Earth Engine. Kod napisany dla biblioteki klienta może zawierać odwołania do obiektów po stronie klienta i zmiennych reprezentujących obiekty po stronie serwera.

Należy odróżniać obiekty Earth Engine od innych obiektów Pythona lub JavaScriptu oraz prymitywów, które mogą występować w Twoim kodzie. Obiektami na serwerze możesz manipulować, manipulując obiektami „pośrednimi” po stronie klienta w skrypcie. Obiekt zastępczy można rozpoznać po tym, że zaczyna się od ee. Te obiekty proxy Earth Engine nie zawierają żadnych rzeczywistych danych i są tylko uchwytami obiektów na serwerze. Na początek rozważ obiekt ciągu znaków po stronie klienta (który NIE jest obiektem zastępczym):

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

import ee
import geemap.core as geemap

Colab (Python)

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

Z wyników widać, że klient (przeglądarka internetowa lub notebook) zinterpretował ten kod i go uruchomił, określając, że zmienna jest typu string. Załóżmy, że chcesz, aby Earth Engine wykonał jakąś operację na tym ciągu znaków. Aby to zrobić, musisz umieścić ciąg znaków w specjalnym kontenerze i przesłać go do Google. Ten kontener jest obiektem zastępczym. Oto przykład:

Edytor kodu (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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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

Z danych wyjściowych wynika, że ee.String to object, a nie string. Dokładniej rzecz biorąc, jest to ee.computedObject, co oznacza, że jest obiektem zastępczym dla czegoś na serwerze. ee.Thing to sposób na umieszczenie czegoś w kontenerze, aby wysłać to do Google. Twój klient nie wie, co znajduje się w pojemniku, ale możesz to sprawdzić, drukując:

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

import ee
import geemap.core as geemap

Colab (Python)

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

Aby zobaczyć, jak wygląda sam kontener, wydrukuj reprezentację ciągu znaków obiektu:

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

import ee
import geemap.core as geemap

Colab (Python)

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

Jeśli z jakiegoś powodu musisz użyć Pythona lub JavaScriptu działającego po stronie klienta, aby manipulować zawartością kontenera, użyj funkcji getInfo(), aby pobrać zawartość kontenera i przypisać ją do zmiennej:

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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?

Odtwarzanie w pętli

Ponieważ klient nie wie, co znajduje się w obiektach ee.Thing po stronie serwera, operacje po stronie klienta, takie jak warunki i pętle for, nie działają z nimi. Z tego powodu oraz aby uniknąć wywołań synchronicznych do funkcji getInfo(), używaj funkcji serwera w jak największym stopniu. Rozważ te 2 sposoby tworzenia listy:

Niezalecane – pętla for po stronie klienta

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

import ee
import geemap.core as geemap

Colab (Python)

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

Zalecane – mapowanie po stronie serwera

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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())

Przykład mapowania po stronie serwera jest trochę śmieszny, ponieważ można utworzyć tę samą listę za pomocą funkcji ee.List.sequence(1, 8), ale ilustruje on ważne pojęcia. Pierwsza koncepcja to map(), która po prostu stosuje tę samą funkcję do wszystkich elementów na liście. Ponieważ ta funkcja jest wykonywana na serwerze, funkcje po stronie klienta, takie jak getInfo()print(), nie będą działać w zmapowanej funkcji. Dlatego kod i + 1 musi zostać zastąpiony odpowiednim kodem po stronie serwera: ee.Number(n).add(1). Co ważne, n to obiekt, który istnieje tylko na serwerze. Funkcja nie zna typu argumentu, dlatego musi być on zamieniony na typ ee.Number.

(Aby dowiedzieć się, które funkcje działają po stronie klienta, zapoznaj się z sekcją o funkcjach po stronie klienta i serwera).

Warto też pamiętać, że czasami funkcje po stronie klienta są wygodne. Na przykład poprzednią petlę for można wykorzystać do utworzenia listy i opakowania jej za pomocą obiektu po stronie serwera:

Edytor kodu (JavaScript)

var toServerList = ee.List(clientList);

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

import ee
import geemap.core as geemap

Colab (Python)

to_server_list = ee.List(client_list)

Pamiętaj, że przetwarzanie po stronie klienta odbywa się na komputerze z procesorem graficznym, czyli na notebooku lub w przeglądarce, więc może być mniej wydajne niż użycie Earth Engine do wykonania pracy na serwerze. Aby uniknąć nieoczekiwanych wyników, w swoich skryptach nie mieszaj funkcji klienta i serwera. Sekcja Warunki zawiera przykłady potencjalnych niezamierzonych konsekwencji.

Warunki

Obiekty po stronie serwera niekoniecznie współpracują z funkcjami po stronie klienta i odwrotnie. Weźmy na przykład zmienną logiczną po stronie serwera:

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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

Jak widać w poniższym przykładzie, zmienna nie działa w warunkach po stronie klienta, ponieważ jest obiektem po stronie serwera. Aby prawidłowo sprawdzić typ danych boolean po stronie serwera, użyj funkcji po stronie serwera:

Niezalecane – warunek po stronie klienta

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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!

Zalecane – reguły po stronie serwera.

Edytor kodu (JavaScript)

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

Konfiguracja Pythona

Informacje o interfejsie Python API i o używaniu pakietu geemap do programowania interaktywnego znajdziesz na stronie Python Environment.

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!

Funkcje klienta i serwera

W poprzednich sekcjach opisaliśmy kilka powodów, dla których łączenie obiektów i funkcji klienta i serwera jest nieefektywne lub nielogiczne. Które obiekty i funkcje działają po stronie klienta, a które po stronie serwera? Ogólnie rzecz biorąc wszystko zainicjowane jako ee.Thing jest obiektem serwera, a każda metoda tego obiektu, ee.Thing.method(), jest funkcją serwera. Obiekty i funkcje występujące w dokumentacji Python lub JavaScript są po stronie klienta. Jak już wspomnieliśmy, możesz użyć funkcji po stronie klienta do utworzenia obiektu, a potem go opakować, podając obiekt po stronie klienta konstruktorowi Earth Engine, na przykład ee.String().