Questa guida spiega come iniziare rapidamente a inviare query all'API REST di Earth Engine da Python utilizzando Google Colab. Gli stessi concetti si applicano all'accesso all'API da altri linguaggi e ambienti.
Nota:l'API REST contiene funzionalità nuove e avanzate che potrebbero non essere adatte a tutti gli utenti. Se non hai mai utilizzato Earth Engine, inizia con la guida JavaScript.
Prima di iniziare
Segui queste istruzioni per:
- Configurare l'accesso a Earth Engine
- Crea un service account
Configurare il notebook di Colab
Se inizi questa guida di avvio rapido da zero, puoi creare un nuovo notebook Colab facendo clic su NUOVO NOTEBOOK dalla pagina iniziale di Colab e inserendo gli esempi di codice riportati di seguito in una nuova cella di codice. Colab ha già installato Cloud SDK. Ciò include lo strumento a riga di comando gcloud
, che puoi utilizzare per gestire i servizi cloud. In alternativa, esegui il blocco note demo dal pulsante all'inizio di questa pagina.
Autenticarsi su Google Cloud
La prima cosa da fare è accedere per poter effettuare richieste autenticate a Google Cloud.
In Colab puoi eseguire:
PROJECT = 'my-project' !gcloud auth login --project {PROJECT}
(o, se esegui l'operazione localmente, da una riga di comando, supponendo che tu abbia installato Cloud SDK:)
PROJECT='my-project' gcloud auth login --project $PROJECT
Accetta l'opzione di accesso utilizzando il tuo account utente Google e completa la procedura di accesso.
Ottenere un file della chiave privata per il service account
Prima di poter utilizzare il service account per l'autenticazione, devi scaricare un file della chiave privata. Per farlo in Colab, scarica nella 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}
In alternativa, dalla riga di comando:
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
Accedere alle credenziali e testarle
Ora puoi inviare la tua prima query all'API Earth Engine. Utilizza la chiave privata per ottenere le credenziali. Utilizza le credenziali per creare una sessione autorizzata per effettuare richieste HTTP. Puoi inserirlo in una nuova cella di codice del notebook Colab. Se utilizzi la riga di comando, devi assicurarti che le librerie necessarie siano installate.
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))
Se tutto è configurato correttamente, l'esecuzione di questo comando produrrà un output simile al seguente:
{'id': 'LANDSAT',
'name': 'projects/earthengine-public/assets/LANDSAT',
'type': 'FOLDER'}
Scegliere un set di dati
Puoi cercare ed esplorare i set di dati disponibili utilizzando Earth Engine Code Editor all'indirizzo code.earthengine.google.com. Cerchiamo alcuni dati di Sentinel 2. Se è la prima volta che utilizzi l'editor di codice, ti verrà chiesto di autorizzarlo ad accedere a Earth Engine per tuo conto quando accedi. Nell'editor di codice, cerca "sentinel" nella casella di ricerca in alto. Vengono visualizzati diversi set di dati raster:

Fai clic su "Sentinel-2: MultiSpectral Instrument (MSI), Level-1C":

Le pagine di descrizione dei set di dati come questa includono le informazioni essenziali necessarie per utilizzare qualsiasi set di dati nel catalogo dei dati pubblici di Earth Engine, tra cui una breve descrizione del set di dati, link al fornitore di dati per ottenere ulteriori dettagli, informazioni su eventuali limitazioni di utilizzo che potrebbero essere applicate al set di dati e l'ID asset Earth Engine del set di dati.
In questo caso, sul lato destro della finestra vediamo che si tratta di un asset di raccolta di immagini il cui percorso è COPERNICUS/S2
.
Query per immagini specifiche
Questo set di dati Sentinel-2 include oltre due milioni di immagini che coprono il mondo dal 2015 a oggi. Eseguiamo una query projects.assets.listImages sulla raccolta di immagini per trovare alcuni dati di aprile 2017 con una copertura nuvolosa bassa che includono un punto specifico di Mountain View, in California.
import urllib coords = [-122.085, 37.422] project = 'projects/earthengine-public' asset_id = 'COPERNICUS/S2' 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))
Questo script esegue una query sulla raccolta per trovare le immagini corrispondenti, decodifica la risposta JSON risultante e stampa l'ID risorsa e la copertura nuvolosa per ogni risorsa immagine corrispondente. L'output dovrebbe essere simile al seguente:
COPERNICUS/S2/20170420T184921_20170420T190203_T10SEG : 4.3166
COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG : 0
Evidentemente ci sono due immagini sopra questo punto che sono state scattate in questo mese e hanno una copertura nuvolosa bassa.
Esaminare un'immagine specifica
Sembra che una delle corrispondenze abbia una copertura nuvolosa praticamente nulla. Diamo un'occhiata più da vicino a questo asset, il cui ID è COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG
. Tieni presente che tutti gli asset del catalogo pubblico appartengono al progetto earthengine-public
. Ecco un snippet Python che eseguirà una query projects.assets.get per recuperare i dettagli di una risorsa specifica in base all'ID, stampare le bande di dati disponibili e stampare informazioni più dettagliate sulla prima banda:
asset_id = 'COPERNICUS/S2/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))
L'output dovrebbe essere simile al seguente:
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"
}
L'elenco delle bande di dati corrisponde a quanto visto in precedenza nella descrizione del set di dati. Possiamo vedere che questo set di dati contiene numeri interi a 16 bit nel sistema di coordinate EPSG:32610 o UTM Zone 10N. Questa prima banda ha l'ID B1
e una risoluzione di 60 metri per pixel. L'origine dell'immagine si trova nella posizione (499980,4200000) in questo sistema di coordinate.
Il valore negativo di affineTransform.scaleY
indica che l'origine si trova nell'angolo nord-ovest dell'immagine, come di solito accade: l'aumento degli indici dei pixel y
corrisponde alla diminuzione delle coordinate spaziali y
(direzione sud).
Recupero dei valori dei pixel
Eseguiamo una query projects.assets.getPixels per recuperare alcuni dati dalle bande ad alta risoluzione di questa immagine. La pagina di descrizione del set di dati indica che le bande B2
, B3
, B4
e B8
hanno una risoluzione di 10 metri per pixel. Questo script recupera il riquadro di dati 256 x 256 pixel in alto a sinistra da queste quattro bande. Il caricamento dei dati nel formato numpy
NPY semplifica la decodifica della risposta in un array di dati 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)
L'output dovrebbe essere simile al seguente:
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)]]
Per selezionare un insieme diverso di pixel da questa immagine, specifica semplicemente affineTransform
di conseguenza. Ricorda che affineTransform
è specificato nel sistema di riferimento delle coordinate spaziali dell'immagine. Se vuoi regolare la posizione dell'origine nelle coordinate pixel, utilizza questa semplice formula:
request_origin = image_origin + pixel_scale * offset_in_pixels
Generare un'immagine in miniatura
Possiamo utilizzare un meccanismo simile per generare una miniatura RGB di questa immagine. Anziché richiedere i dati alla risoluzione nativa, specificheremo esplicitamente una regione e le dimensioni dell'immagine. Per ottenere una miniatura dell'intera immagine, possiamo utilizzare la geometria dell'impronta dell'immagine come regione della richiesta. Infine, specificando le bande dell'immagine rossa, verde e blu e un intervallo appropriato di valori dei dati, possiamo ottenere un'accattivante immagine miniatura RGB.
Mettendo insieme tutto questo, lo snippet Python ha questo aspetto (utilizzando il widget di visualizzazione delle immagini IPython
di 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)
Ecco l'immagine in miniatura risultante:
