En esta guía, se explica cómo puedes comenzar rápidamente a emitir consultas a la API de REST de Earth Engine desde Python con Google Colab. Los mismos conceptos se aplican para acceder a la API desde otros lenguajes y entornos.
Nota: La API de REST contiene funciones nuevas y avanzadas que pueden no ser adecuadas para todos los usuarios. Si es la primera vez que usas Earth Engine, comienza con la guía de JavaScript.
Antes de comenzar
Sigue estas instrucciones para hacer lo siguiente:
Configura tu notebook de Colab
Si estás comenzando esta guía de inicio rápido desde cero, puedes crear un notebook de Colab nuevo. Para ello, haz clic en NOTEBOOK NUEVO en la página de inicio de Colab y, luego, ingresa las muestras de código que se indican a continuación en una celda de código nueva. Colab ya tiene instalado el SDK de Cloud. Esto incluye la herramienta de línea de comandos de gcloud que puedes usar para administrar los servicios de Cloud. Como alternativa, ejecuta el notebook de demostración desde el botón que se encuentra al principio de esta página.
Autentícate en Google Cloud
Lo primero que debes hacer es acceder para poder realizar solicitudes autenticadas a Google Cloud.
En Colab, puedes ejecutar lo siguiente:
PROJECT = 'my-project' !gcloud auth login --project {PROJECT}
(O si ejecutas de forma local, desde una línea de comandos, suponiendo que tienes instalado el SDK de Cloud):
PROJECT='my-project' gcloud auth login --project $PROJECT
Acepta la opción para acceder con tu Cuenta de Google y completa el proceso de acceso.
Obtén un archivo de claves privadas para tu cuenta de servicio
Antes de poder usar la cuenta de servicio para autenticarte, debes descargar un archivo de clave privada. Para hacerlo en Colab, descarga el archivo en la VM del notebook:
SERVICE_ACCOUNT='foo-name@project-name.iam.gserviceaccount.com' KEY = 'my-secret-key.json' !gcloud iam service-accounts keys create {KEY} --iam-account {SERVICE_ACCOUNT}
O bien, desde la línea de comandos:
SERVICE_ACCOUNT='foo-name@project-name.iam.gserviceaccount.com' KEY='my-secret-key.json' gcloud iam service-accounts keys create $KEY --iam-account $SERVICE_ACCOUNT
Accede a tus credenciales y pruébalas
Ya puedes enviar tu primera consulta a la API de Earth Engine. Usa la clave privada para obtener credenciales. Usa las credenciales para crear una sesión autorizada y realizar solicitudes HTTP. Puedes ingresar esto en una nueva celda de código de tu notebook de Colab. (Si usas la línea de comandos, deberás asegurarte de que estén instaladas las bibliotecas necesarias).
from google.auth.transport.requests import AuthorizedSession from google.oauth2 import service_account credentials = service_account.Credentials.from_service_account_file(KEY) scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/cloud-platform']) session = AuthorizedSession(scoped_credentials) url = 'https://earthengine.googleapis.com/v1alpha/projects/earthengine-public/assets/LANDSAT' response = session.get(url) from pprint import pprint import json pprint(json.loads(response.content))
Si todo está configurado correctamente, cuando ejecutes este comando, se producirá un resultado similar al siguiente:
{'id': 'LANDSAT',
'name': 'projects/earthengine-public/assets/LANDSAT',
'type': 'FOLDER'}
Elige un conjunto de datos
Puedes buscar y explorar los conjuntos de datos disponibles con el editor de código de Earth Engine en code.earthengine.google.com. Busquemos algunos datos de Sentinel 2. (Si es la primera vez que usas el editor de código, se te pedirá que lo autorices para acceder a Earth Engine en tu nombre cuando accedas). En el Editor de código, busca "sentinel" en el cuadro de búsqueda de la parte superior. Aparecerán varios conjuntos de datos de trama:

Haz clic en "Sentinel-2: MultiSpectral Instrument (MSI), Level-1C":

