Nach BigQuery exportieren

Übersicht

Die Computing-Architektur von Earth Engine ist für schnelle und skalierbare Bildberechnungen (pixelbasiert) optimiert. BigQuery ist ebenfalls für die skalierbare Verarbeitung tabellarischer Daten (Vektoren) optimiert und bietet viele Funktionen, die es zu einer guten Ergänzung für Earth Engine machen.

Beispiele für Workflows:

  • Große BigQuery-Joins auf in Earth Engine generierte Daten ausführen
  • Vektordaten mit Statistiken aus Bildern für die weitere Verarbeitung in BigQuery annotieren
  • Daten regelmäßig aus Earth Engine in eine BigQuery-Tabelle exportieren, in die Daten angehängt werden können

Wenn Sie weitere tolle Anwendungsfälle haben, teilen Sie sie uns gern mit.

BigQuery: Grundlagen

Earth Engine schreibt in BigQuery-Tabellen und alle Tabellen sind in Datensätzen enthalten. Exportaufgaben schlagen fehl, wenn das angegebene Dataset nicht in BigQuery vorhanden ist. Weitere Informationen finden Sie in der Einführung in BigQuery-Datasets.

Dataset-Erstellung

Für Datensätze gibt es eine Reihe von Optionen zur Erstellung, darunter Name, Speicherregion und Ablaufverhalten sowie mehrere andere, erweiterte Optionen.

Es gibt verschiedene Möglichkeiten, Datasets zu erstellen. Eine einfache Möglichkeit ist die Cloud Console:

  1. Rufen Sie in der Cloud Console die Seite „BigQuery“ auf.
  2. Klicken Sie auf „Aktivieren“, um die API zu aktivieren, falls Sie dazu aufgefordert werden.
  3. Klicken Sie auf dem Tab „SQL-Arbeitsbereich“ neben dem Projekt auf das Dreipunkt-Menü ().
  4. Wählen Sie die Option „Dataset erstellen“ aus.
  5. Folgen Sie der Konfigurationsanleitung.

Alle Optionen zum Erstellen und Konfigurieren eines Datasets finden Sie in der BigQuery-Dokumentation.

Berechtigungen

Zusätzlich zu den Standardrollen und ‑berechtigungen, die für die Verwendung von Earth Engine erforderlich sind, benötigen Aufrufer auch die richtigen BigQuery-Berechtigungen für das Cloud-Projekt oder ‑Dataset.

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

Jede der folgenden Kombinationen von vordefinierten IAM-Rollen (Identity and Access Management) enthält die erforderlichen Berechtigungen:

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

Preise

BigQuery ist ein kostenpflichtiger Google Cloud-Dienst. Daher fallen für die Nutzung von BigQuery Gebühren an, einschließlich der Speicherung und Analyse aller Earth Engine-Daten, die Sie nach BigQuery exportieren.

Weitere Informationen zu den Preisen für die BigQuery-Exportfunktion von Earth Engine finden Sie unten im Abschnitt zu Preisen.

Konfiguration exportieren

Syntax

  Export.table.toBigQuery({
    'collection': myFeatureCollection,
    'table': 'myproject.mydataset.mytable',
    'description': 'put_my_data_in_bigquery',
    'append': true,
    'overwrite': false
  });
  task = ee.batch.Export.table.toBigQuery(
      collection=myFeatureCollection,
      table='myproject.mydataset.mytable',
      description='put_my_data_in_bigquery',
      append=True,
      overwrite=False)
  task.start()

Automatische oder manuelle Schemaspezifikation

Wenn in BigQuery keine Tabelle vorhanden ist, versucht Earth Engine, anhand der Eigenschaften der ersten ee.Feature in der Sammlung ein Schema zu ermitteln. Das ist eine Schätzung. Es ist möglich, eine Sammlung zu erstellen, bei der sich das Schema der ersten Funktion vom Schema anderer Funktionen unterscheidet.

Wenn Sie ein bestimmtes Schema für Ihre BigQuery-Tabelle benötigen, konfigurieren Sie es, indem Sie eine leere Tabelle mit dem Zielschema erstellen.

Attributnamen

Die Eigenschaften von Earth Engine-Features entsprechen den Spalten in BigQuery. Earth Engine verwendet den Namen „geo“, um die ee.Feature-Geometrie (die „.geo“-Auswahl) in BigQuery zu schreiben.

Damit keine Umbenennungen erforderlich sind, müssen die Properties Ihrer ee.Feature-Objekte gültige Spaltennamen sein und keiner darf „geo“ heißen, da dieser Name für die Geometrie des Elements verwendet wird, das in Earth Engine keinen Namen hat.

Ungültige Zeichen in Property-Namen führen aufgrund von Einschränkungen für BigQuery-Spaltennamen zum Abbruch des Exports.

