O Que É um Cloud Optimized GeoTIFF (COG)? Como Verificar um e Como Criar um
Um Cloud Optimized GeoTIFF não é um novo formato de arquivo. É um GeoTIFF comum cujos bytes estão organizados para que um programa que o lê pela rede busque apenas os poucos kilobytes de que precisa, em vez do arquivo inteiro. O mesmo .tif continua abrindo no QGIS, no ArcGIS, em Python, em qualquer coisa que já tenha aberto um TIFF. Um COG é uma convenção de organização, não um formato — vale dizer isso logo de cara, porque é o equívoco mais comum, e porque um arquivo que não é um COG não está quebrado, só está mal organizado para a rede.
Tudo abaixo foi rodado em 11 de setembro de 2026 com o GDAL 3.13.3 sobre imagens reais do Sentinel-2. Quando uma afirmação vem da documentação em vez de um teste feito aqui, a gente avisa.
O que um COG realmente é
Três propriedades transformam um GeoTIFF em um COG, e as três vivem dentro do mesmo arquivo.
- Tiles internos em vez de faixas (strips). Uma exportação de desktop guarda a imagem em faixas com a largura toda — quantas linhas entram em cada uma é decisão do codificador, e as nossas saíram com uma linha por faixa — então um pequeno quadrado no meio do arquivo custa centenas delas. Um COG guarda blocos quadrados, 512 pixels de lado por padrão, então uma janela custa algumas leituras contíguas.
- Overviews dentro do mesmo arquivo. Cópias em resolução reduzida são escritas antes dos dados em resolução total — num arquivo
-of COGo menor nível da pirâmide fica nos primeiros kilobytes — então um visualizador que precisa de uma miniatura lê a miniatura em vez de decodificar 120 milhões de pixels e descartar a maioria deles. - Um cabeçalho que um cliente lê em uma ou duas requisições. As image file directories — os blocos de tags que dizem o tamanho da imagem e onde cada tile começa — ficam no início do arquivo, então um cliente as lê uma vez e depois pede só os tiles que quer.
Num arquivo real: um asset true-color do Sentinel-2 do bucket aberto sentinel-cogs reporta LAYOUT=COG, COMPRESSION=DEFLATE, Band 1 Block=1024x1024 e Overviews: 5490x5490, 2745x2745, 1373x1373, 687x687. Escrevendo os mesmos pixels de novo com gdal_translate -of GTiff -co TILED=NO -co COMPRESS=NONE, essa imagem de 10,980 pixels de lado vira 361,747,558 bytes com Band 1 Block=10980x1: uma faixa por linha, sem overviews, sem compressão. Pixels idênticos, inútil pela rede.
Como verificar se um GeoTIFF é um COG
O verificador no navegador
A checagem mais rápida não precisa de instalação: solte o arquivo no COG checker. Ele lê o cabeçalho no seu navegador com o geotiff.js e reporta quatro coisas. Não tem caixa de URL e nada é enviado — ele só vê o arquivo que você soltar.
- Georreferenciado — o arquivo carrega um CRS, e um resultado positivo o nomeia:
Georreferenciado (EPSG:32719). - Tiles internos — blocos quadrados em vez de faixas. Um resultado positivo imprime o tamanho do bloco,
Dividido em tiles internos (512×512).; uma falha imprimeEm faixas (striped), sem tiles — o COG exige tiles internos. - Overviews (pirâmides) — níveis em resolução reduzida dentro do mesmo arquivo, com a contagem. Uma falha imprime
Sem overviews (pirâmides) — obrigatórios para um COG. - Compressão — uma recomendação, e a que mais surpreende. É um aviso, nunca uma falha. Construímos um arquivo dividido em tiles com overviews e
-co COMPRESS=NONE, soltamos no verificador, e a ferramenta respondeu✓ É um COG válido, com a linha de compressão como uma nota dizendoSem compressão — válido, mas DEFLATE/LZW reduziriam o tamanho do arquivo.Num arquivo que o verificador lê como comprimido, essa linha nomeia o codec em vez disso.
Então o veredito é as três primeiras juntas. Perca qualquer uma delas e o arquivo não é um COG; perca só a recomendação de compressão e ele continua sendo. "Um COG tem que ser comprimido" não deveria estar no seu checklist.
gdalinfo, e as três linhas que são ausências
Com o GDAL instalado, gdalinfo file.tif responde à mesma pergunta, e o truque é que todo "não" é impresso como coisa nenhuma.
- Tiles é o valor de
Block=em cada banda.Block=512x512é dividido em tiles;Block=10980x1, a largura da imagem por um, é em faixas. - Overviews são uma linha
Overviews:sob a listagem da banda, com cada nível. Sem pirâmide, ogdalinfonão diz "nenhum" — ele simplesmente não imprime essa linha e a estrofe da banda termina. - Compressão é uma linha
COMPRESSION=emImage Structure Metadata. Sem compressão é a ausência dessa linha, nãoCOMPRESSION=NONE.
Uma linha que parece uma checagem e não é: OVR_RESAMPLING_ALG, que é copiada do arquivo que você converteu. Medimos duas saídas construídas com resampling diferente que imprimem a mesma tag e têm checksums de overview diferentes.
A terceira opção, em Python, é o rio cogeo validate do plugin rio-cogeo para o rasterio. Não rodamos ele — não está instalado aqui, então essa frase se apoia na documentação dele, não numa transcrição nossa.
Como criar um COG com o gdal_translate
O GDAL já vem com um driver para isso, então a conversão é um único comando: gdal_translate -of COG input.tif output.tif. Isso transformou o arquivo em faixas de 361,747,558 bytes citado acima num COG de 2,232,769 bytes em cerca de três segundos, com Block=512x512, COMPRESSION=LZW e cinco níveis de overview até 343 pixels quadrados.
Dois detalhes aí importam. O driver COG comprime por padrão — COMPRESS usa LZW como padrão, e é por isso que essa rodada reporta COMPRESSION=LZW sem ser pedido, então a alegação comum de que -of COG deixa o arquivo sem compressão é falsa num GDAL moderno. E ele construiu cinco níveis de overview onde a fonte tinha quatro, reduzindo pela metade até o menor caber num bloco: a profundidade da pirâmide segue o tamanho da sua imagem, não a quantidade de níveis que o arquivo de entrada trazia.
As opções de criação que importam
Cada uma é uma flag -co NAME=VALUE nesse comando, e cada número vem de uma rodada sobre a mesma entrada.
- COMPRESS —
-co COMPRESS=DEFLATEpara sem perdas,-co COMPRESS=JPEGpara imagens de 8 bits com perdas,-co COMPRESS=WEBPpara o menor resultado com perdas. O GDAL reescreve um pedido de JPEG sobre dados RGB comoCOMPRESSION=YCbCr JPEG; isso é esperado, e é de onde vem a maior parte da economia do JPEG. - BLOCKSIZE — a aresta do tile, 512 por padrão.
-co BLOCKSIZE=1024deixou a saída menor, 1,830,891 bytes contra 2,232,769, porque tiles menos numerosos e maiores significam menos burocracia interna. A troca é granularidade: um cliente que quer um pixel busca um quadrado de 1024 pixels. - OVERVIEW_RESAMPLING — como a pirâmide é subamostrada, como em
-co OVERVIEW_RESAMPLING=NEAREST. Use nearest para rasters categóricos como uso do solo, onde fazer a média de dois códigos de classe inventa um terceiro; a média serve para dados contínuos. - OVERVIEWS —
-co OVERVIEWS=NONEsuprime a pirâmide, e está aqui como um aviso, não como uma recomendação. - BIGTIFF —
-co BIGTIFF=YESmuda para offsets de 64 bits, necessário quando um arquivo se aproxima do teto de 4 GiB do TIFF clássico. É invisível nogdalinfoe visível nos quatro primeiros bytes do arquivo,II*para o clássico contraII+para o BigTIFF. Forçar essa opção custou 3,364 bytes a mais aqui.
OVERVIEWS=NONE é a armadilha mais afiada do driver: o GDAL continua escrevendo LAYOUT=COG, porque produziu um arquivo com o layout de COG que por acaso tem um único nível de resolução, e o verificador então o reprova nos overviews. A tag de layout não é o veredito. Verifique a contagem de overviews em vez disso.
Compressão, medida numa única janela
Essas seis rodadas partem de uma única janela de 2048 pixels de lado, três bandas, de imagem de deserto sem nuvens. Não são uma tabela universal — uma cena majoritariamente vazia comprime muito melhor, e é por isso que a janela é 100 % pixels válidos.
- Sem compressão — 16,517,434 bytes, a base.
- LZW, o padrão do driver — 15,929,384 bytes, apenas 4 % a menos. O LZW se paga em rasters planos ou sintéticos, não em fotografia.
- DEFLATE — 13,094,841 bytes, 21 % a menos, e sem perdas: os checksums batem com o original nas três bandas.
- JPEG — 1,047,694 bytes na qualidade padrão de 75, um corte de 94 %, e com perdas: os checksums são diferentes em cada banda. Na qualidade 90 são 1,815,578 bytes, um corte de 89 % com dano visivelmente menor.
- WEBP — 828,166 bytes, o menor dos seis, e com perdas por padrão.
A escolha é sobre para que serve o raster: sem perdas para tudo que você vai medir, com perdas para imagem de fundo que um humano só vai olhar.
Por que isso importa: a requisição por intervalo (range request)
Tudo isso existe por causa de um único recurso do HTTP. Um servidor que responde Accept-Ranges: bytes deixa um cliente pedir um intervalo de bytes e receber 206 Partial Content em vez do arquivo inteiro, e um COG é a organização que faz esses pedidos aterrissarem em algo útil. Medimos isso contra um COG do Sentinel-2 de 313,765,265 bytes lido via /vsicurl/, sem cópia local.
- Ler o cabeçalho inteiro e a lista de overviews — tamanho, CRS, layout de blocos, todos os níveis de pirâmide — custou 2 requisições GET e 16,716 bytes, ou 0.005 % do arquivo.
- Extrair uma janela de 2048 pixels de lado do meio da imagem custou 7 requisições GET e 22,672,068 bytes, ou 7.2 % do arquivo.
Contra um GeoTIFF em faixas e sem compressão, os dois custam o arquivo inteiro.
Um alerta, sobre navegadores. O nosso visualizador de GeoTIFF aceita uma URL, e a caixa de URL baixa o arquivo inteiro antes de renderizar qualquer coisa. Confirmamos isso num navegador de verdade: a primeira requisição é um GET comum, sem cabeçalho Range, que retorna 200 e puxa 100 % do arquivo, e só depois o renderizador faz leituras 206 de verdade — que não custam bytes extras, porque o corpo já está em cache. Então cole uma URL quando o arquivo for pequeno e baixe quando não for. Soltar o arquivo é o único modo que o verificador tem, de qualquer forma.
Arquivos de teste que você pode usar
Toda URL aqui foi requisitada em 11 de setembro de 2026 com um user agent de navegador, registrando status, Accept-Ranges, o cabeçalho de CORS e o tamanho total. Uma lista assim envelhece, então leia como um retrato de um dia e uma rede específicos.
Um hábito primeiro: confira o content type antes de chamar uma URL de raster. Um 206 só prova que o servidor suporta intervalos de bytes, e muita página HTML também responde 206 — seis responderam assim na nossa campanha paralela de fontes de elevação. Os rasters abaixo respondem todos content-type: image/tiff.
- Sentinel-2 na AWS, encontrado por uma busca e não por uma chave chutada. O bucket
sentinel-cogsguarda toda cena Sentinel-2 Level-2A como COG, aberto e com CORS aberto:206,accept-ranges: bytes,access-control-allow-origin: *. Não copie um caminho de cena de um tutorial — ids de cena carregam uma data, e uma chave vizinha chutada retorna404 NoSuchKey, que parece um bucket morto e na verdade é uma chave errada. Consulte a API STAC em vez disso: envie um bounding box e um intervalo de datas para o endpoint do earth-search e use os hrefs de asset que ele retorna. O documento de coleção responde200e não defineaccept-ranges, por ser um catálogo e não um arquivo. Licença: os dados do Copernicus Sentinel são livres e abertos sob os termos do Copernicus, com atribuição. - Uma cena pequena que dá para colar direto no visualizador. tem 1,412,993 bytes. Num navegador de verdade transferiu 1,413,682 bytes em 2 requisições:
✓ COG válido,4 tiles · EPSG:32723, 6.3 segundos. - Uma maior, também verificada num navegador. tem 5,810,809 bytes, e transferiu 5,811,498 bytes em 5 requisições:
✓ COG válido,84 tiles · EPSG:32723, 16 segundos. - O tamanho de um asset é uma propriedade da cena, não do nome da banda. Mesma coleção, mesmo dia: o
TCI.tiftinha 1,412,993 bytes na costa de São Paulo e 313,765,265 bytes no Atacama, uma diferença de 222 vezes, porque a primeira cena é 90 % nodata mascarado por nuvem. Leia o tamanho no resultado da busca antes de colar uma URL; acima de uns 64 MiB, baixe em vez disso. - A elevação USGS 3DEP, aberta e grande demais para colar. responde
206comaccept-ranges: byteseaccess-control-allow-origin: *, e tem 222,936,410 bytes. Um COG de verdade, mas a caixa de URL puxaria os 212.6 MiB inteiros primeiro. Baixe e solte o arquivo. Licença: domínio público dos EUA. - O Copernicus GLO-30, que funciona em todo lugar exceto num app de navegador. responde
206comaccept-ranges: bytese tem 44,155,932 bytes, mas não envia nenhum cabeçalhoaccess-control-allow-origin. Um cliente HTTP comum lê tranquilo; uma página de navegador não consegue. Colamos no visualizador para ter certeza, e o navegador recusou no preflight de CORS, com zero bytes trafegados. Licença: os termos do Copernicus DEM no readme do bucket, que exigem atribuição. - O OpenTopography, o host mais amigável que medimos. é um tile SRTM de um grau, com 15,340,529 bytes:
206, cross-origin permitido, e o único host desta leva que também expõeContent-Rangepara scripts da página. Não o carregamos no visualizador ainda, então baixe e solte o arquivo por enquanto. Licença: por dataset, no OpenTopography. - Um que está morto, para você parar de procurar. O índice de eventos do Maxar Open Data em
maxar-opendata.s3.amazonaws.com/events/index.htmlainda é bastante linkado por aí e hoje retorna404 NoSuchKey, assim como vários diretórios de download da NASA LP DAAC em tutoriais mais antigos. Quando um caminho S3 dá 404, confira se o bucket responde antes de concluir que os dados sumiram.
As fontes de elevação recebem um tratamento mais longo, com resolução, datum vertical e cobertura, no nosso guia de fontes de elevação (DEM) gratuitas.
Os erros decodificados
Quando uma ferramenta recusa o seu raster ou renderiza dolorosamente devagar, é quase sempre um destes casos.
- Em faixas, não dividido em tiles.
Block=<width>x1nogdalinfo; o arquivo precisa ser lido quase do início ao fim para entregar qualquer janela. Corrija comgdal_translate -of COG. - Em faixas e grande, que é quando um visualizador para e pergunta. O nosso visualizador separa rasters em quatro níveis, e só o de faixas-e-grande interrompe: acima de 100 megapixels, uns 10,000 pixels de lado, um arquivo em faixas recebe o título
Este TIFF não é cloud-optimized, um botão Carregar mesmo assim e uma sugestão de conversão para COG. Um arquivo em faixas de 4 megapixels renderiza sem aviso, e o mesmo vale para um arquivo de 120 megapixels que está dividido em tiles mas não tem pirâmide, rotuladotiled, sem overviews— o limite só é consultado no ramo das faixas. - Um sidecar externo .ovr não conta. Uma pirâmide construída ao lado do arquivo, em vez de dentro dele, cai num segundo objeto,
file.tif.ovr. Tudo bem num disco local, inútil via HTTP: um cliente que buscoufile.tiftem um objeto só, e os overviews estão em outro que ele não tem motivo para pedir. Um verificador no navegador não consegue ver um sidecar que você não soltou. - JPEG onde deveria ser DEFLATE. JPEG dentro de TIFF é dramaticamente menor — 1,047,694 bytes contra 13,094,841 na nossa janela — e muda os valores dos seus pixels. Em elevação, refletância ou qualquer coisa de que depende um limite de classe, isso é corrupção de dados com um arquivo menor.
- O muro dos 4 GiB. O TIFF clássico usa offsets de 32 bits, então um arquivo não pode passar de 4 GiB. Depois disso você precisa do BigTIFF, com offsets de 64 bits e um número mágico diferente,
II+em vez deII*. Nada nogdalinfoavisa isso, então se um arquivo grande não abrir num software mais antigo, confira os bytes mágicos antes de culpar os dados.
Servindo COGs sem rodar o GDAL você mesmo
Converter um arquivo é um comando; converter todo raster que um time de campo envia, manter as pirâmides atualizadas e servir os tiles é um pipeline, e essa é a parte que o Geodocs faz. As duas ferramentas acima são gratuitas e não pedem conta: verifique um arquivo, ou abra um num mapa. Para a convenção em si, veja o site da especificação e a página do driver COG do GDAL.