Las páginas de descripción de los conjuntos de datos como esta incluyen la información fundamental que necesitas para usar cualquier conjunto de datos del catálogo de datos públicos de Earth Engine, incluida una breve descripción del conjunto de datos, vínculos al proveedor de datos para obtener detalles adicionales, información sobre las restricciones de uso que puedan aplicarse al conjunto de datos y el ID del activo de Earth Engine del conjunto de datos.
En este caso, vemos en el lado derecho de la ventana que se trata de un recurso de colección de imágenes cuya ruta de acceso es COPERNICUS/S2_HARMONIZED.
Cómo consultar imágenes específicas
Este conjunto de datos de Sentinel-2 incluye más de dos millones de imágenes que cubren el mundo desde 2015 hasta la fecha. Emitiremos una consulta projects.assets.listImages en la colección de imágenes para encontrar algunos datos de abril de 2017 con poca cobertura de nubes que incluya un punto en particular en Mountain View, California.
import urllib coords = [-122.085, 37.422] project = 'projects/earthengine-public' asset_id = 'COPERNICUS/S2_HARMONIZED' name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}:listImages?{}'.format( name, urllib.parse.urlencode({ 'startTime': '2017-04-01T00:00:00.000Z', 'endTime': '2017-05-01T00:00:00.000Z', 'region': '{"type":"Point", "coordinates":' + str(coords) + '}', 'filter': 'CLOUDY_PIXEL_PERCENTAGE < 10', })) response = session.get(url) content = response.content for asset in json.loads(content)['images']: id = asset['id'] cloud_cover = asset['properties']['CLOUDY_PIXEL_PERCENTAGE'] print('%s : %s' % (id, cloud_cover))
Esta secuencia de comandos consulta la colección para encontrar imágenes que coincidan, decodifica la respuesta JSON resultante y, luego, imprime el ID del activo y la cobertura de nubes para cada recurso de imagen que coincida. El resultado debería verse de la siguiente manera:
COPERNICUS/S2_HARMONIZED/20170420T184921_20170420T190203_T10SEG : 4.3166
COPERNICUS/S2_HARMONIZED/20170430T190351_20170430T190351_T10SEG : 0
Evidentemente, hay dos imágenes sobre este punto que se tomaron en este mes y tienen una baja cobertura de nubes.
Inspecciona una imagen en particular
Parece que una de las coincidencias tiene prácticamente cero cobertura de nubes. Analicemos con más detalle ese activo, cuyo ID es COPERNICUS/S2_HARMONIZED/20170430T190351_20170430T190351_T10SEG. Ten en cuenta que todos los recursos del catálogo público pertenecen al proyecto earthengine-public. Aquí tienes un fragmento de Python que emitirá una consulta projects.assets.get para recuperar los detalles de ese recurso en particular por ID, imprimir las bandas de datos disponibles y mostrar información más detallada sobre la primera banda:
asset_id = 'COPERNICUS/S2_HARMONIZED/20170430T190351_20170430T190351_T10SEG' name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}'.format(name) response = session.get(url) content = response.content asset = json.loads(content) print('Band Names: %s' % ','.join(band['id'] for band in asset['bands'])) print('First Band: %s' % json.dumps(asset['bands'][0], indent=2, sort_keys=True))
El resultado debería ser similar a este:
Band Names: B1,B2,B3,B4,B5,B6,B7,B8,B8A,B9,B10,B11,B12,QA10,QA20,QA60
First Band: {
"dataType": {
"precision": "INTEGER",
"range": {
"max": 65535
}
},
"grid": {
"affineTransform": {
"scaleX": 60,
"scaleY": -60,
"translateX": 499980,
"translateY": 4200000
},
"crsCode": "EPSG:32610",
"dimensions": {
"height": 1830,
"width": 1830
}
},
"id": "B1",
"pyramidingPolicy": "MEAN"
}
La lista de bandas de datos corresponde a lo que vimos antes en la descripción del conjunto de datos. Podemos ver que este conjunto de datos tiene datos de números enteros de 16 bits en el sistema de coordenadas EPSG:32610 o la zona UTM 10N. Esta primera banda tiene el ID B1 y una resolución de 60 metros por píxel. El origen de la imagen se encuentra en la posición (499980,4200000) en este sistema de coordenadas.
El valor negativo de affineTransform.scaleY indica que el origen se encuentra en la esquina noroeste de la imagen, como suele ser el caso: el aumento de los índices de píxeles de y corresponde a la disminución de las coordenadas espaciales de y (hacia el sur).
Recupera valores de Pixel
Emitamos una consulta projects.assets.getPixels para recuperar algunos datos de las bandas de alta resolución de esta imagen. En la página de descripción del conjunto de datos, se indica que las bandas B2, B3, B4 y B8 tienen una resolución de 10 metros por píxel. Esta secuencia de comandos recupera el mosaico de datos de 256 x 256 píxeles de la esquina superior izquierda de esas cuatro bandas. Cargar los datos en el formato NPY de numpy facilita la decodificación de la respuesta en un array de datos de Python.
import numpy import io name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}:getPixels'.format(name) body = json.dumps({ 'fileFormat': 'NPY', 'bandIds': ['B2', 'B3', 'B4', 'B8'], 'grid': { 'affineTransform': { 'scaleX': 10, 'scaleY': -10, 'translateX': 499980, 'translateY': 4200000, }, 'dimensions': {'width': 256, 'height': 256}, }, }) pixels_response = session.post(url, body) pixels_content = pixels_response.content array = numpy.load(io.BytesIO(pixels_content)) print('Shape: %s' % (array.shape,)) print('Data:') print(array)
El resultado debería verse así:
Shape: (256, 256)
Data:
[[( 899, 586, 351, 189) ( 918, 630, 501, 248) (1013, 773, 654, 378) ...,
(1014, 690, 419, 323) ( 942, 657, 424, 260) ( 987, 691, 431, 315)]
[( 902, 630, 541, 227) (1059, 866, 719, 429) (1195, 922, 626, 539) ...,
( 978, 659, 404, 287) ( 954, 672, 426, 279) ( 990, 678, 397, 304)]
[(1050, 855, 721, 419) (1257, 977, 635, 569) (1137, 770, 400, 435) ...,
( 972, 674, 421, 312) (1001, 688, 431, 311) (1004, 659, 378, 284)]
...,
[( 969, 672, 375, 275) ( 927, 680, 478, 294) (1018, 724, 455, 353) ...,
( 924, 659, 375, 232) ( 921, 664, 438, 273) ( 966, 737, 521, 306)]
[( 920, 645, 391, 248) ( 979, 728, 481, 327) ( 997, 708, 425, 324) ...,
( 927, 673, 387, 243) ( 927, 688, 459, 284) ( 962, 732, 509, 331)]
[( 978, 723, 449, 330) (1005, 712, 446, 314) ( 946, 667, 393, 269) ...,
( 949, 692, 413, 271) ( 927, 689, 472, 285) ( 966, 742, 516, 331)]]
Para seleccionar un conjunto diferente de píxeles de esta imagen, simplemente especifica el affineTransform según corresponda. Recuerda que el affineTransform se especifica en el sistema de referencia de coordenadas espaciales de la imagen. Si, en cambio, quieres ajustar la ubicación del origen en coordenadas de píxeles, usa esta fórmula simple:
request_origin = image_origin + pixel_scale * offset_in_pixels
Genera una imagen en miniatura
Podemos usar un mecanismo similar para generar una miniatura RGB de esta imagen. En lugar de solicitar datos en su resolución nativa, especificaremos una región y las dimensiones de la imagen de forma explícita. Para obtener una miniatura de toda la imagen, podemos usar la geometría de la huella de la imagen como la región de la solicitud. Por último, si especificamos las bandas de imágenes rojas, verdes y azules, y un rango adecuado de valores de datos, podemos obtener una imagen en miniatura RGB atractiva.
Si se junta todo esto, el fragmento de Python se verá de la siguiente manera (con el widget de visualización de imágenes IPython de Colab):
url = 'https://earthengine.googleapis.com/v1alpha/{}:getPixels'.format(name) body = json.dumps({ 'fileFormat': 'PNG', 'bandIds': ['B4', 'B3', 'B2'], 'region': asset['geometry'], 'grid': { 'dimensions': {'width': 256, 'height': 256}, }, 'visualizationOptions': { 'ranges': [{'min': 0, 'max': 3000}], }, }) image_response = session.post(url, body) image_content = image_response.content from IPython.display import Image Image(image_content)
Esta es la imagen de miniatura resultante:
Ejecutar en Google Colab
Ver el código fuente en GitHub