Esportazione in BigQuery

Panoramica

L'architettura di calcolo di Earth Engine è ottimizzata per rendere i calcoli delle immagini (basati su pixel) rapidi e scalabili. BigQuery è ottimizzato in modo simile per l'elaborazione scalabile dei dati tabulari (vettori) e offre molte funzionalità che lo rendono un ottimo complemento di Earth Engine.

Ecco alcuni esempi di flussi di lavoro:

  • Eseguire unioni BigQuery di grandi dimensioni sui dati generati in Earth Engine
  • Annotazione dei dati vettoriali con statistiche ricavate dalle immagini per ulteriore lavorazione in BigQuery
  • Esportare periodicamente i dati da Earth Engine in una tabella BigQuery aggriorabile

Se hai altri casi d'uso interessanti, saremo lieti di conoscerli.

Nozioni di base su BigQuery

Earth Engine scrive nelle tabelle BigQuery e tutte le tabelle sono contenute nei set di dati. Le attività di esportazione non riescono se il set di dati specificato non è presente in BigQuery. Scopri di più nell'introduzione ai set di dati BigQuery.

Creazione del set di dati

I set di dati hanno una serie di opzioni al momento della creazione, tra cui il nome, la regione di archiviazione e il comportamento di scadenza (oltre a diverse altre opzioni più avanzate).

Esistono diversi meccanismi per creare set di dati, ma un modo semplice per iniziare è tramite la console Cloud:

  1. Vai alla pagina BigQuery nella console Cloud.
  2. Fai clic su "Attiva" per abilitare l'API, se richiesto.
  3. Nella scheda "Spazio di lavoro SQL", fai clic sul menu con tre puntini () accanto al progetto.
  4. Scegli l'opzione "Crea set di dati".
  5. Segui la guida alla configurazione.

Per tutte le opzioni per creare e configurare un set di dati, consulta la documentazione di BigQuery.

Autorizzazioni

Oltre ai ruoli e alle autorizzazioni standard necessari per utilizzare Earth Engine, gli utenti che chiamano devono disporre anche delle autorizzazioni BigQuery corrette per il progetto o il set di dati Cloud.

  • bigquery.tables.get
  • bigquery.tables.create
  • bigquery.tables.updateData
  • bigquery.tables.delete
  • bigquery.jobs.create

Qualsiasi delle seguenti combinazioni di ruoli IAM (Identity and Access Management) predefiniti include le autorizzazioni necessarie:

  • bigquery.dataEditor + bigquery.jobUser
  • bigquery.dataOwner + bigquery.jobUser
  • bigquery.user
  • bigquery.admin

Prezzi

BigQuery è un servizio Google Cloud a pagamento, pertanto ti verranno addebitati costi per l'utilizzo di BigQuery, inclusi lo stoccaggio e l'analisi di eventuali dati di Earth Engine esportati in BigQuery.

Per informazioni dettagliate sui prezzi della funzionalità di esportazione in BigQuery di Earth Engine, consulta la sezione relativa ai prezzi di seguito.

Esporta configurazione

Sintassi

Editor di codice (JavaScript)

Export.table.toBigQuery({
  collection: features,
  table: 'myproject.mydataset.mytable',
  description: 'put_my_data_in_bigquery',
  append: true,
  overwrite: false
});

Configurazione di Python

Per informazioni sull'API Python e sull'utilizzo di geemap per lo sviluppo interattivo, consulta la pagina Ambiente Python.

import ee
import geemap.core as geemap

Colab (Python)

task = ee.batch.Export.table.toBigQuery(
    collection=features,
    table='myproject.mydataset.mytable',
    description='put_my_data_in_bigquery',
    append=True,
    overwrite=False,
)
task.start()

Specifica dello schema automatica o manuale

Se in BigQuery non è presente alcuna tabella, Earth Engine tenta di determinare un schema utilizzando le proprietà del primo ee.Feature nella collezione. Si tratta di una stima migliore ed è possibile creare una raccolta in cui lo schema della prima funzionalità è diverso da quello delle altre funzionalità.

Se hai bisogno di uno schema specifico nella tabella BigQuery, configuralo creando una tabella vuota con lo schema di destinazione.

Nomi delle proprietà

Le proprietà degli elementi Earth Engine corrispondono alle colonne in BigQuery. Earth Engine utilizza il nome "geo" per scrivere la geometria ee.Feature (il selettore ".geo") in BigQuery.