Typkonvertierung

Earth Engine-Daten (die Werte von ee.Feature-Properties) werden nach Möglichkeit in einen entsprechenden BigQuery-Typ konvertiert. Die Nullbarkeit wird vom Tabellenschema und nicht vom Typ gesteuert.

Earth Engine-Typ BigQuery-Typ Hinweise
ee.String STRING
ee.Number FLOAT oder INTEGER
ee.Geometry GEOGRAPHY
ee.Date TIMESTAMP
ee.ByteString BYTES
ee.Array STRUCT<ARRAY<INT64>, ARRAY<INT64|FLOAT64>> Weitere Informationen finden Sie im Abschnitt zu Arrays.
Andere ee.*-Typen Nicht unterstützt [not_supported] Weitere Informationen finden Sie im Abschnitt JSON-Werte.

Arrays

In Earth Engine werden alle mehrdimensionalen ee.Array in STRUCT<ARRAY<INT64> dimensions, ARRAY<INT64|FLOAT64> values> exportiert. Das Format ähnelt dem, das von der BigQuery-Funktion ML.DECODE_IMAGE verwendet wird.

Das erste Array im Struct, dimensions, enthält die Dimensionen des Earth Engine-Arrays, d_1 bis d_n.

Das zweite Array im Struct, values, enthält alle Werte im mehrdimensionalen Array, die zu einem einzelnen BigQuery-Array zusammengeführt wurden. Die Gesamtzahl der Werte im flachen Array ist i=1ndi. Der Wert am Index (ii,,in) im ursprünglichen Earth Engine-Array entspricht dem Wert am folgenden Index im flachen Array:

j=1n(ijk=j+1ndk)

In den meisten Fällen sieht der Indexierungsausdruck für das Array values so aus:

Array-Größe Abmessungen Indexierungsexpression
Eindimensional d1 [i1]
Zweidimensional d1, d2 [(i1 * d2) + i2]
Dreidimensional d1, d2, d3 [(i1 * d2 * d3) + (i2 * d3) + i3]

Betrachten Sie beispielsweise ein 2x3x4-Array in 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]
      ]
    ]);

Dieses Array wird in eine BigQuery-STRUCT umgewandelt, deren dimensions-Element das Array [2, 3, 4] und deren values-Element das flache Array [1, 2, 3, 4, 5, 6, 7, 8, ..., 21, 22, 23, 24] ist. Die Indizes im flachen Array können als [(i1 * 12) + (i2 * 4) + i3] berechnet werden.

JSON-Werte

Um in einer Zelle besser strukturierte Daten zu unterstützen, können Earth Engine-Werte als JSON-Objekte codiert werden. BigQuery unterstützt SQL-Vorgänge für JSON-codierte Daten. So können Sie Abfragen ausführen, die in die codierten JSON-Werte in Earth Engine „hineinschauen“.

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);

Auf der Seite Python-Umgebung finden Sie Informationen zur Python API und zur Verwendung von geemap für die interaktive Entwicklung.

import ee
import geemap.core as geemap
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()

Geometrische Conversion

BigQuery unterstützt nur begrenzt verschiedene Projektionen. Daher werden alle Earth Engine-Geometrien mit einer Fehlertoleranz von 1 Meter in geodätische EPSG:4326-Koordinaten umgewandelt.

Wenn Sie diesen Transformationsprozess genauer steuern möchten, können Sie die Features manuell zuordnen und ihre Geometrien transformieren, z.B.:

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

Auf der Seite Python-Umgebung finden Sie Informationen zur Python API und zur Verwendung von geemap für die interaktive Entwicklung.

import ee
import geemap.core as geemap
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)

Leistung

Earth Engine-Leistung

Die Earth Engine-Berechnung ist häufig das Nadelöhr für Export-Vorgänge. Dazu ist es wichtig, die Verarbeitung so zu organisieren, dass sie maximal parallel abläuft. Alle Berechnungen, die eine serielle Verarbeitung erfordern (z. B. ee.FeatureCollection.iterate()), können dazu führen, dass der Export langsam ausgeführt wird oder fehlschlägt.

Leistung in BigQuery

Die richtige Strukturierung und Klusterung von Daten ist die beste Möglichkeit, Abfragen in BigQuery effizient zu gestalten. Wenn in BigQuery noch keine Tabelle vorhanden ist, werden aus Earth Engine exportierte Tabellen nach der Geometrie der Features (falls vorhanden) gruppiert. Das Gruppieren nach dem geografischen Feld ist bei raumbezogenen Daten sehr üblich. Sie verbessert die Leistung und reduziert die Kosten für Abfragen mit geografischen Filtern, am häufigsten für BigQuery-Vorgänge wie:

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

