Visão geral
A arquitetura computacional do Earth Engine é otimizada para tornar a computação de imagens (baseada em pixels) rápida e escalonável. O BigQuery também é otimizado para processamento escalonável de dados tabulares (vetores) e tem muitos recursos que o tornam um bom complemento para o Earth Engine.
Confira alguns exemplos de fluxos de trabalho:
- Como realizar mesclagens grandes do BigQuery em dados gerados no Earth Engine
- Como anotar dados vetoriais com estatísticas derivadas de imagens para processamento no BigQuery
- Exportar dados periodicamente do Earth Engine para uma tabela do BigQuery que pode ser anexada
Se você tiver outros casos de uso incríveis, conte para a gente.
Noções básicas do BigQuery
O Earth Engine grava em tabelas do BigQuery, e todas as tabelas estão contidas em conjuntos de dados. As tarefas de exportação falham se o conjunto de dados especificado não estiver presente no BigQuery. Saiba mais na introdução ao conjunto de dados do BigQuery.
Criação do conjunto de dados
Os conjuntos de dados têm várias opções de criação, incluindo o nome, a região de armazenamento e o comportamento de expiração, além de várias outras opções mais avançadas.
Há vários mecanismos para criar conjuntos de dados, mas uma maneira simples de começar é pelo Console do Cloud:
- Acesse a página do BigQuery no console do Cloud.
- Clique em "Ativar" para ativar a API, se necessário.
- Na guia "SQL Workspace", clique no menu de três pontos ( ) ao lado do projeto.
- Escolha a opção "Criar conjunto de dados".
- Siga o guia de configuração.
Para conferir todas as opções de criação e configuração de um conjunto de dados, consulte a documentação do BigQuery.
Permissões
Além das funções e permissões padrão necessárias para usar o Earth Engine, os autores da chamada também precisam das permissões do BigQuery corretas no projeto ou conjunto de dados do Cloud.
bigquery.tables.get
bigquery.tables.create
bigquery.tables.updateData
bigquery.tables.delete
bigquery.jobs.create
Qualquer uma das seguintes combinações de papéis predefinidos do Identity and Access Management (IAM) inclui as permissões necessárias:
bigquery.dataEditor
maisbigquery.jobUser
bigquery.dataOwner
maisbigquery.jobUser
bigquery.user
bigquery.admin
Preços
O BigQuery é um serviço pago do Google Cloud. Por isso, você vai receber taxas pelo uso do BigQuery, incluindo armazenamento e análise de todos os dados do Earth Engine exportados para o BigQuery.
Para saber mais sobre os preços do recurso de exportação do BigQuery do Earth Engine, consulte a seção de preços abaixo.
Exportar configuração
Sintaxe
Editor de código (JavaScript)
Export.table.toBigQuery({ collection: features, table: 'myproject.mydataset.mytable', description: 'put_my_data_in_bigquery', append: true, overwrite: false });
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()
Especificação de esquema automática ou manual
Se não houver nenhuma tabela no BigQuery, o Earth Engine tentará determinar um esquema usando as propriedades do primeiro ee.Feature
na coleção. Essa é a melhor estimativa, e é possível criar uma coleção
em que o esquema do primeiro recurso é diferente do esquema de outros
recursos.
Se você precisar de um esquema específico na tabela do BigQuery, configure-o criando uma tabela vazia com o esquema de destino.
Nomes de propriedades
As propriedades nos elementos do Earth Engine correspondem a colunas no BigQuery. O Earth Engine usa o nome "geo" para gravar a geometria ee.Feature
(o seletor ".geo") no BigQuery.
Para evitar renomeações, verifique se os objetos ee.Feature
têm propriedades que são nomes de coluna válidos e se nenhum deles é chamado de "geo", já que esse nome é usado para a geometria do elemento, que não tem nome no Earth Engine.
Caracteres inválidos nos nomes de propriedade fazem com que a exportação falhe devido a restrições nos nomes de colunas do BigQuery.
Conversão de tipo
Os dados do Earth Engine (os valores das propriedades ee.Feature
) são convertidos em um
tipo equivalente do BigQuery sempre que possível. A nulidade é
controlada pelo esquema da tabela, não pelo tipo.
Tipo do Earth Engine | Tipo do BigQuery | Observações |
---|---|---|
ee.String |
STRING |
|
ee.Number
|
FLOAT ou
INTEGER
|
|
ee.Geometry |
GEOGRAPHY |
|
ee.Date |
TIMESTAMP |
|
ee.ByteString |
BYTES |
|
ee.Array
|
STRUCT<ARRAY<INT64>,
ARRAY<INT64|FLOAT64>> |
Consulte a seção sobre matrizes. |
Outros tipos de ee.*
|
not supported | Consulte a seção sobre valores JSON. |
Matrizes
O Earth Engine exporta qualquer ee.Array
multidimensional para STRUCT<ARRAY<INT64> dimensions, ARRAY<INT64|FLOAT64> values>
, semelhante ao formato usado pela função ML.DECODE_IMAGE do BigQuery.
A primeira matriz na struct, dimensions
, contém as dimensões da matriz do Earth Engine, de $d_1$ a $d_n$.
A segunda matriz no struct, values
, contém todos os valores na
matriz multidimensional, achatada em uma única matriz do BigQuery.
O número total de valores na matriz achatada é $\sum_{i=1}^n d_i$, e
o valor no índice $(i_i, \ldots, i_n)$ na matriz original do Earth Engine
corresponde ao valor no índice a seguir na matriz achatada:
\[ \sum_{j=1}^n \left( i_j \cdot \prod_{k=j+1}^n d_k \right) \]
Para casos comuns, a expressão de indexação para a matriz values
é a seguinte:
Tamanho da matriz | Dimensões | Expressão de indexação |
---|---|---|
Unidimensional | d1 |
[i1] |
Bidimensional | d1, d2 |
[(i1 * d2) + i2] |
Tridimensional | d1, d2, d3 |
[(i1 * d2 * d3) + (i2 * d3) + i3] |
Por exemplo, considere uma matriz 2x3x4
do 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]
]
]);
Essa matriz é convertida em um STRUCT
do BigQuery em que o elemento dimensions
é a matriz [2, 3, 4]
e o elemento values
é a matriz plana [1, 2, 3, 4, 5, 6, 7, 8, ..., 21, 22, 23, 24]
.
Os índices na matriz plana podem ser calculados como
[(i1 * 12) + (i2 * 4) + i3]
.
Valores JSON
Para oferecer suporte a dados mais estruturados em uma célula, é possível codificar os valores do Earth Engine como objetos JSON. O BigQuery oferece suporte a operações SQL em dados codificados em JSON, permitindo consultas que "procuram dentro" dos valores JSON codificados que você produz no Earth Engine.
Editor de código (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);
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()
Conversão de geometria
O BigQuery tem suporte limitado para diferentes projeções. Portanto, todas as geometrias do Motor do Google Earth são transformadas em EPSG:4326
geodésica usando uma margem de erro de 1 metro.
Para ter um controle mais preciso sobre esse processo de transformação, é possível mapear manualmente os elementos e transformar as geometrias deles, por exemplo:
Editor de código (JavaScript)
var transformedCollection = originalCollection.map(function transformGeo(e) { var myErrorMargin = 10 * 1000; // meters return e.setGeometry(e.geometry(myErrorMargin, 'EPSG:4326', true)); });
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)
Desempenho
Desempenho do Earth Engine
A computação do Earth Engine geralmente é o gargalo das operações Export
. Para
isso, é importante organizar o processamento para o máximo de paralelismo.
Qualquer cálculo que seja incorporado ao processamento em série (por exemplo,
ee.FeatureCollection.iterate()
) pode fazer com que a exportação seja executada lentamente ou falhe.
Desempenho no BigQuery
Estruturar e agrupar dados corretamente é a melhor maneira de garantir que as consultas sejam eficientes no BigQuery. Se não houver uma tabela já presente no BigQuery, as tabelas exportadas do Earth Engine serão agrupadas na geometria dos elementos (se houver). Agrupar por campo de geografia é muito comum para dados geoespaciais. Isso melhora a performance e reduz o custo das consultas que usam filtros espaciais, geralmente para operações do BigQuery, como:
WHERE ST_DWithin(<table_column>, <constant_geography>, <distance>)
WHERE ST_Intersects(<table_column>, <constant_geography>)
Adicionar agrupamento a uma tabela não agrupada também não prejudica nada, embora possa aumentar um pouco o tempo de carregamento de dados na tabela. Para saber mais sobre a otimização de consultas, consulte a documentação do BigQuery.
As configurações de agrupamento afetam apenas os dados novos gravados na tabela.
Demonstração: como usar reduceRegions
Em alguns casos, é possível usar reduceRegions
para ter o máximo de paralelismo
possível da infraestrutura de processamento do Earth Engine. Este exemplo
demonstra como usar um número menor de chamadas reduceRegions
(algumas
centenas) em vez de dezenas de milhares de chamadas reduceRegion
(a abordagem
típica para mapear uma função em uma coleção).
Editor de código (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' });
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()
Paralelização de tarefas
Com a opção {append: true}
, várias tarefas podem gravar dados
em uma tabela do BigQuery simultaneamente. Esse é um mecanismo para gravar dados com um
maior throughput, mas tem o custo de maior complexidade (gerenciamento
da fila de tarefas, nova tentativa etc.).
Diferenças de desempenho entre os parâmetros append
e overwrite
A substituição é mais lenta do que a adição porque o BigQuery precisa processar os novos dados antes de substituir os antigos. Definir o parâmetro {overwrite: true} ao exportar para uma tabela do BigQuery aciona um processo de substituição segura:
- Tabela temporária: os dados são exportados para uma nova tabela temporária no conjunto de dados de destino.
- Substituir de forma atômica: o conteúdo da tabela temporária é copiado para a tabela de destino final, substituindo os dados atuais em uma única transação atômica.
- Limpeza: a tabela temporária é excluída.
Isso garante que erros durante a exportação não corrompam seus dados. Para tabelas pequenas, o atraso geralmente é de alguns minutos.
Alternativas de alto desempenho
Para fluxos de trabalho que exigem um throughput muito alto, use o GeoBeam para mover dados do Earth Engine para o BigQuery. Isso requer mais configuração e infraestrutura. Por isso, sugerimos começar com a funcionalidade integrada do Earth Engine.
Preços
A exportação para o BigQuery é um processo em lote que consome o tempo de EECU em lote. Se você usar o Earth Engine comercialmente ou operacionalmente, a exportação de dados para o BigQuery vai cobrar o tempo de EECU usado pelas tarefas. Todo o uso pode ser monitorado com exatamente as mesmas ferramentas de monitoramento que funcionam para o restante do Earth Engine.
Contas do Cloud Billing
Para gravar dados no BigQuery, o projeto do Cloud associado precisa ter uma conta de faturamento ativada. Para saber mais sobre a configuração da conta de faturamento, consulte a documentação da conta de faturamento do Cloud.
Saída
Todos os custos de entrada e saída são cobrados como tráfego de rede padrão.
O Earth Engine é hospedado apenas nos EUA, mas os conjuntos de dados do BigQuery podem ser hospedados em várias outras regiões. Dependendo das regiões e dos volumes de dados envolvidos, a gravação de dados do Earth Engine no BigQuery pode gerar um tráfego de rede considerável.
Problemas conhecidos
Orientação para polígonos grandes
A função de exportação do BigQuery inverte polígonos maiores que um hemisfério reversando a orientação deles (mudando o polígono para o complemento geométrico). Em casos raros, polígonos maiores que um hemisfério podem não carregar.
Se necessário, os polígonos invertidos podem ser corrigidos no BigQuery invertendo-os novamente usando a expressão ST_Difference(ST_GeogFromText('fullglobe'), geo)
.
Para mais informações, acesse este link.