Экспорт в BigQuery

Обзор

Вычислительная архитектура Earth Engine оптимизирована для быстрых и масштабируемых вычислений изображений (на основе пикселей). BigQuery также оптимизирован для масштабируемой обработки табличных данных (векторов) и имеет множество функций, которые делают его хорошим дополнением к Earth Engine.

Примеры рабочих процессов включают в себя:

  • Выполнение больших объединений BigQuery для данных, созданных в Earth Engine
  • Аннотирование векторных данных с помощью статистики, полученной из изображений, для дальнейшей обработки в BigQuery
  • Периодический экспорт данных из Earth Engine в добавляемую таблицу BigQuery

Если у вас есть другие замечательные примеры использования, мы будем рады о них услышать !

Основы BigQuery

Earth Engine записывает данные в таблицы BigQuery, а все таблицы содержатся в наборах данных. Задачи экспорта завершаются неудачей, если указанный набор данных отсутствует в BigQuery. Узнайте больше во введении к набору данных BigQuery .

Создание набора данных

Наборы данных имеют ряд параметров, настраиваемых при создании, включая имя, регион хранения и поведение при истечении срока действия (а также несколько других, более расширенных параметров).

Существует множество механизмов создания наборов данных , но самый простой способ начать работу — через облачную консоль:

  1. Перейдите на страницу BigQuery в консоли Cloud .
  2. Нажмите «Включить», чтобы включить API, если будет предложено.
  3. На вкладке «Рабочая область SQL» щелкните меню с тремя точками ( ) рядом с проектом.
  4. Выберите опцию «Создать набор данных».
  5. Следуйте руководству по настройке.

Все варианты создания и настройки набора данных см. в документации BigQuery .

Разрешения

Помимо стандартных ролей и разрешений, необходимых для использования Earth Engine, вызывающим сторонам также необходимы правильные разрешения BigQuery для проекта или набора данных Cloud.

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

Любая из следующих комбинаций предопределенных ролей управления идентификацией и доступом (IAM) включает необходимые разрешения:

  • bigquery.dataEditor плюс bigquery.jobUser
  • bigquery.dataOwner плюс bigquery.jobUser
  • bigquery.user
  • bigquery.admin

Ценообразование

BigQuery — это платный сервис Google Cloud, поэтому за использование BigQuery, включая хранение и анализ любых данных Earth Engine, которые вы экспортируете в BigQuery, будет взиматься плата .

Подробную информацию о ценах на функцию экспорта BigQuery от Earth Engine см. в разделе цен ниже.

Экспортировать конфигурацию

Синтаксис

Редактор кода (JavaScript)

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

Настройка Python

Информацию об API Python и использовании geemap для интерактивной разработки см. на странице Python Environment .

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

Автоматическая или ручная спецификация схемы

Если в BigQuery нет таблицы, Earth Engine пытается определить схему , используя свойства первого ee.Feature в коллекции. Это лучшее предположение, и можно построить коллекцию, в которой схема первого объекта отличается от схемы других объектов.

Если вам требуется определенная схема для таблицы BigQuery, настройте ее, создав пустую таблицу с целевой схемой .

Названия свойств

Свойства объектов Earth Engine соответствуют столбцам в BigQuery. Earth Engine использует имя "geo" для записи геометрии ee.Feature (селектор ".geo") в BigQuery.

Чтобы избежать переименования, убедитесь, что свойства объектов ee.Feature являются допустимыми именами столбцов и ни одно из них не имеет имени «geo» (поскольку это имя используется для геометрии объекта, которая не имеет имени в Earth Engine).

Недопустимые символы в именах свойств приводят к сбою экспорта из-за ограничений на имена столбцов BigQuery .

Преобразование типов

Данные Earth Engine (значения свойств ee.Feature ) преобразуются в эквивалентный тип BigQuery, когда это возможно. Обратите внимание, что допустимость значений null контролируется схемой таблицы, а не типом.

Тип двигателя Земли Тип BigQuery Примечания
ee.String STRING
ee.Number FLOAT или INTEGER
ee.Geometry GEOGRAPHY
ee.Date TIMESTAMP
ee.ByteString BYTES
ee.Array STRUCT<ARRAY<INT64>, ARRAY<INT64|FLOAT64>> См. раздел о массивах
Другие типы ee.* не поддерживается См. раздел о значениях JSON.

Массивы

Earth Engine экспортирует любой многомерный ee.Array в STRUCT<ARRAY<INT64> dimensions, ARRAY<INT64|FLOAT64> values> , аналогично формату, используемому функцией BigQuery ML.DECODE_IMAGE .

Первый массив в структуре, dimensions , содержит измерения массива Earth Engine, от $d_1$ до $d_n$.

Второй массив в структуре, values ​​, содержит все значения в многомерном массиве, сведенные в один массив BigQuery. Общее количество значений в сведенном массиве составляет $\sum_{i=1}^n d_i$, а значение по индексу $(i_i, \ldots, i_n)$ в исходном массиве Earth Engine соответствует значению по следующему индексу в сведенном массиве:

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

Для общих случаев выражение индексации для массива values выглядит следующим образом:

Размер массива Размеры Индексирование выражения
1-мерный d1 [i1]
2-мерный d1, d2 [(i1 * d2) + i2]
3-х мерный d1, d2, d3 [(i1 * d2 * d3) + (i2 * d3) + i3]

Например, рассмотрим массив Earth Engine 2x3x4 :

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

