Como criar mapas de evolução temporal no QGIS usando Google Earth Engine?

Confira nosso curso online de QGIS

Como mostrar mudanças do uso do solo em mapas? Aprenda a usar o GEE dentro do QGIS e monte seus mapas de evolução temporal.

Imagens de sensoriamento remoto podem ser utilizadas em diferentes estudos ambientais. É possível utilizar elas para analisar presença de algas e sedimentos em cursos d’água, delimitar o uso do solo e avaliar inundações.

As possibilidades de uso são inúmeras.

Aliado à isso, temos alguns satélites que estão funcionando ou funcionaram por um bom período de tempo, tornando possível a realização de séries históricas de imagens.

Confira nosso curso de Geoprocessamento para Estudos Ambientais usando QGIS.

Neste tutorial, vamos aprender a utilizar o Google Earth Engine (GEE) dentro QGIS para avaliar a evolução temporal do município de Siderópolis e região de 1990 até os dias de hoje, por meio das imagens Landsat 5 e 8.

Como instalar o GEE no QGIS?

Para utilizar o GEE no QGIS, é necessário instalar o Google Earth Engine Plugin, mas não basta somente ir em Complementos e marcar o plugin, alguns passos antes disso são necessários.

É necessário ter o Python instalado no seu computador e estar registrado no Google Earth Engine.

O procedimento com maiores detalhes pode ser encontrado no site do Jorge Santos (Instrutor GIS – QGIS 3.14: Instalação dos Plugins Google Earth Engine e Sentinel-2), sugerimos que você utilize ele para instalar o GEE plugin.

Máscara de Nuvens do Landsat

Agora que já temos o GEE plugin instalado, vamos começar a escrever nosso código em python. Você pode escrever diretamente no editor de scripts do QGIS ou trabalhar no bloco de notas e depois jogar para dentro do QGIS.

Antes de mais nada, vamos importar as bibliotecas do GEE e do plugin e caso você não tenha autenticado ou inicializado o GEE, descomente as linhas comentadas abaixo.

import ee
from ee_plugin import Map

# ee.Authenticate()
# ee.Initialize()

Agora, iremos criar uma função para remover as nuvens das imagens Landsat.

A remoção das nuvens é realizada usando a banda ‘pixel_qa’, a qual apresenta valores em bits classificados conforme o que foi capturado pelo sensor. Por exemplo, o bit 3 e 5 representam a presença de sombra das nuvens e nuvens no Landsat 8.

Lembre-se que tais valores se diferenciam para cada sensor.

def maskL8SR(imagem):
    '''Filtro para remover nuvens e sombras
    das imagens LANDSAT 8 com buffer de 100m'''
    
    cloudShadowBitmask = int(2**3)
    cloudBitmask = int(2**5)
    qa = imagem.select('pixel_qa')
    mask = qa.bitwiseAnd(cloudShadowBitmask).eq(0).And(\
           qa.bitwiseAnd(cloudBitmask).eq(0))\
        .focal_min(radius = 100, units = 'meters')
    
    return imagem.updateMask(mask)

def maskL5SR(imagem):
    '''Filtro para remover nuvens e sombras
    das imagens LANDSAT 5 com buffer de 100m'''
    
    qa = imagem.select('pixel_qa')
    cloud = qa.bitwiseAnd(int(2**5)).And(qa.bitwiseAnd(int(2**7)))\
        .Or(qa.bitwiseAnd(2**3)).focal_max(radius = 100, units = 'meters')
        
    mask2 = imagem.mask().reduce(ee.Reducer.min())
    
    return imagem.updateMask(cloud.Not()).updateMask(mask2)

Em python, a definição de funções é iniciada com ‘def’, seguida do nome da função e a inserção dos argumentos de entrada entre parênteses, finalizando com dois pontos. Tudo que for para ser executado pela função deverá estar com um espaçamento (i.e. identação).

Como vamos utilizar essas funções numa coleção de imagens do GEE por meio da função map (que aplica a função desejada em todas as imagens da coleção), devemos manter apenas a própria imagem como entrada.

Além disso, note que usamos o método .select() para selecionar a banda ‘pixel_qa’ e pedimos para que os pixels que contém os bits de nuvens e sombras sejam diferenciados.

Note também que a função do Landsat 8 marca os pixels bons (i.e. sem nuvens), deixando seus pixels com valor igual à 1, enquanto as nuvens são 0, sendo possível aplicar o buffer por meio do focal_min (janela que passa na imagem selecionando os pixels de menor valor).