Per evitare di rinominarle, assicurati che gli oggetti ee.Feature abbiano proprietà che siano nomi di colonna validi e che nessuno sia denominato "geo" (poiché questo nome viene utilizzato per la geometria dell'elemento, che non ha nome in Earth Engine).

I caratteri non validi nei nomi delle proprietà causano l'errore di esportazione a causa delle limitazioni relative ai nomi delle colonne BigQuery.

Conversione dei tipi

I dati di Earth Engine (i valori delle proprietà ee.Feature) vengono convertiti in un tipo BigQuery equivalente, se possibile. Tieni presente che la nullabilità è controllata dallo schema della tabella, non dal tipo.

Tipo di Earth Engine Tipo BigQuery Note
ee.String STRING
ee.Number FLOAT o INTEGER
ee.Geometry GEOGRAPHY
ee.Date TIMESTAMP
ee.ByteString BYTES
ee.Array STRUCT<ARRAY<INT64>, ARRAY<INT64|FLOAT64>> Consulta la sezione sugli array.
Altri tipi di ee.* non supportato Consulta la sezione relativa ai valori JSON

Array

Earth Engine esporta qualsiasi ee.Array multidimensionale in STRUCT<ARRAY<INT64> dimensions, ARRAY<INT64|FLOAT64> values>, in modo simile al formato utilizzato dalla funzione ML.DECODE_IMAGE di BigQuery.

Il primo array nella struttura, dimensions, contiene le dimensioni dell'array Earth Engine, da $d_1$ a $d_n$.

Il secondo array nella struttura, values, contiene tutti i valori dell'array multidimensionale, appiattiti in un singolo array BigQuery. Il numero totale di valori nell'array appiattito è $\sum_{i=1}^n d_i$ e il valore all'indice $(i_i, \ldots, i_n)$ nell'array Earth Engine originale corrisponde al valore all'indice seguente nell'array appiattito:

\[ \sum_{j=1}^n \left( i_j \cdot \prod_{k=j+1}^n d_k \right) \]

Per i casi comuni, l'espressione di indicizzazione per l'array values è la seguente:

Dimensione array Dimensioni Espressione di indicizzazione
Unidimensionale d1 [i1]
2 dimensioni d1, d2 [(i1 * d2) + i2]
Tridimensionale d1, d2, d3 [(i1 * d2 * d3) + (i2 * d3) + i3]

Ad esempio, considera un array 2x3x4 di Earth Engine:

    ee.Array([
      [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12]
      ],
      [
        [13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]
      ]
    ]);

Questo array si traduce in un STRUCT di BigQuery il cui elemento dimensions è l'array [2, 3, 4] e il cui elemento values è l'array [1, 2, 3, 4, 5, 6, 7, 8, ..., 21, 22, 23, 24] semplificato. Gli indici nell'array appiattito possono essere calcolati come [(i1 * 12) + (i2 * 4) + i3].

Valori JSON

Per supportare dati più strutturati all'interno di una cella, è possibile codificare i valori di Earth Engine come oggetti JSON. BigQuery supporta operazioni SQL sui dati codificati in JSON, consentendo query che "esaminano" i valori JSON codificati prodotti in Earth Engine.

Editor di codice (JavaScript)

var states = ee.FeatureCollection('TIGER/2018/States');
var mod11a1 = ee.ImageCollection('MODIS/061/MOD11A1');

// Find the max day and night temperatures per pixel for a given time.
var maxTemp = mod11a1
    .select(['LST_Day_1km', 'LST_Night_1km'])
    .filterDate('2023-05-15', '2023-05-25')
    .max();

// Annotate each state with its max day/night temperatures.
var annotatedStates = states.map(function (e) {
  var dict = maxTemp.reduceRegion({
    reducer: ee.Reducer.max(),
    geometry: e.geometry(),
    scale: 10 * 1000,  // 10 km
  });
  // Convert the dictionary to JSON and add it as a property.
  return e.set('maxTemp', ee.String.encodeJSON(dict));
});

Export.table.toBigQuery(annotatedStates);

Configurazione di Python

Per informazioni sull'API Python e sull'utilizzo di geemap per lo sviluppo interattivo, consulta la pagina Ambiente Python.

import ee
import geemap.core as geemap

Colab (Python)

states = ee.FeatureCollection('TIGER/2018/States')
mod11a1 = ee.ImageCollection('MODIS/061/MOD11A1')

# Find the max day and night temperatures per pixel for a given time.
max_temp = (
    mod11a1.select(['LST_Day_1km', 'LST_Night_1km'])
    .filterDate('2023-05-15', '2023-05-25')
    .max()
)


def get_max_temp_for_state(e):
  max_temp_dict = max_temp.reduceRegion(
      reducer=ee.Reducer.max(),
      geometry=e.geometry(),
      scale=10 * 1000,  # 10 km
  )
  # Convert the dictionary to JSON and add it as a property.
  return e.set('maxTemp', ee.String.encodeJSON(max_temp_dict))


