Biblioteki klienta Earth Engine w Python i JavaScript 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
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
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
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!")
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?
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);
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);
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()
i 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
.
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);
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
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!
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!
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()
.