Como abrir (muitos) layers raster no QGIS 3.18 de uma vez, por processamento em lotes, e como alterar suas simbologias em grupo

Tutorial simples com códigos e snippets em Python

Colegas pesquisadores e entusiastas de SIG de código livre,

Olá e bem-vindos ao meu blog!

Gostaria de começar com um aviso - posso ser uma pesquisadora desta área, mas isso não significa que tudo o que faço ou escrevo aqui funcionará para você, em suas próprias configurações de desktop e versões de packages. Me eximo de responsabilidade se você perder dados ou bagunçar sua instalação. Eu também não autorizo nenhum tipo de cópia do meu conteúdo (exceto para os trechos de código fornecidos, para eles, a licença do tipo MIT se aplica).

Hoje, vou escrever sobre abrir muitas camadas (layers) raster por meio de processamento em lotes (batch processing), e alteração de suas simbologias, também em lotes, no QGIS. Este tutorial foi elaborado com base no QGIS 3.18 Zürich e utiliza seu console Python para a parte de carregamento dos layers.

Abrir muitas camadas raster pode ser uma tarefa tediosa. Talvez você tenha uma profusão de grânulos de satélites que devem ser verificados antes de fazer Merge, talvez você esteja trabalhando com uma área tão grande que precise ter partes do seu projeto em diferentes fusos UTM, ou ainda, talvez você tenha 80 bandas raster do mesmo local salvas separadamente, mas precisa usar todas de uma vez. Para mim, abrir mais de cerca de 20 arquivos, um por um, já é tedioso.

Na verdade, abrir os meus arquivos um por um era tão tedioso que decidi programar um pequeno script para abri-los todos juntos. E você também pode!

Neste post, estou fornecendo meu código para você para que você possa alterá-lo para atender às suas necessidades (fornecido sob licença de uso e de cópia do tipo MIT).

Vamos lá!

Abra o QGIS e no menu, em Plugins, abra o console do Python.

Open Python Console

Clique em “Show Editor”

Click in Show editor

Abra o script Python

Clique em “Abrir Script” e abra o script que estou fornecendo, ou copie e cole o código abaixo em um arquivo de texto, dando um nome do tipo “qualquer_nome.py”

Click in Open Script

O gist Python no GitHub:

Primeiro, coloque a pasta padrão na variável “caminho_base” (base_path). Esta é a parte do caminho dos arquivos que se mantém e não muda de arquivo para arquivo.

“MAX_ARQ” é o número de arquivos que você deseja abrir neste processamento em lote. Se você não tem esse número, em geral, não tem problema, mas vai precisar de uma forma mais elaborada para usar o código. Falei um pouco disso na seção de extras.

Eu faço o meu loop for começando em 1 e terminando no número de arquivos mais um, porque o loop do Python clássico começa em zero. A seguir, eu transformo meus dígitos (números inteiros) em strings. Isso vai ser útil se o nome dos arquivos contiver o do número do raster que você deseja abrir. Exemplo: raster_1.tif, raster_2.tif…

num_1dig é uma string com, no mínimo, um dígito (1, 2,… 10,11,… 99,100,101,…)

num_2dig é uma string com, no mínimo, dois dígitos (01, 02,… 10,11,… 99,100,101,…)

num_3dig é uma string com, no mínimo, três dígitos (001, 002,… 010,011,… 099,100,101,…)

Altere o código para atender às suas necessidades

Em “caminho_arquivo” deve ser colocada a lógica que compõe o nome dos arquivos que se deseja abrir. Alguns casos comuns + fragmentos (snippets) de código abaixo:

Caso 1. Cada arquivo está em uma pasta diferente, e as pastas são nomeadas “folder_01”, “folder_02”, etc. Todos os arquivos têm o mesmo nome “raster.tif”.

caminho_arquivo = caminho_base + ‘folder_’ + num_2dig + ‘/’ + ‘raster.tif’

Caso 2. Cada arquivo está em uma pasta diferente, e as pastas são nomeadas “folder_01”, “folder_02”, etc. Os arquivos são nomeados “raster_001.tif”, “raster_002.tif”, e estão um em cada pasta.