# Annotate each state with its max day/night temperatures.
annotated_states = states.map(get_max_temp_for_state)

task = ee.batch.Export.table.toBigQuery(
    collection=annotated_states, table='myproject.mydataset.mytable'
)
task.start()

Conversione della geometria

BigQuery ha un supporto limitato per proiezioni diverse, pertanto tutte le geometrie di Earth Engine vengono trasformate in EPSG:4326 geodesiche utilizzando un margine di errore di 1 metro.

Per un controllo più preciso di questo processo di trasformazione, puoi mappare manualmente le funzionalità e trasformarne le geometrie, ad esempio:

Editor di codice (JavaScript)

var transformedCollection = originalCollection.map(function transformGeo(e) {
  var myErrorMargin = 10 * 1000;  // meters
  return e.setGeometry(e.geometry(myErrorMargin, 'EPSG:4326', true));
});

Configurazione di Python

Per informazioni sull'API Python e sull'utilizzo di geemap per lo sviluppo interattivo, consulta la pagina Ambiente Python.

import ee
import geemap.core as geemap

Colab (Python)

def transform_geo(e):
  my_error_margin = 10 * 1000  # meters
  return e.setGeometry(e.geometry(my_error_margin, 'EPSG:4326', True))


transformed_collection = original_collection.map(transform_geo)

Prestazioni

Rendimento di Earth Engine

Il calcolo di Earth Engine è spesso il collo di bottiglia per le operazioni Export. A questo scopo, è importante organizzare l'elaborazione per ottenere il massimo parallelismo. Qualsiasi calcolo che includa l'elaborazione seriale (ad esempioee.FeatureCollection.iterate()) può causare l'esecuzione lenta o l'interruzione dell'esportazione.

Prestazioni in BigQuery

La strutturazione e il clustering dei dati in modo corretto è il modo migliore per garantire l'efficienza delle query in BigQuery. Se non è già presente una tabella in BigQuery, le tabelle esportate da Earth Engine vengono raggruppate in base alla geometria degli elementi (se presente). Il clustering in base al campo geografico è molto comune per i dati geospaziali. Migliora le prestazioni e riduce i costi per le query che utilizzano filtri spaziali, più comunemente per operazioni BigQuery come:

WHERE ST_DWithin(<table_column>, <constant_geography>, <distance>)
WHERE ST_Intersects(<table_column>, <constant_geography>)

Anche l'aggiunta del clustering a una tabella non raggruppata in genere non causa alcun problema, anche se potrebbe aumentare leggermente il tempo di caricamento dei dati nella tabella. Per saperne di più sull'ottimizzazione delle query, consulta la documentazione di BigQuery.

Tieni presente che le impostazioni di clustering influiscono solo sui nuovi dati scritti nella tabella.

Demo: utilizzo di reduceRegions

In alcuni casi, è possibile utilizzare reduceRegions per ottenere il massimo parallelismo possibile dall'infrastruttura di elaborazione di Earth Engine. Questo esempio dimostra come utilizzare un numero inferiore di chiamate reduceRegions (alcune cento) anziché decine di migliaia di chiamate reduceRegion (l'approccio tipico per mappare una funzione su una raccolta).

Editor di codice (JavaScript)

var lucas = ee.FeatureCollection('JRC/LUCAS_HARMO/COPERNICUS_POLYGONS/V1/2018');
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');

// Fetch the unique date values from the dataset.
var dates = lucas.aggregate_array('survey_date')
    .distinct()
    .map(function (date) {
      return ee.Date.parse('dd/MM/yy', date);
    });

// For each date, annotate the LUCAS samples with the Sentinel-2 band values for
// a two-week window.
function getLucasSamplesForDate(date) {
  date = ee.Date(date);
  var imageForDate = s2
    .filterDate(
      date.advance(-1, 'week'),
      date.advance(1, 'week'))
    .select('B.*');
  var median = imageForDate.median();
  var lucasForDate = lucas.filter(
    ee.Filter.equals('survey_date', date.format('dd/MM/yy')));
  var sample = median.reduceRegions({
    collection: lucasForDate,
    reducer: ee.Reducer.mean(),
    scale: 10,
    tileScale: 8,
  });
  return sample;
}

// Flatten the collection.
var withSamples =
    ee.FeatureCollection(dates.map(getLucasSamplesForDate))
      .flatten();

Export.table.toBigQuery({
  collection: withSamples,
  description: 'lucas_s2_annotated'
});

Configurazione di Python