Этот массив преобразуется в BigQuery STRUCT , элемент dimensions которого является массивом [2, 3, 4] , а элемент values ​​— сглаженным массивом [1, 2, 3, 4, 5, 6, 7, 8, ..., 21, 22, 23, 24] . Индексы в сглаженном массиве можно вычислить как [(i1 * 12) + (i2 * 4) + i3] .

Значения JSON

Для поддержки более структурированных данных в ячейке можно кодировать значения Earth Engine как объекты JSON . BigQuery поддерживает операции SQL над данными в кодировке JSON , позволяя выполнять запросы, которые «заглядывают внутрь» кодированных значений JSON, которые вы создаете в Earth Engine.

Редактор кода (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);

Настройка Python

Информацию об API Python и использовании geemap для интерактивной разработки см. на странице Python Environment .

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

Преобразование геометрии

BigQuery имеет ограниченную поддержку различных проекций , поэтому все геометрии Earth Engine преобразуются в геодезические EPSG:4326 с погрешностью 1 метр.

Чтобы лучше контролировать этот процесс преобразования, вы можете вручную сопоставить объекты и преобразовать их геометрию, например:

Редактор кода (JavaScript)

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

Настройка Python

Информацию об API Python и использовании geemap для интерактивной разработки см. на странице Python Environment .

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)

Производительность

Производительность двигателя Земли

Вычисления Earth Engine часто являются узким местом для операций Export . С этой целью важно организовать обработку для максимального параллелизма. Любое вычисление, которое запекается в последовательной обработке (например, ee.FeatureCollection.iterate() ), может привести к медленному выполнению или сбою экспорта.

Производительность в BigQuery

Правильное структурирование и кластеризация данных — лучший способ гарантировать, что запросы могут быть сделаны эффективными в BigQuery. Если в BigQuery еще нет таблицы, таблицы, экспортированные из Earth Engine, кластеризуются по геометрии объектов (если она присутствует). Кластеризация по полю географии очень распространена для геопространственных данных. Она повышает производительность и снижает стоимость для запросов, которые используют пространственные фильтры, чаще всего для операций BigQuery, таких как:

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

Добавление кластеризации в некластеризованную таблицу также обычно ничему не вредит, хотя может немного увеличить время загрузки данных в таблицу. Подробнее об оптимизации запросов см. в документации BigQuery .

Обратите внимание, что настройки кластеризации влияют только на новые данные, записываемые в таблицу.

Демонстрация: использование reduceRegions

В некоторых случаях можно использовать reduceRegions , чтобы получить как можно больше параллелизма от инфраструктуры обработки Earth Engine. Этот пример демонстрирует, как использовать меньшее количество вызовов reduceRegions (несколько сотен) вместо десятков тысяч вызовов reduceRegion (типичный подход для отображения функции на коллекцию).

Редактор кода (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'
});

Настройка Python

Информацию об API Python и использовании geemap для интерактивной разработки см. на странице Python Environment .

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

Распараллеливание задач

С опцией {append: true} возможно, что несколько задач будут записывать данные в таблицу BigQuery одновременно. Это механизм для записи данных с более высокой пропускной способностью, но он достигается за счет увеличения сложности (управление очередью задач, повторные попытки и т. д.).

Различия в производительности между параметрами append и overwrite

Обратите внимание, что перезапись медленнее, чем добавление, поскольку BigQuery должен обработать новые данные перед перезаписью старых. Установка параметра {overwrite: true} при экспорте в существующую таблицу BigQuery запускает безопасный процесс перезаписи:

  1. Временная таблица: данные экспортируются в новую временную таблицу в целевом наборе данных.
  2. Атомарная перезапись: содержимое временной таблицы копируется в конечную целевую таблицу, заменяя существующие данные в одной атомарной транзакции.
  3. Очистка: временная таблица удаляется.

Это гарантирует, что ошибки во время экспорта не повредят ваши существующие данные. Для небольших таблиц задержка обычно составляет несколько минут.

Высокопроизводительные альтернативы

Для рабочих процессов, требующих очень высокой пропускной способности, рассмотрите возможность использования GeoBeam для перемещения данных из Earth Engine в BigQuery . Это требует большей конфигурации и инфраструктуры, поэтому мы предлагаем начать со встроенной функциональности Earth Engine.

Ценообразование

Экспорт в BigQuery — это пакетный процесс, который потребляет пакетное время EECU. Если вы используете Earth Engine в коммерческих или операционных целях, экспорт данных в BigQuery будет стоить вам EECU-время, используемое задачами. Все использование можно отслеживать с помощью тех же самых инструментов мониторинга , которые работают для остальной части Earth Engine.

Облачные счета для выставления счетов

Для записи данных в BigQuery, связанный проект Cloud должен иметь включенный счет выставления счетов. Чтобы узнать больше о настройке счета выставления счетов, см. документацию по счету выставления счетов Cloud .

Выход

Все входящие и исходящие расходы тарифицируются как стандартный сетевой трафик.

Earth Engine размещается только в США, но наборы данных BigQuery могут размещаться в ряде других регионов . В зависимости от регионов и объемов данных, запись данных из Earth Engine в BigQuery может генерировать значительный сетевой трафик.

Известные проблемы

Ориентация для больших полигонов

Функция экспорта BigQuery инвертирует многоугольники, которые больше полусферы, изменяя их ориентацию (изменяя многоугольник на его геометрическое дополнение). В редких случаях многоугольники, большие полусферы, могут не загружаться.

При необходимости инвертированные полигоны можно исправить в BigQuery, инвертировав их снова, используя выражение BigQuery ST_Difference(ST_GeogFromText('fullglobe'), geo) .

Более подробную информацию смотрите здесь .