Na função do Landsat 5 é diferente, ela marca os pixels ruins (i.e. com nuvens), fazendo com eles sejam identificados com o valor igual à 1, enquanto onde não há nuvem, o pixel fica 0. Dessa forma, aplicamos o focal_max para expandir a máscara por meio de um buffer. Inclusive, é utilizado a função Not() para inverter esses valores depois.

Por fim, é chamada a função updateMask() para tirar os pixels marcados com 0.

Definindo Parâmetros de Entrada

Agora vamos definir parâmetros como o polígono que abrange nossa área de estudo e a coleção de imagens para os anos em estudo (neste caso, 1990 e 2020).

Embora no QGIS o polígono não seja usado, é interessante mantermos o código caso você utilize ele fora do QGIS.

coordenadas = [[-49.45, -28.58], [-49.40, -28.58], [-49.40, -28.60], [-49.45, -28.60], [-49.45, -28.58]]
ee_pol = ee.Geometry.Polygon(coordenadas)

img_1990 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')\
	.filterDate('1989-01-01', '1991-12-31')\
	.filterBounds(ee_pol)\
	.map(maskL5SR)\
	.mean()
	
visParams5 = {'bands': ['B3', 'B2', 'B1'], 'min': 0, 'max': 3000, 'gamma': 1.4}

Map.addLayer(img_1990, visParams5, 'IMG_1990')

img_2020 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')\
	.filterDate('2020-01-01', '2020-12-31')\
	.filterBounds(ee_pol)\
	.map(maskL8SR)\
	.median()
	
visParams8 = {'bands': ['B4', 'B3', 'B2'], 'min': 0, 'max': 3000, 'gamma': 1.4}

Map.addLayer(img_2020, visParams8, 'IMG_2020')

Nas primeiras linhas do código, definimos as coordenadas dos vértices do nosso polígono que será usado para filtrar as imagens disponíveis nos anos de 1990 e 2020.

Note que para o ano de 1990, aumentamos a janela para fazer a imagem, isso porque se usarmos somente 1990, para esta localidade, a imagem fica ‘embaçada’, ainda com a presença de pixels contaminados por nuvens.

Em seguida, salvar as imagens por meio da função ImageCollection(), aplicar os filtros de data e de localização. Depois passamos a função para retirar as nuvens e aplicamos a função mediana para que todas as imagens sejam unidas, prevalecendo os valores medianos delas.

Adicionando imagens do GEE no QGIS

Para abrirmos as imagens no QGIS, precisamos usar a função Map.addLayer().

O primeiro argumento desta função é a imagem propriamente dita, seguida do dicionário indicando quais bandas devem ser usadas e os valores máximos e mínimos. Por fim, temos o nome da camada.

Agora que você já tem as imagens, basta construir um layout e gerar seu mapa. A figura abaixo apresenta o resultado da nossa postagem.

Análise histórica da região de Siderópolis em Santa Catarina
Análise histórica da região de Siderópolis em Santa Catarina.

É interessante verificar nessa imagem a evolução da área urbana ao sul, assim como a recuperação de áreas degradadas pela mineração de carvão.

Você pode conferir o código completo no GitHub.

Agora você pode replicar o código para adicionar outros anos ao seu mapa. Você também pode aplicar índices espectrais como NDVI para analisar o desenvolvimento da vegetação e ou ainda modificar os valores mínimos e máximos para melhorar o contraste das imagens.

Confira nosso curso de Geoprocessamento para Estudos Ambientais usando QGIS.

E chegamos ao fim da nossa postagem, caso tenha ficado com alguma dúvida, utilize os comentários que responderemos assim que possível.



Clique na figura abaixo e assine nossa lista de emails para receber nosso ebook "Como criar mapas de localização com ArcGIS 10.x".

Apostila Mapa de Localização Banner

Author: Fernando BS

Engenheiro Ambiental e de Segurança do Trabalho. Atua nas áreas de geoprocessamento, mineração e hidrologia. Busca soluções utilizando softwares como QGIS, R e Python.

2 thoughts on “Como criar mapas de evolução temporal no QGIS usando Google Earth Engine?”

  1. Boa tarde Fernando, tudo bem?

    Muito bom seu tutorial, porém quando vou exportar meu layout de impressão para imagem, a imagem aérea não aprece. Ou seja fica fundo branco e aprece só as grades, rótulos, escalas… Sabes me dizer o que está acontecendo?

    1. Boa tarde Eduardo, já vi isso acontecer com outras imagens obtidas por WMS quando você dá um zoom muito grande (escala grande) ou verifique se o DPI da imagem não esta muito elevado também. Você pode dar uma conferida nisso. Tente obter as informações da imagem por meio do .getInfo() para ver se ela não esta vazio ou se o GEE retorna algum erro.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *