As bibliotecas de cliente do Earth Engine para Python e JavaScript convertem análises geoespaciais complexas em solicitações do Earth Engine. O código que você escreve para uma biblioteca de cliente pode conter uma mistura de referências a objetos e variáveis do lado do cliente que representam objetos do lado do servidor.
É importante distinguir os objetos do Earth Engine de outros objetos Python ou JavaScript
ou primitivos que possam estar no seu código. É possível manipular objetos no servidor
manipulando objetos "proxy" do lado do cliente no script. É possível reconhecer um objeto
proxy como qualquer coisa que comece com ee
. Esses objetos proxy do Earth Engine não contêm dados reais e são apenas identificadores de objetos no servidor. Para começar, considere
um objeto de string do lado do cliente (que NÃO é um objeto proxy):
Editor de código (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
Observe na saída que o cliente (o navegador da Web ou o notebook) interpretou e executou esse
código, determinando que a variável
é do tipo string
. Agora suponha que você quer que o Earth Engine faça algo com essa string. Para fazer isso, você precisa agrupar a string em um contêiner
e enviá-la ao Google. Esse contêiner é o objeto proxy. Veja um exemplo:
Editor de código (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
Observe na saída que ee.String
é um object
,
e não um string
. Mais especificamente, é um ee.computedObject
, o que
significa que é um objeto proxy de algo no servidor. Pense em ee.Thing
como
a maneira de colocar algo em um contêiner para enviar ao Google. Seu cliente não sabe
o que está no contêiner, mas você pode descobrir imprimindo-o:
Editor de código (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
Para conferir como o contêiner é, imprima a representação de string do objeto:
Editor de código (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!"})
Se, por algum motivo, você precisar usar Python ou JavaScript
em execução no cliente para manipular o que estiver no contêiner, use
getInfo()
para extrair o conteúdo do contêiner e atribuir a uma variável:
Editor de código (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?
Looping
Como o cliente não sabe o que está nos objetos ee.Thing
do lado do servidor,
as operações do lado do cliente, como condicionais e loops for, não funcionam com eles. Por
esse motivo, e para evitar chamadas síncronas para getInfo()
, use funções
do servidor sempre que possível. Por exemplo, considere as duas maneiras a seguir de
criar uma lista:
Não recomendado: loop for do lado do cliente
Editor de código (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)
Recomendado: mapeamento do servidor
Editor de código (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())
O exemplo de mapeamento no servidor é um pouco, porque você pode criar a mesma lista
simplesmente com ee.List.sequence(1, 8)
, mas ele ilustra alguns conceitos
importantes. O primeiro conceito é map()
, que simplesmente aplica a mesma função
a tudo na lista. Como essa função é executada no servidor, as funções do lado do cliente, como getInfo()
e print()
, não vão funcionar em uma função mapeada. Por esse motivo, o código i + 1
precisa ser substituído pelo código
equivalente do lado do servidor: ee.Number(n).add(1)
. É importante ressaltar que n
é um objeto
que existe apenas no servidor. Como a função não sabe o tipo do argumento,
ela precisa ser convertida em ee.Number
.
Vale lembrar que, às vezes, a funcionalidade do lado do cliente é conveniente. Por exemplo, o laço for anterior pode ser usado para criar uma lista e envolvê-la com um objeto do lado do servidor:
Editor de código (JavaScript)
var toServerList = ee.List(clientList);
import ee import geemap.core as geemap
Colab (Python)
to_server_list = ee.List(client_list)
O processamento do lado do cliente é feito no seu notebook ou navegador, na CPU da máquina host, e pode ser menos eficiente do que usar o Earth Engine para fazer o trabalho no servidor. Além disso, para evitar resultados potencialmente surpreendentes, é recomendável não misturar a funcionalidade do cliente e do servidor nos scripts. A seção Condições mostra um exemplo de consequências não intencionais.
Condicionais
Os objetos do lado do servidor não necessariamente funcionam com funções do lado do cliente e vice-versa. Por exemplo, considere o caso de uma variável booleana do lado do servidor:
Editor de código (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
Como mostrado no exemplo abaixo, a variável não se comporta em uma condicional do lado do cliente porque é um objeto do lado do servidor. Para verificar corretamente um booleano do lado do servidor, use uma função do lado do servidor:
Não recomendado: condicional do lado do cliente
Editor de código (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!
Recomendado: condicional do lado do servidor
Editor de código (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!
Funções de cliente e servidor
As seções anteriores descrevem vários motivos pelos quais é ineficiente ou ilógico
misturar objetos e funções de cliente e servidor. Quais objetos e funções são do lado do cliente
e do lado do servidor? Em geral, qualquer coisa inicializada como ee.Thing
é um objeto de servidor, e qualquer método nesse objeto, ee.Thing.method()
, é uma
função do servidor. Os objetos e as funções que aparecem na referência do
Python ou do
JavaScript
são do lado do cliente. Conforme observado anteriormente, é possível usar a funcionalidade do lado do cliente para criar um objeto e, em seguida, agrupá-lo fornecendo o objeto do lado do cliente para um construtor do Earth Engine, por exemplo, ee.String()
.