caminho_arquivo = caminho_base + ‘folder_’ + num_2dig + ‘/’ + ‘raster_’ + num_3dig + ‘.tif’

Caso 3. Cada pasta possui dois arquivos. As pastas são nomeadas “folder_01”, “folder_02”, etc. Os arquivos são nomeados “raster_01.tif” e “raster_02.tif” em folder_01,… “raster_51.tif” e “raster_52.tif” em folder_25.

import math # add on the beginning of the .py file
num_div2=math.floor(i/2)
num_div2_str_2dig=str(num_div2).zfill(2)
caminho_arquivo = caminho_base + ‘folder_’ + num_div2_str_2dig + ‘/’ + ‘raster_’ + num_2dig + ‘.tif’

Caso 4. Cada pasta possui dois arquivos. As pastas são nomeadas “folder_01”, “folder_02”, etc. Os arquivos são nomeados “raster_01.tif” e “raster_02.tif” em folder_01,… “raster_01.tif” e “raster_02.tif” em folder_25. Eles têm sempre os nomes de “raster_01.tif” e “raster_02.tif”.

Substitua MAX_ARQ pela metade do número total de arquivos. Ou seja, coloque o número total de pastas.

Copie tudo de “caminho_arquivo” para baixo e faça uma versão para “raster_01.tif” e outra para “raster_02.tif”, ambas podem ser baseadas no trecho mostrado para o Caso 1.

Caso 5. Os rasters estão todos na mesma pasta, é o nome do arquivo que muda.

caminho_arquivo = caminho_base + ‘folder/’ + ‘raster_’ + num_2dig+ ‘.tif’

Caso 6. Os arquivos raster estão em pastas diferentes e os nomes das pastas são dados por datas, e não por números.

Bem, este é um dos casos mais difíceis. Primeiro, obtenha as datas de início e fim. Se você não tiver a data final, você pode usar este snippet que criei para obter sua data final:

from datetime import date #add to the beginning
from datetime import datetime #add to the beginning
startyear=1970
startmonth=1
startday=1
date_start=date.toordinal(date(startyear,startmonth,startday))
date_end=date_start+MAX_ARQ
end_datetime=date.fromordinal(date_end)
endyear = end_datetime.strftime("%Y")
endmonth = end_datetime.strftime("%m")
endday = end_datetime.strftime("%d")

No entanto, você não precisará apenas das datas de início e de término, você precisará de todas as outras também. Nesse caso, date_end é substituído por loop_date, a data dentro do loop for.

from datetime import date #add to the beginning
from datetime import datetime #add to the beginning
startyear=1970 # before the loop
startmonth=1 # before the loop
startday=1 # before the loop
date_start=date.toordinal(date(startyear,startmonth,startday)) # before the loop
date_loop=date_start+i
loop_datetime=date.fromordinal(date_loop)
year = loop_datetime.strftime("%Y")
month = loop_datetime.strftime("%m")
day = loop_datetime.strftime("%d")

Agora, crie o nome da sua pasta.

caminho_arquivo = caminho_base + year+ ’-’ + month + ‘-’ + day + ’/’ + ‘raster.tif’

ou…

caminho_arquivo = caminho_base + year+ ’_’ + month + ‘_’ + day + ’/’ + ‘raster.tif’

Outras formulações também são possíveis.

Eu codifiquei também uma versão do código específica para este caso, que você pode usar como base para a sua:

Outra coisa que você pode alterar é o nome da camada no QGIS. Você pode escolher o nome que quiser, mas eu sugiro incluir a iteração do loop para que você saiba qual camada é qual.

nome_layer= 'camada_' + num_1dig

Depois de alterar o código para atender às suas necessidades, execute o script para iniciar o processo de carregamento dos arquivos em processamento por lotes

Run Script

Depois de executar o script, os layers devem aparecer carregados

QGIS layers loaded

Certo!

Simbologia em lote

Agora, como posso aplicar o mesmo estilo a todos eles sem ter que mudar cada um separadamente? (novamente, isso seria muito tedioso!)

É bem simples, na verdade. E não envolve nada de Python!

Abra as Propriedades de uma de suas camadas e vá para a guia Symbology (Simbologia)