Per informazioni sull'API Python e sull'utilizzo di geemap per lo sviluppo interattivo, consulta la pagina Ambiente Python.

import ee
import geemap.core as geemap

Colab (Python)

lucas = ee.FeatureCollection('JRC/LUCAS_HARMO/COPERNICUS_POLYGONS/V1/2018')
s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')

# Fetch the unique date values from the dataset.
dates = (
    lucas.aggregate_array('survey_date')
    .distinct()
    .map(lambda date: ee.Date.parse('dd/MM/yy', date))
)


# For each date, annotate the LUCAS samples with the Sentinel-2 band values for
# a two-week window.
def get_lucas_samples_for_date(date):
  date = ee.Date(date)
  image_for_date = s2.filterDate(
      date.advance(-1, 'week'), date.advance(1, 'week')
  ).select('B.*')
  median = image_for_date.median()
  lucas_for_date = lucas.filter(
      ee.Filter.equals('survey_date', date.format('dd/MM/yy'))
  )
  sample = median.reduceRegions(
      collection=lucas_for_date,
      reducer=ee.Reducer.mean(),
      scale=10,
      tileScale=8,
  )
  return sample


# Flatten the collection.
with_samples = ee.FeatureCollection(
    dates.map(get_lucas_samples_for_date)
).flatten()

task = ee.batch.Export.table.toBigQuery(
    collection=with_samples,
    table='myproject.mydataset.mytable',
    description='lucas_s2_annotated',
)
task.start()

Parallelizzazione delle attività

Con l'opzione {append: true}, è possibile che più attività scrivano contemporaneamente dati in una tabella BigQuery. Si tratta di un meccanismo per scrivere dati con un throughput superiore, ma a un costo maggiore in termini di complessità (gestione della coda di attività, tentativi di nuovo invio e così via).

Differenze di rendimento tra i parametri append e overwrite

Tieni presente che l'overwriting è più lento dell'accodamento perché BigQuery deve elaborare i nuovi dati prima di sovrascrivere quelli vecchi. L'impostazione del parametro {overwrite: true} durante l'esportazione in una tabella BigQuery esistente attiva una procedura di sovrascrittura sicura:

  1. Tabella temporanea: i dati vengono esportati in una nuova tabella temporanea all'interno del set di dati di destinazione.
  2. Sostituzione atomica: i contenuti della tabella temporanea vengono copiati nella tabella di destinazione finale, sostituendo i dati esistenti in un'unica transazione atomica.
  3. Pulizia: la tabella temporanea viene eliminata.

In questo modo, gli errori durante l'esportazione non danneggeranno i dati esistenti. Per le piccole tabelle, il ritardo è in genere di pochi minuti.

Alternative ad alte prestazioni

Per i flussi di lavoro che richiedono un throughput molto elevato, ti consigliamo di utilizzare GeoBeam per trasferire i dati da Earth Engine a BigQuery. Questa operazione richiede più configurazione e infrastruttura, pertanto ti consigliamo di iniziare con la funzionalità Earth Engine integrata.

Prezzi

L'esportazione in BigQuery è un processo batch che consuma tempo EECU batch. Se utilizzi Earth Engine a fini commerciali o operativi, l'esportazione dei dati in BigQuery comporta l'addebito del tempo EECU utilizzato dalle attività. Tutto l'utilizzo può essere monitorato con gli stessi strumenti di monitoraggio utilizzati per il resto di Earth Engine.

Account di fatturazione Cloud

Per scrivere dati in BigQuery, è necessario che nel progetto Cloud associato sia abilitato un account di fatturazione. Per scoprire di più sulla configurazione dell'account di fatturazione, consulta la documentazione relativa all'account di fatturazione Cloud.

In uscita

Tutti i costi di traffico in entrata e in uscita vengono addebitati come traffico di rete standard.

Earth Engine è ospitato solo negli Stati Uniti, ma i set di dati BigQuery possono essere ospitati in diverse altre regioni. A seconda delle regioni e dei volumi di dati coinvolti, la scrittura dei dati da Earth Engine a BigQuery può generare un traffico di rete considerevole.

Problemi noti

Orientamento per poligoni di grandi dimensioni

La funzione BigQuery Export inverte i poligoni più grandi di un emisfero volgendoli al contrario (modificando il poligono in modo da ottenere il suo complementare geometrico). In rari casi, i poligoni più grandi di un emisfero potrebbero non caricarsi.

Se necessario, i poligoni invertiti possono essere corretti in BigQuery invertendoli di nuovo utilizzando l'espressione BigQueryST_Difference(ST_GeogFromText('fullglobe'), geo).

Per saperne di più, fai clic qui.