Olá, daqui é o Alex da DEV STORIES DOT EU. Rasterio:
Numpy para Dados Geoespaciais, episódio 5 de 5. Às vezes tens imagens de satélite belíssimas e de alta resolução, mas o teu modelo climático só aceita inputs mais grosseiros e de baixa resolução. Não podes simplesmente fazer slice do array, porque os pixels resultantes ainda precisam de representar exatamente a mesma área física, apenas numa grid de menor densidade. Para fazeres isso corretamente, precisas de Resampling e Writing.
Isto não é sobre reprojection. O coordinate reference system permanece exatamente o mesmo. Estamos apenas a alterar a resolução. Digamos que precisas de fazer downsample de um raster para metade. No Rasterio, fazes o resampling no exato momento em que lês os dados para a memória. Quando chamas o método read no teu dataset, passas um parâmetro chamado out shape. Em vez de ler o array completo, o Rasterio lê-o e faz logo o scale para se ajustar ao shape que pediste. Para um raster de uma só band, o teu out shape seria um tuple a especificar uma band, depois metade da height original, e metade da width original.
Também precisas de dizer ao Rasterio como calcular os valores destes novos pixels maiores. Fazes isso passando um parâmetro de resampling. O Rasterio fornece um enum Resampling para isto. Se estiveres a lidar com dados contínuos, como temperatura, podes passar Resampling dot bilinear, que calcula uma média ponderada dos pixels vizinhos. Se estiveres a lidar com dados categóricos, como land cover, usarias Resampling dot nearest para preservar os valores exatos das classes originais.
Aqui está o ponto chave. Agora tens um novo array Numpy mais pequeno, mas que ainda representa exatamente a mesma área geográfica na Terra. Como o array tem menos pixels, cada pixel individual cobre mais espaço físico. Isto significa que o teu Affine transform original está agora completamente errado. Se escreveres o novo array para o disco usando o transform antigo, a tua imagem vai encolher no mapa para cobrir apenas um quarto da sua área original.
Tens de fazer scale do transform. Fazes isto pegando no transform original do dataset e multiplicando-o por uma scaling matrix Affine. Encontras os scaling ratios dividindo a width original pela tua nova width, e a height original pela tua nova height. Como reduzimos as dimensões para metade, ambos estes ratios são exatamente dois. Quando multiplicas o transform original por estes scaling factors, obténs um novo transform onde as dimensões dos pixels são duplicadas, mas o ponto de origem no canto superior esquerdo permanece perfeitamente ancorado.
Agora tens o teu array com resampling e o teu transform com scale. O passo final é escrever um GeoTIFF válido para o disco. Para fazeres isto, precisas de metadata. A abordagem mais segura é copiar a propriedade profile do teu dataset de origem. Isto dá-te um dictionary que contém o file driver, o coordinate reference system, o data type, e o valor nodata. Depois, atualizas este dictionary de profile com a tua nova height, a tua nova width, e o teu transform recém-calculado.
Com o profile atualizado pronto, chamas rasterio dot open. Forneces o novo filename, defines o mode para write, e fazes unpack do teu dictionary de profile como keyword arguments. Isto cria um dataset vazio no disco, formatado de acordo com as tuas especificações exatas. Finalmente, chamas o método write neste novo objeto dataset e passas o teu array Numpy com downsample. O array é escrito para o ficheiro, e o teu novo GeoTIFF de menor resolução está pronto para o modelo climático.
Lembra-te, modificar dados raster é sempre um contrato de duas partes: se alterares o shape do array Numpy, tens de alterar explicitamente o Affine transform para corresponder, ou o teu spatial footprint fica estragado. Isto leva-nos ao fim da nossa série. Encorajo-te a ler a documentação oficial do Rasterio para explorares outros algoritmos de resampling e tentares construir estas pipelines hands-on. Se quiseres sugerir tópicos para uma futura série, visita devstories dot eu. Gostaria de tirar um momento para te agradecer por ouvires — isso ajuda-nos muito. Tem um ótimo dia!