O Earth Engine oferece suporte a recursos com GeoTIFFs otimizados para a nuvem (COGs, na sigla em inglês). Uma vantagem dos recursos com suporte do COG é que os campos espaciais e de metadados da imagem são indexados no momento da criação do recurso, o que melhora o desempenho da imagem nas coleções. A performance dos recursos com suporte do COG é comparável à dos recursos ingeridos em casos de uso típicos.
Um único recurso pode ser apoiado por vários COGs (por exemplo, pode haver um COG por banda). No entanto, não é possível usar muitos blocos de COG para uma única faixa.
Como alternativa, o Earth Engine pode carregar imagens diretamente de COGs no Google Cloud Storage. Saiba
mais.
No entanto, uma imagem carregada por ee.Image.loadGeoTIFF
e adicionada a uma coleção
de imagens vai exigir a leitura do GeoTiff para operações de filtragem na
coleção.
Para criar um recurso com suporte a COG,
- Coloque seus arquivos COG em um bucket do GCS (confira abaixo as regiões permitidas).
- Gravar um manifesto de upload de imagem
- Use o utilitário de linha de comando
earthengine
para enviar um comando de upload:
earthengine upload external_image --manifest my_manifest.json
Exemplo de manifesto de imagem com um Tileset
A ImageManifest
mais simples é aquela com um único Tileset
. Se nenhuma banda for especificada, o recurso resultante vai conter todas as bandas do GeoTIFF com os nomes de banda codificados no GeoTIFF (neste caso, "vis-red", "vis-green" e "vis-blue").
request = {
'imageManifest': {
'name': f'projects/{ee_project}/assets/cogdemo1',
'tilesets': [
{ 'id': '0', 'sources': [ { 'uris': ['gs://ee-docs-demos/COG_demo.tif'] } ] }
],
'properties': {
'version': '1.1'
},
'startTime': '2016-01-01T00:00:00.000000000Z',
'endTime': '2016-12-31T15:01:23.000000000Z',
},
}
pprint(request)
Mais de um Tileset
É possível especificar um ImageManifest
com mais de um Tileset
, em que
cada banda do recurso resultante é apoiada por uma das bandas de um Tileset
usando os campos tilesetId
e tilesetBandIndex
. Isso é útil quando bandas diferentes têm resoluções ou tipos de dados diferentes. As faixas podem ser
listadas em qualquer ordem de qualquer Tileset
disponível. No exemplo abaixo:
- "b4b3b2.tif" tem uma escala de 10 m, enquanto "b5b6b7" tem uma escala de 20 m.
- A ordem de faixa do recurso resultante é misturada a partir dos COGs de entrada (por exemplo,
a faixa de saída 0 é de
Tileset
0, enquanto a faixa de saída 1 é deTileset
1).
request = {
'imageManifest': {
'name': f'projects/{ee_project}/assets/cogdemo2',
'uriPrefix': 'gs://ee-docs-demos/external_image_demo/',
'tilesets': [
{ 'id': '0', 'sources': [ { 'uris': ['b4b3b2.tif'] } ] },
{ 'id': '1', 'sources': [ { 'uris': ['b5b6b7.tif'] } ] },
],
'bands': [
{ 'id': 'red', 'tilesetId': '0', 'tilesetBandIndex': 0 },
{ 'id': 'rededge3', 'tilesetId': '1', 'tilesetBandIndex': 2 },
{ 'id': 'rededge2', 'tilesetId': '1', 'tilesetBandIndex': 1 },
{ 'id': 'green', 'tilesetId': '0', 'tilesetBandIndex': 1 },
{ 'id': 'blue', 'tilesetId': '1', 'tilesetBandIndex': 0 },
{ 'id': 'rededge1', 'tilesetId': '0', 'tilesetBandIndex': 2 },
],
},
}
pprint(request)
Detalhes sobre os recursos com COG
Local
O local do bucket do Cloud Storage precisa ser um destes:
- A multirregião dos EUA
- Qualquer região dupla dos EUA que inclua a US-CENTRAL1
- A região US-CENTRAL1
Classe de armazenamento
A classe de armazenamento do bucket precisa ser "Armazenamento padrão".
Permissões de compartilhamento
As ACLs dos recursos do Earth Engine com suporte do COG e os dados subjacentes são gerenciados separadamente. Ao compartilhar recursos com suporte de COG com colaboradores para leitura, é responsabilidade do proprietário garantir que o acesso de leitura seja concedido ao recurso do Earth Engine e aos arquivos COG.
1. Conceder permissões de leitura para o bucket do Google Cloud Storage
Para que os colaboradores leiam os recursos com suporte de COG, eles precisam primeiro ter acesso de leitura aos
arquivos COG no bucket do Google Cloud Storage. Sem essas
permissões, o Earth Engine não poderá recuperar os dados. Se os dados no Google Cloud Storage não estiverem visíveis para um usuário do Earth Engine, o Earth Engine vai retornar um erro do tipo "Não foi possível carregar o GeoTIFF em gs://my-bucket/my-object#123456
" (em que 123456 é a geração do objeto).
Especificamente, os colaboradores precisam ter as seguintes permissões:
storage.buckets.get
no bucket para recuperar os metadados e o local do bucket, permitindo que o Earth Engine resolva corretamente a origem do recurso.storage.objects.get
no bucket para ler os dados de recursos realmente armazenados no COG.
Essas permissões são fornecidas pelos papéis "Storage Legacy Bucket Reader" e "Storage Legacy Object Reader", respectivamente, entre outros.
Para atribuir esses papéis a colaboradores:
- Acesse a página de permissão do bucket:
https://console.cloud.google.com/storage/browser/{MY-BUCKET};tab=permissions
- Clique em CONCEDER ACESSO.
- Adicione todos os principais (por exemplo, usuários, grupos, contas de serviço) que precisam ter acesso de leitura.
- Atribua as seguintes funções:
- Leitor de bucket legado do Storage: fornece
storage.buckets.get
e outras permissões de leitura no nível do bucket. - "Leitor de objeto legado do Storage" (fornece
storage.objects.get
). - Como alternativa, crie um novo papel personalizado com apenas as permissões
storage.buckets.get
estorage.objects.get
e atribua-o.
- Leitor de bucket legado do Storage: fornece
- Salvar
2. Compartilhar o recurso do Earth Engine para leitura
Depois de garantir que seus colaboradores tenham as permissões necessárias no bucket e nos objetos do GCS, você também precisa compartilhar o próprio recurso do Earth Engine. Para mais informações sobre como definir permissões de recursos do Earth Engine, consulte o guia de gerenciamento de recursos do Earth Engine.
Gerações
Quando um recurso com suporte do COG é criado, o Earth Engine lê os metadados dos TIFFs especificados no manifesto e cria uma entrada de armazenamento de recursos. Cada URI associado
a essa entrada pode ter uma geração. Consulte os documentos de controle de versão de
objetos para saber mais sobre
gerações. Se uma geração for especificada, por exemplo, gs://foo/bar#123
,
o Earth Engine vai armazenar esse URI literalmente. Se nenhuma geração for especificada,
o Earth Engine vai armazenar esse URI com a geração do TIFF no momento em que
ImportExternalImage
foi chamado.
Isso significa que, se qualquer TIFF que inclua um recurso externo no GCS for atualizado,
alterando a geração, o Earth Engine vai retornar o erro "Não foi possível carregar
o GeoTIFF em gs://my-bucket/my-object#123456
" porque o objeto esperado
não existe mais, a menos que o bucket permita várias versões de objetos.
Essa política foi projetada para manter os metadados do recurso sincronizados com os metadados
do objeto.
Configuração
Em termos de como uma COG deve ser configurada, o TIFF PRECISA ser:
Em blocos, em que as dimensões são:
- 256x256
- 512x512
- 1024x1024
- 2.048 x 2.048
Organizada para que todos os IFDs estejam no início.
Para ter o melhor desempenho:
- Use dimensões de bloco de 512 x 512 ou mais.
- Inclua as informações gerais sobre o poder de 2.
Dependendo dos casos de uso pretendidos, a opção de criação 'INTERLEAVE' pode afetar a performance. Recomendamos o uso da intercalação BAND em todas as circunstâncias.
Consulte esta página para mais detalhes sobre uma configuração otimizada.
O comando gdal_translate
a seguir vai converter um raster em um GeoTIFF otimizado para a nuvem, com bandas intercaladas, com compactação zstd, que vai ter bom desempenho no Earth Engine:
gdal_translate in.tif out.tif \
-co COPY_SRC_OVERVIEWS=YES \
-co TILED=YES \
-co BLOCKXSIZE=512 \
-co BLOCKYSIZE=512 \
-co COMPRESS=ZSTD \
-co ZSTD_LEVEL=22 \
-co INTERLEAVE=BAND \
-co NUM_THREADS=ALL_CPUS
Talvez seja possível reduzir ainda mais o tamanho do arquivo de saída especificando um
previsor
(-co PREDICTOR=2
para tipos de dados inteiros e -co PREDICTOR=3
para tipos de dados de ponto flutuante).
Para usuários com GDAL >= 3.11, o driver COG pode produzir arquivos sem precisar se preocupar em criar e preservar informações gerais.
gdal_translate in.tif out.tif \
-of COG \
-co OVERVIEWS=IGNORE_EXISTING \
-co COMPRESS=ZSTD \
-co LEVEL=22 \
-co PREDICTOR=2 \
-co INTERLEAVE=BAND \
-co NUM_THREADS=ALL_CPUS \
Como criar recursos com base em Cloud GeoTiff usando a API REST
Observação: a API REST contém recursos novos e avançados que podem não ser adequados para todos os usuários. Se você é iniciante no Earth Engine, recomendamos começar com o guia de JavaScript.
Para criar um recurso com suporte do COG usando a API REST, faça uma solicitação POST
para o endpoint ImportExternalImage
do Earth Engine.
Como mostrado abaixo, essa solicitação precisa ser autorizada para criar um recurso na
pasta do usuário.
Iniciar uma sessão autorizada
Para criar um recurso do Earth Engine na sua pasta de usuário, você precisa se autenticar como você mesmo ao fazer a solicitação. É possível usar as credenciais do autenticador do Earth Engine para iniciar um AuthorizedSession
.
Em seguida, use AuthorizedSession
para enviar solicitações ao Earth Engine.
import ee
import json
from pprint import pprint
from google.auth.transport.requests import AuthorizedSession
ee.Authenticate() # or !earthengine authenticate --auth_mode=gcloud
# Specify the cloud project you want associated with Earth Engine requests.
ee_project = 'your-project'
session = AuthorizedSession(
ee.data.get_persistent_credentials().with_quota_project(ee_project)
)
Corpo da solicitação
O corpo da solicitação é uma instância de um
ImageManifest
.
É aqui que o caminho para o COG é especificado, junto com outras propriedades úteis.
Consulte este
guia para
mais detalhes sobre como configurar um ImageManifest
. É possível definir um ou
mais Tileset
com cada uma das bandas de suporte. Para ImportExternalImage
,
é possível usar no máximo um ImageSource
por Tileset
.
Consulte este documento para saber como exportar COGs.
Enviar a solicitação
Faça a solicitação POST para o endpoint projects.images.importExternal
do Earth Engine.
url = f'https://earthengine.googleapis.com/v1alpha/projects/{ee_project}/image:importExternal'
response = session.post(
url = url,
data = json.dumps(request)
)
pprint(json.loads(response.content))