Las bibliotecas cliente de Earth Engine para Python y JavaScript traducen análisis geoespaciales complejos en solicitudes de Earth Engine. El código que escribes para una biblioteca cliente puede contener una combinación de referencias a objetos y variables del cliente que representan objetos del servidor.
Es importante distinguir los objetos de Earth Engine de otros objetos o primitivos de Python o JavaScript que puedan estar en tu código. Puedes manipular objetos en el servidor manipulando los objetos "proxy" del cliente en tu secuencia de comandos. Puedes reconocer un objeto proxy como cualquier elemento que comience con ee
. Estos objetos de proxy de Earth Engine no contienen datos reales y son solo identificadores de objetos en el servidor. Para comenzar, considera un objeto de cadena del cliente (que NO es un objeto de 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
Observa en el resultado que el cliente (el navegador web o la notebook) interpretó este código y lo ejecutó, y determinó que la variable es del tipo string
. Ahora supongamos que quieres que Earth Engine pueda hacer algo con esta cadena. Para ello, debes unir la cadena en un contenedor ordenado
y enviarla a Google. Ese contenedor es el objeto proxy. Por ejemplo:
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
Observa en el resultado que ee.String
es object
,
NO string
. Más específicamente, es un ee.computedObject
, lo que significa que es un objeto proxy para algo en el servidor. Piensa en ee.Thing
como
la forma de colocar un elemento en un contenedor para enviarlo a Google. Tu cliente no sabe qué hay en el contenedor, pero puedes averiguarlo si lo imprimes:
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 ver cómo se ve el contenedor, imprime la representación de cadena del 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!"})
Si, por algún motivo, necesitas usar Python o JavaScript
en ejecución en el cliente para manipular lo que está en el contenedor, usa
getInfo()
para obtener el contenido del contenedor y asignarlo a una variable:
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?
Repetición
Debido a que el cliente no sabe qué contiene los objetos ee.Thing
del servidor, las operaciones del cliente, como las condicionales y los bucles for, no funcionan con ellos. Por
ese motivo, y para evitar llamadas síncronas a getInfo()
, usa funciones
del servidor en la medida de lo posible. Por ejemplo, considera las siguientes dos formas de crear una lista:
No se recomienda: bucle for del 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: Asignación del 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())
El ejemplo de asignación del servidor es un poco porque podrías hacer la misma lista solo con ee.List.sequence(1, 8)
, pero ilustra algunos conceptos importantes. El primer concepto es map()
, que simplemente aplica la misma función a todo lo que está en la lista. Debido a que esta función se ejecuta en el servidor, las funciones del cliente, como getInfo()
y print()
, no funcionarán en una función asignada. Por esa razón, el código i + 1
debe reemplazarse por el código del servidor equivalente: ee.Number(n).add(1)
. Es importante tener en cuenta que n
es un objeto que solo existe en el servidor. Como la función no conoce el tipo de su argumento, se debe transmitir a un ee.Number
.
También es importante tener en cuenta que, en ocasiones, la funcionalidad del cliente es conveniente. Por ejemplo, el bucle for anterior se podría usar para crear una lista y unirla con un objeto del 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)
Ten en cuenta que el procesamiento del cliente se realiza en tu notebook o navegador, la CPU de la máquina anfitrión, por lo que puede ser menos eficiente que usar Earth Engine para realizar el trabajo en el servidor. Además, para evitar resultados potencialmente sorprendentes, se recomienda evitar mezclar la funcionalidad del cliente y del servidor en tus secuencias de comandos. En la sección Condicionales, se proporciona un ejemplo de consecuencias posiblemente no deseadas.
Condicionales
Los objetos del servidor no necesariamente funcionan con funciones del cliente y viceversa. Por ejemplo, considera el caso de una variable booleana del 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 se muestra en el siguiente ejemplo, la variable no se comporta en una sentencia condicional del cliente porque es un objeto del servidor. Para verificar correctamente un valor booleano del servidor, usa una función del servidor:
No se recomienda: Condicional del 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 del 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!
Funciones del cliente y del servidor
En las secciones anteriores, se describen varios motivos por los que es ineficiente o ilógico mezclar objetos y funciones de cliente y servidor. ¿Qué objetos y funciones son del cliente y cuáles son del servidor? En general, todo lo que se inicializa como ee.Thing
es un objeto de servidor, y cualquier método en ese objeto, ee.Thing.method()
, es una función de servidor. Los objetos y las funciones que aparecen en la referencia de Python o JavaScript son del cliente. Como se señaló anteriormente, puedes usar la funcionalidad del cliente para crear un objeto y, luego, unirlo proporcionando el objeto del cliente a un constructor de Earth Engine, por ejemplo, ee.String()
.