QGIS layer properties

QGIS layer properties camada 8

Ajuste a simbologia da camada como quiser.

QGIS symbology adjusted

Clique em Apply e em OK

Crie um novo grupo em Add Group

QGIS add group

QGIS add group

Selecione todos os seus layers ao mesmo tempo, clicando no primeiro, segurando Shift e clicando no último. A seguir, arraste-as para o grupo de camadas que você acabou de criar, para que se tornem parte dele.

QGIS drag layers group

QGIS drag layers group

Copie o estilo da camada que você alterou

Clique com o botão direito na camada que você ajustou a simbologia e escolha Styles, Copy Style (copiar o estilo).

QGIS copy style

Você pode colar o estilo que foi copiado em um editor de texto (você não precisa e nem deve fazer isso, este é só um comentário). Se você fizer isso, e se já viu um arquivo XML, o estilo é algo parecido com isso.

Cole o estilo no grupo onde estão as camadas

Agora, cole o estilo no grupo. Para isso, clique com o botão direito do mouse no grupo e clique em “Paste Style” (colar estilo).

QGIS paste style

Todas as camadas devem estar com a representação escolhida, agora.

Acho que é isso!

Extras:

  • Tenho tantos arquivos que nem sei quantos são. Não sei os números, e tenho apenas uma lista com os nomes deles.

Uma lista com os nomes é o suficiente para conseguir abri-los. Você só precisa copiar esta lista para o código em Python e declará-la como um list. Em seguida, faça o loop for sobre a sua lista. Exemplo abaixo:

file_list = ['rasterXYN.tif', 'anotherraster.tif', 'thirdraster.tif', 'OKraster.tif', 'Nice_raster.tif']
for item in file_list:
	…
  • Por que você simplesmente não faz um mosaico de todos os arquivos juntos? Daí você não terá mais que abrir todos esses arquivos.

Há uma infinidade de razões pelas quais alguém pode não querer fazer um mosaico de seus rasters. Os principais motivos incluem: eles estão em diferentes sistemas de coordenadas projetadas, como por exemplo, em diferentes fusos UTM, ou, eles gerariam um arquivo muito grande após o mosaico, ou mesmo, todos os rasters se referem ao mesmo local no espaço, mas em bandas espectrais ou períodos de tempo diferentes.

  • Basta adicionar todos os arquivos uma vez e salvar o projeto, e você não terá que se preocupar nunca mais em abrir eles!

Desculpe, mas se você muda constantemente de estação de trabalho ou costuma trabalhar em vários computadores diferentes, isso não funcionará, pois você ainda terá que especificar a localização dos rasters quando abrir o projeto em um computador diferente.

Além disso, em alguns casos, até mesmo abrir todos os arquivos uma única vez pode acarretar um desperdício de tempo. Imagine o caso de você ter mil rasters. Se você for muito rápido(a), consegue carregar cada um deles em uns 20 segundos. Portanto, levariam 5,56 horas para abrir todo o conjunto de dados. Seguindo a lógica, se você tiver cem arquivos, abrir todos eles demoraria cerca de meia hora, o que eu já acho um pouco demais, considerando que ler este post inteiro leva só cerca de 9 minutos!

  • Eu tenho mais de mil rasters, como vou selecionar e arrastar todos para dentro de um grupo de camadas? Não existe uma maneira mais simples de fazer isso?

Sim, você pode, antes de tudo, criar o grupo, selecionar o grupo e, enquanto estiver selecionado, execute o código de abrir os rasters em lote. Quando as camadas carregarem, elas aparecerão dentro do grupo de camadas que estava selecionado.

  • Tenho muitos layers para carregar, mas são vetores! Este procedimento funciona apenas para raster?

Por enquanto, sim, mas ele pode ser adaptado para carregar shapefiles e geopackages (entre outros). Estou pensando em adaptá-lo a dados vetoriais. Quando eu fizer isso, edito esta postagem para adicionar o código.

Luísa Vieira Lucchese
Luísa Vieira Lucchese
Pós-doutoranda

Pós-doutoranda na Universidade de Pittsburgh

Relacionados