Das Hinzufügen von Clustering zu einer nicht gruppierten Tabelle ist im Allgemeinen auch nicht schädlich, kann aber die Zeit für das Laden von Daten in die Tabelle etwas verlängern. Weitere Informationen zur Abfrageoptimierung finden Sie in der BigQuery-Dokumentation.

Die Clustereinstellungen wirken sich nur auf neue Daten aus, die in die Tabelle geschrieben werden.

Demo: reduceRegions verwenden

In einigen Fällen können Sie reduceRegions verwenden, um die Parallelität der Earth Engine-Verarbeitungsinfrastruktur so weit wie möglich zu erhöhen. In diesem Beispiel wird gezeigt, wie Sie eine kleinere Anzahl von reduceRegions-Aufrufen (ein paar hundert) anstelle von Zehntausenden von reduceRegion-Aufrufen verwenden, was der typische Ansatz für die Zuordnung einer Funktion auf eine Sammlung ist.

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'
});

Auf der Seite Python-Umgebung finden Sie Informationen zur Python API und zur Verwendung von geemap für die interaktive Entwicklung.

import ee
import geemap.core as geemap
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()

Aufgabenparallelisierung

Mit der Option {append: true} können mehrere Aufgaben gleichzeitig Daten in eine BigQuery-Tabelle schreiben. Dies ist ein Mechanismus zum Schreiben von Daten mit höherem Durchsatz, der jedoch mit einer erhöhten Komplexität verbunden ist (Verwaltung der Aufgabenwarteschlange, Wiederholung usw.).

Leistungsunterschiede zwischen append- und overwrite-Parametern

Das Überschreiben ist langsamer als das Anhängen, da BigQuery die neuen Daten verarbeiten muss, bevor die alten überschrieben werden. Wenn Sie beim Exportieren in eine vorhandene BigQuery-Tabelle den Parameter {overwrite: true} festlegen, wird ein sicherer Überschreibungsprozess ausgelöst:

  1. Temporäre Tabelle: Die Daten werden in eine neue temporäre Tabelle im Zieldatensatz exportiert.
  2. Atomisches Überschreiben: Der Inhalt der temporären Tabelle wird in die endgültige Zieltabelle kopiert und ersetzt vorhandene Daten in einer einzelnen sitzungsübergreifenden Transaktion.
  3. Bereinigung: Die temporäre Tabelle wird gelöscht.

So wird verhindert, dass vorhandene Daten durch Fehler beim Export beschädigt werden. Bei kleinen Tabellen dauert es in der Regel nur wenige Minuten.

Hochleistungsalternativen

Für Workflows mit sehr hohem Durchsatz können Sie GeoBeam verwenden, um Daten aus Earth Engine in BigQuery zu verschieben. Das erfordert mehr Konfiguration und Infrastruktur. Wir empfehlen daher, mit der integrierten Earth Engine-Funktion zu beginnen.

Preise

Der Export nach BigQuery ist ein Batchprozess, der EECU-Zeit für Batches beansprucht. Wenn Sie Earth Engine kommerziell oder betrieblich nutzen, werden Ihnen beim Exportieren von Daten nach BigQuery die für die Aufgaben benötigten EECU-Minuten in Rechnung gestellt. Die gesamte Nutzung kann mit genau denselben Monitoring-Tools überwacht werden, die auch für den Rest von Earth Engine verwendet werden.

Cloud-Rechnungskonten

Damit Daten in BigQuery geschrieben werden können, muss für das zugehörige Cloud-Projekt ein Abrechnungskonto aktiviert sein. Weitere Informationen zur Konfiguration von Abrechnungskonten finden Sie in der Dokumentation zu Cloud-Rechnungskonten.

Ausgehender Traffic

Alle Kosten für eingehenden und ausgehenden Traffic werden als Standardnetzwerkverkehr abgerechnet.

Earth Engine wird nur in den USA gehostet, BigQuery-Datasets können jedoch in einer Reihe anderer Regionen gehostet werden. Je nach Region und Datenvolumen kann das Schreiben von Daten aus Earth Engine in BigQuery erheblichen Netzwerkverkehr verursachen.

Bekannte Probleme

Ausrichtung für große Polygone

Die BigQuery-Exportfunktion invertiert Polygone, die größer als eine Hemisphäre sind, indem sie ihre Ausrichtung umkehrt (das Polygon in sein geometrisches Komplement ändert). In seltenen Fällen können Polygone, die größer als eine Hemisphäre sind, nicht geladen werden.

Bei Bedarf können umgekehrte Polygone in BigQuery korrigiert werden, indem sie mit dem BigQuery-Ausdruck ST_Difference(ST_GeogFromText('fullglobe'), geo) noch einmal umgekehrt werden.

Weitere Informationen