Py Qgis 1
Py Qgis 1
Py Qgis 1
e PyQGIS
Os arquivos de dados usados nessa apostila, bem como esta apostila são encontrados
em:
https://amazeone.com.br/pyqgis/
VISITE:
amazeone.com.br
Sumário
1. QGIS .......................................................................................................................................... 4
1.0 Introdução ........................................................................................................................... 4
1.1 Instalando e Iniciando o QGIS ............................................................................................. 4
1.2 Carregando dados Vetoriais ................................................................................................ 5
1.3 Carregando dados Raster .................................................................................................. 15
1.4 Criando Dados Vetoriais .................................................................................................... 20
1.5 Criando Raster a partir de Pontos Vetoriais ...................................................................... 24
2. Fundamentos de Python ........................................................................................................ 28
2.0 A linguagem Python – Introdução ..................................................................................... 28
2.1 Fundamentos da linguagem Python ................................................................................. 29
2.2 Controles de fluxo ............................................................................................................. 35
2.3 Funções ............................................................................................................................. 37
2.4 Módulos ............................................................................................................................ 39
2.5 Pandas ............................................................................................................................... 39
2.6 Gráficos ............................................................................................................................. 42
3.Usando Python no QGIS .......................................................................................................... 44
3.1 Primeiros passos, noções de Classes ................................................................................. 44
3.2 Interagindo com informações de objetos da classe Vector .............................................. 48
3.3 Interagindo com informações de objetos da classe Raster .............................................. 56
3.4 Criando objeto vetorial ..................................................................................................... 62
3.5 Criando objeto raster ........................................................................................................ 68
4.Executando python scripts fora do Qgis ................................................................................. 71
1. QGIS
1.0 Introdução
O QGIS é um programa que foi iniciado em 2002 por Gary Sherman e se tornou em um
projeto incubador da Open-Source Geospatial Foundation em 2007. Sua Versão 1.0 foi
lançada em janeiro de 2009.
As bases para o QGIS foram as bibliotecas QT, GEOS, OGR/GDAL e GRASS. Usado com o
apoio de PostgreSQL-Postgis o QGIS se transforma em uma ferramenta completa para o
geoprocessamento e análise espacial de dados.
A versão que trabalharemos é a 3.16 LTR (Hannover) que é versão estável mais recente.
Versões mais recentes de desenvolvimento já lançadas são a 3.22 (Białowieża ) . O QGIS
pode ser instalado em qualquer sistema operacional (Linux, Unix, OSX, Windows,
Android) e já possui o python dentro dele. O python script é a ferramenta principal de
interação para tarefas mais complexas ou repetitivas e é usado também para o
desenvolvimento dos plugins.
Veremos nessa apostila a integração da linguagem Python com o QGIS com o objetivo
de automatização de processos e análises espaciais de dados bem como a integração
com banco de dados geoespaciais.
O QGIS pode ser instalado em diversos sistemas operacionais. O link abaixo fornece
detalhadamente as informações necessárias para a instalação em todos os sistemas
operacionais. https://www.qgis.org/pt_BR/site/forusers/alldownloads.html
Ao iniciar o QGIS veremos a seguinte imagem.
Elementos do Programa:
1 - Painel Principal do Mapa – Aqui é onde o mapa é mostrado na medida que as
camadas são carregadas. Você pode interagir com as camadas carregadas tipo: dar
zoom, mover o mapa, selecionar elementos e várias outras operações que veremos
adiante.
2 - Lista de Camadas Carregadas – À medida que as camadas são carregadas uma lista
delas será criada nesse painel. Aqui podemos ativar/desativar a visualização, ordenar, e
modificar a aparência das camadas.
3 - Navegador – No navegador podemos acessar diversos formatos de dados
compatíveis localizados no seu computador, em provedores de dados, em banco de
dados, etc.
4 - Barra de Ferramentas e Menus – Aqui, como em todos os programas, estão os
controles do aplicativo divididos nas categorias correspondentes.
5 - Pesquisa – Podemos nesse campo acessar/pesquisar rapidamente as ferramentas,
controles e processos do QGIS entrando com o nome a ser pesquisado.
6 - Barra de Status – Informações gerais sobre projeção, coordenadas do mapa na
posição do cursor, escala, rotação etc. podem ser vistos de forma rápida aqui.
QGIS pode abrir dados vetoriais de diversos formatos graças à interação com a biblioteca
GDAL.
Posicione a camada recém adicionada abaixo da camada cidade para ficar como a
imagem da direita. Faça isso clicando e arrastando na camada amazonas.
Abaixo vemos o resultado.
Podemos gravar o nosso projeto com o nome de primeiro. Vá até o menu Projeto >
Salvar. Na janela que aparece escreva o nome ‘primeiro’. Pronto, o projeto está salvo.
O QGIS é uma ferramenta bastante versátil e pode abrir também dados localizados em
fontes remotas do tipo banco de dados PostgreSQL-Postgis, Oracle, mySQL, DB2, etc.
Também dados de ArcGisMapServer, WFS, XYZ Tiles, etc.
A janela abaixo vai aparecer. Entre com droid como usuário e devcor como senha, Clique
OK.
Clique na seta para baixo em public e selecione, clicando duas vezes no objeto ucus para
carregar ele:
Vimos aqui como carregar objetos de dados espaciais de diversos formatos de maneira
bem simples para dentro do QGIS. Salve novamente o projeto. Ao abrir novamente o
projeto as credenciais do banco de dados devem ser inseridas novamente (usuário droid
e senha devcor) para carregar o dado remoto.
Os tipos de objetos usados no QGIS são pontos, linhas, polígonos, multipontos,
multilinhas, multipolígonos e coleções de dados (tipo misto).
Vamos agora ver como visualizar os atributos dos dados carregados e como modificar a
aparência de cada um dos objetos carregados.
Seleciona tudo
Inverte a seleção
Dados do tipo raster podem apresentar valores de uma única grandeza no seu grid ou
várias grandezas (separadas bandas). Um exemplo de bandas de valores são os dados
multiespectrais de sensoriamento remoto. Um exemplo de dados de simples grandeza
são os modelos digitais de elevação.
Dados pontuais do tipo vetorial podem ser convertidos em dados do tipo raster usando
interpolações matemáticas ou estatísticas que calcula ou estima a distribuição dos
valores em intervalos regulares de acordo com o grid a ser criado.
Vamos aqui ver como carregar uma imagem de um modelo digital de elevação e gerar
um sombreamento para realce de relevo. Depois vamos carregar uma imagem Sentinel2
com 3 bandas no espectro do visível da mesma área.
Abra o QGIS e carregue a imagem raster dem.tif Camada > Adicionar Camada > Raster
ou Ctrl+Shift +r e proceda acionando ... para navegar ao local do arquivo dem.tif. Em
seguida clique em Adicionar e Close. A objeto raster deverá ser carregado conforme
mostrado abaixo.
No painel Camadas clique duas vezes em dem e vamos modificar as cores de cinza para
uma rampa de cor já predefinida. Na janela que se abriu selecione Simbologia no painel
da esquerda e selecione Paletizado/Valores Únicos no campo Tipo de renderização.
Selecione Spectral no campo Gradiente de Cores e pressione o botão Classifica. Após
isso clique em OK. Nosso DEM aparecerá conforme a imagem abaixo.
Vamos agora processar o DEM para gerar um sombreamento para realçar o relevo da
imagem. No menu selecione Raster > Análise > Sombreamento e a janela aparecerá.
Clique em Executar com os parâmetros apresentados e a imagem Sombreamento será
criada.
Clique duas vezes em sombreamento e selecione Transparência na esquerda, entre com
o valor 40% no primeiro campo e clique em OK. De um zoom numa região com diferença
de relevo e compare o resultado.
Sem sombreamento:
Com Sombreamento:
Combinamos estas três bandas para criar uma composição de cor verdadeira (RGB)
usando Raster > Miscelânea > Mesclar. Selecione as três bandas recém carregadas
clicando no ... e marcando elas conforme abaixo.
Clique OK na janela de Seleção Múltipla e em seguida coloque cada arquivo de entrada
em uma banda separada. Selecione ‘Coloque cada arquivo de entrada em banda
separada’. Clique Executar e Close e uma nova imagem raster chamada Mesclado.
Vamos clicar duas vezes em Mesclado e colocar banda 3 no canal vermelho e Banda 1
no canal Azul e clicar em OK. A nossa imagem deverá aparecer assim.
Entre em Camada > Criar Nova Camada > Shapefile para criar uma camada.
Vamos inicialmente criar uma camada do tipo ponto.
Primeiro criamos o arquivo selecionando o botão ..., navegue até a pasta desejada e crie
um arquivo com o nome poi.shp
Uma nova camada com o nome poi aparecerá no painel de Camadas. Estamos prontos
para adicionar novos pontos nela. O processo é feito pelo menu Camada > Alternar
edição, estamos prontos para adicionar pontos. Fazemos isso pelo menu Editar >
Ao terminar de adicionar os pontos clique em Camada > Alternar edição para finalizar e
clique em Save para salvar a adição dos pontos. Abra agora a tabela de dados e selecione
um dos pontos. Teremos algo como o mostrado abaixo.
Acabamos de criar uma camada do tipo pontos. Vamos agora repetir o processo criando
uma camada do tipo linha e outra do tipo polígono.
Entre em Camada > Criar Nova Camada > Shapefile para criar uma camada e crie uma
camada do tipo linha com o nome de rota com os atributos nome_rota e tipo_rota.
Clique em e digite as linhas clicando com o botão esquerdo do mouse, ao terminar uma
avenida clique no botão direito do mouse e entre com os atributos desta linha, repita
para digitar duas novas linhas.
Finalizaremos agora criando uma camada do tipo polígono. Entre em Camada > Criar
Nova Camada > Shapefile para criar uma camada e crie uma camada do tipo polígono
com o nome de cancha com o atributo nome_canch. Clique em e digite as linhas clicando
com o botão esquerdo do mouse, ao terminar um dos campos de futebol clique no botão
direito do mouse e entre com os atributos deste polígono, repita para digitar o outro
polígono.
Para gravar esse raster basta clicar com o botão direito do mouse na camada e
selecionar Exportar > Salvar como. Escolha o nome e diretório e use as opções padrões
apresentadas.
Pronto! Aqui finalizamos nossa breve introdução ao QGIS, muito mais pode ser feito,
mas o foco agora será o uso de Python no QGIS. Primeiros veremos os fundamentos da
linguagem e depois cobriremos o seu uso no QGIS.
2. Fundamentos de Python
2.0 A linguagem Python – Introdução
Python foi criada por Guido Van Rossum em 1991 quando ele trabalhava para no
Instituto de Pesquisa Nacional para Matemática e Ciência da Computação (CWI) na
Holanda.
Em 2001 a linguagem passou a ser desenvolvida pela Python Software Foundation. Todo
código, documentação e especificação, desde o lançamento da versão alfa 2.1, é
propriedade da Python Software Foundation (PSF).
Instalação
QGIS já vem com python instalado e vamos usar o Console Python do QGIS inicialmente.
Console Python
Vamos utilizar o Console Python para aprender os conceitos básicos de python.
O console Python pode ser iniciado usando CTRL+ALT+P ou menu Plugin > Python
Console:
Python Console
Use iface to access QGIS API interface or Type help(iface) for more info
Security warning: typing commands from an untrusted source can harm your computer
Tipos Numéricos
Python possui primitivamente os tipos numéricos de números inteiros (int), ponto
flutuante (float) e complexo (complex).
>>> a = 1
>>> b = 3.2
>>> c = 4 + 3j
Tipo Alfanumérico
Em python o tipo str é usado para palavras, textos e caracteres alfanuméricos.
>>> nome = 'Manuel'
>>> type(nome)
<class 'str'>
>>> letra = 'a'
>>> type(letra)
<class 'str'>
Um objeto da classe str nada mais é do que uma matriz de valores sequenciados onde o
primeiro valor (caractere) corresponde ao índice 0 da matriz e o último valor ao índice -
1, o penúltimo -2 e assim sucessivamente.
>>> nome[0]
'M'
>>> nome[1]
'a'
>>> nome[-1]
'l'
>>> nome[-2]
'e'
>>> nome[-6]
'M'
>>> nome[2:5] #note que o valor do índice 5 não está incluído
'nue'
Um objeto str uma vez definido é imutável e se tentarmos mudar o valor de um objeto
str uma mensagem de erro aparecerá.
>>> nome[2]='t'
Traceback (most recent call last):
File "/usr/lib/python3.7/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Podemos usar aspas simples ou duplas para delimitar um objeto str para podermos
definir estas como:
>>> s1 = "Bom dia senhor O'Brien"
>>> print(s1)
Bom dia senhor O'Brien
>>> s2= 'Quoth the raven "Nevermore". '
>>> print(s2)
Quoth the raven "Nevermore".
Tipo lista
Python possui diversos tipos compostos de dados, a lista (list) e uma delas.
Uma lista é um conjunto de objetos de determinado tipo ou de tipos distintos
armazenados em uma lista.
Listas são declaradas dentro de colchetes onde cada objeto (item) dela é separado por
vírgula.
>>> lista = [3200,2670,3100,3000]
>>> caipi = ['gelo', 'limão','açúcar',51,15.99]
Assim como str, cada item de uma lista pode ser acessado usando índices.
>>> lista[0]
3200
>>> lista[1]
2670
>>> lista[3]
3000
>>> lista[1:3]
[2670, 3100]
>>> type(lista2[0])
<class 'str'>
>>> type(lista2[3])
<class 'int'>
>>> type(lista2[4])
<class 'float'>
>>> lista2[-1]
15.99
Ao contrário do objeto str, os valores de itens de uma lista podem ser modificados
>>> caipi[3]='pinga'
>>> caipi
['gelo', 'limão', 'açúcar', 'pinga', 15.99]
Uma lista pode conter outras listas como itens. E acessamos cada item dessa lista interna
usando um índice adicional.
>>> caipi[1]=['abacaxi','maracujá','limão']
>>> caipi
['gelo', ['abacaxi', 'maracujá', 'limão'], 'açúcar', 'pinga', 15.99]
>>> caipi[1][1]
'maracujá'
>>> caipi[1][-1]
'limão'
Podemos adicionar itens a uma lista já existente usando adição ou a função append().
>>> caip = caipi + ['guardanapo','canudo']
>>> caipi.append('copo')
>>> caipi
['gelo', ['abacaxi', 'maracujá', 'limão'], 'açúcar', 'pinga', 15.99,
'guardanapo',
'canudo', 'copo']
O método pop() remove e retorna o item indicado pelo índice dado, se nenhum índice
é fornecido o último item é removido da lista e retornado.
>>> lis3 = [1,1,2,3,4,4,4,3,2,3,1]
>>> lis3.pop(1)
1
>>> lis3
[1, 2, 3, 4, 4, 4, 3, 2, 3, 1]
Podemos usar a instrução del para deletar itens de uma lista usando índices em vez de
valores.
>>> lis3 = [1,1,2,3,4,4,4,3,2,3,1]
>>> del lis3[2]
>>> lis3
[1, 1, 3, 4, 4, 4, 3, 2, 3, 1]
>>> del lis3[5:8]
>>> lis3
[1, 1, 3, 4, 4, 3, 1]
Tuples
Assim como str e listas, tuples são dados em sequência usados em python. As diferenças
principais entre uma tuple e uma lista é que tuples são declaradas usando vírgulas para
separar os itens e esses itens são imutáveis.
>>> t = 'banana', 3,45, False, "oi!"
>>> t
('banana', 3, 45, False, 'oi!')
>>> t[0]
'banana'
>>> doist =t,(1,2,3,4,5)
>>> doist
(('banana', 3, 45, False, 'oi!'), (1, 2, 3, 4, 5))
>>> doist[0]
('banana', 3, 45, False, 'oi!')
>>> doist[0][0]
'banana'
>>> doist[1][0]
1
>>> t[0]='maçã'
Traceback (most recent call last):
File "C:/PROGRA~1/QGIS3~1.4/apps/Python37/lib/code.py", line 90, in
runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Sets
Sets ou conjuntos são outro tipo de dados em sequência que python utiliza. Sets são
definidos dentro de chaves {} e resultam em uma simples aparição de cada um de seus
itens e estes não são indexados.
>>> conjunto = {'rio','terra','fogo','fogo','água','terra'}
>>> conjunto
{'terra', 'fogo', 'rio', 'água'}
>>> 'rio' in conjunto
True
>>> 'mar' in conjunto
False
>>> num ={1,2,3,2,3,2,1,23,'a'}
>>> num
{1, 2, 3, 'a', 23}
>>> cidade=set('pindamonhongaba')
>>> cidade
{'p', 'a', 'h', 'm', 'g', 'n', 'i', 'o', 'b', 'd'}\
Dicionários
Dicionários são um tipo de dados bastante usado em python. Um dicionário possui
sempre uma chave e um valor, esta chave é usada no lugar de um índice numérico que
é usado numa lista. Essa chave deve ser única e um dicionário vazio pode ser criado
usando {}.
>>> dicio={'nome':'andre','sobrenome':'costa'}
>>> dicio['idade']=51
>>> dicio
{'nome': 'andre', 'sobrenome': 'costa', 'idade': 51}
>>> list(dicio)
['nome', 'sobrenome', 'idade']
>>> sorted(dicio)
['idade', 'nome', 'sobrenome']
>>> dicio[1]
Traceback (most recent call last):
File "C:/PROGRA~1/QGIS3~1.4/apps/Python37/lib/code.py", line 90, in
runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
KeyError: 1
>>> del dicio['idade']
>>> dicio
{'nome': 'andre', 'sobrenome': 'costa'}
>>> dicio2=dict([('código', 34), ('senha', 65483), ('acessos', 8)])
>>> dicio2
{'código': 34, 'senha': 65483, 'acessos': 8}
Obrigatoriamente em python temos de usar recuo de blocos de código uma vez que não
os separamos por chaves {}, assim todo bloco de código, seja ele uma classe, função
ou um controle de fluxo, deve ser indentado. Num bloco com recuo no console, o >>>
se transforma em ... indicando que estamos dentro de um bloco no script. Quando
todas as instruções do bloco estão finalizadas, teclamos ‘enter’ na linha final com ...
if elif else
O if talvez seja a instrução mais conhecida em programação. Ela checa se (if) uma
condição ou se outras condições (elif) são atendidas. Se nenhuma condição for
atendida, podemos também instruir que algo seja feito (else).
>>> x = int(input("Diga um número inteiro: "))
Diga um número inteiro: 2
>>> if x<0:
... print('O número é negativo')
... elif x>0:
... print('O número é positivo')
... else:
... print('O número é zero')
...
O número é positivo
for
A repetição (loop) for é definida como “executar/repetir as instruções nos termos
predefinidos”. No exemplo abaixo a repetição é feita para cada palavra da variável
palavras e a palavra e o comprimento dela é impresso como resultado.
>>> palavras = ['Olá!','Vamos','aprender','python?']
>>> for palavra in palavras:
... print(palavra,len(palavra))
...
Olá! 4
Vamos 5
aprender 8
python? 7
while
A repetição while é definida com “enquanto o que foi predefinido não ocorrer, vai
executando/repetindo”.
>>> a, b = 0, 1
>>> while a < 1000:
... print(a, end=',')
... a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
range()
A forma que python interage com uma série numérica é usando a função range().
>>> for i in range(10):
... print(i,end=',')
...
0,1,2,3,4,5,6,7,8,9,
Vamos supor que não sabemos a quantidade de itens numa lista mas queremos interagir
(no caso listar) cada um destes itens. Usamos range para nos auxiliar.
>>> palavras = ['Olá!','Vamos','aprender','python?']
>>> for i in range(len(palavras)):
... print(palavras[i],i)
...
Olá! 0
Vamos 1
aprender 2
python? 3
2.3 Funções
Uma outra forma de escrever essa função, utilizando um valor a ser retornado desta no
formato de lista, é mostrada a seguir:
>>> def fibo2(n):
... """Calcula e retorna a série de Fibonacci até o limite
informado"""
... resultado=[]
... a,b=0,1
... while a<n:
... resultado.append(a)
... a,b=b,a+b
... return resultado
...
>>> fibo2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Se passarmos nossa função como argumento para a função help teremos a string de
documentação (entre as aspas duplas repetidas três vezes) como informação retornada.
Essa é uma maneira de documentar o que uma função faz em python.
>>> help(fibo2)
Help on function fibo2 in module __main__:
fibo2(n)
Calcula e retorna a série de Fibonacci até o limite informado
Vamos ver agora um exemplo prático de como trabalhar com funções criando um nosso
primeiro script. Crie o arquivo temp_converter.py com o seguinte código.
#!/usr/bin/env python3
'''Converte temperaturas de Celsius para Fahrenheit, Kelvin para
Celsius e Kelvin
para Fahrenheit.
Uso:
Carregue usando import
import temp_converter as tc
Autor:
Seu Nome - 03.12.2019'''
def celsius_para_fahr(temp_celsius):
return 9/5 * temp_celsius + 32
def kelvins_para_celsius(temp_kelvins):
return temp_kelvins - 273.15
def kelvins_para_fahr(temp_kelvins):
temp_celsius = kelvins_para_celsius(temp_kelvins)
temp_fahr = celsius_para_fahr(temp_celsius)
return temp_fahr
2.4 Módulos
Em python um module (módulo) é simplesmente um arquivo com extensão .py com com
classes, funções e demais instruções. Nosso script acima é um exemplo de um módulo.
Um package (pacote) é uma forma de organizar vários módulos em uma entidade maior.
Algumas linguagem chamam módulos e pacotes de library. Um module é carregado
usando o comando import e podemos renomear um módulo usando as
>>> import math as m
>>> m.sqrt(81)
9
Usaremos o tempo todo vários módulos, essa é e força da linguagem python com
inúmeros módulos existentes para as mais diversas funções. Vamos iniciar vendo o
módulo pandas.
2.5 Pandas
A biblioteca pandas foi desenvolvida por Wes McKinney como uma alternativa a
linguagem R para lidar com estrutura de dados mais complexas. Hoje é uma biblioteca
potente e moderna largamente utilizadas em diversas áreas da ciência.
Baixe o arquivo curvelo.csv e inicie o python. Vamos trabalhar com pandas lendo o
conteúdo desse arquivo.
>>> import pandas as pd
>>> data = pd.read_csv('curvelo.csv')
>>> data.head()
codigo_estacao data hora ...vento_rajada radiacao precipitacao
0 A538 01/01/2019 16 ... 6.7 2749.00 0.0
1 A538 01/01/2019 8 ... 3.8 -2.63 0.2
2 A538 01/01/2019 11 ... 1.8 977.30 0.0
3 A538 01/01/2019 12 ... 2.6 1349.00 0.0
4 A538 01/01/2019 15 ... 6.3 3561.00 0.0
[5 rows x 20 columns]
>>> type(data)
<class 'pandas.core.frame.DataFrame'>
>>> len(data)
7545
>>> data.shape
(7545, 20)
>>> data.columns.values
array(['codigo_estacao', 'data', 'hora', 'temp_inst', 'temp_max',
'temp_min', 'umid_inst', 'umid_max', 'umid_min',
'pto_orvalho_inst', 'pto_orvalho_max', 'pto_orvalho_min',
'pressao', 'pressao_max', 'pressao_min', 'vento_direcao',
'vento_vel', ' vento_rajada', 'radiacao', 'precipitacao'],
dtype=object)
>>> data.dtypes
codigo_estacao object
data object
hora int64
temp_inst float64
temp_max float64
temp_min float64
umid_inst int64
umid_max float64
umid_min float64
pto_orvalho_inst float64
pto_orvalho_max float64
pto_orvalho_min float64
pressao float64
pressao_max float64
pressao_min float64
vento_direcao float64
vento_vel int64
vento_rajada float64
radiacao float64
precipitacao float64
dtype: object
Vamos agora usar pandas para fazer o caminho inverso, de lista de dados para arquivo
estacoes.csv.
>>> estacao=['E-01','E-02','E-03','E-04','E-05','E-06']
>>> latitude=[-3.34,-3.23,-3.12,-3.32,-3.33,-3.19]
>>> longitude=[-60.12,-60.43,-60.11,-60.54,-59.87,-60.00]
>>> dadoEst = pd.DataFrame(data = {"Estação" : estacao, "latitude" :
latitude,
"longitude" : longitude})
>>> dadoEst
Estação latitude longitude
0 E-01 -3.34 -60.12
1 E-02 -3.23 -60.43
2 E-03 -3.12 -60.11
3 E-04 -3.32 -60.54
4 E-05 -3.33 -59.87
5 E-06 -3.19 -60.00
>>> dadoEst.to_csv('estacoes.csv')
2.6 Gráficos
Vamos mostrar simplificadamente como podemos criar gráficos com python. Existem
diversas bibliotecas para a criação de gráficos mas aqui vamos usar o matplotlib com o
auxílio de pandas para criar alguns gráficos básicos.
>>> import pandas as pd
>>> import matplotlib.pyplot as plt
>>> data = pd.read_csv('curvelo.csv')
>>> plt.plot(data[['precipitacao']], label='Precipitação')
[<matplotlib.lines.Line2D object at 0x7f55bbc70d90>]
>>> plt.ylabel('Precipitação mm')
Text(0, 0.5, 'Precipitação mm')
>>> plt.legend()
<matplotlib.legend.Legend object at 0x7f55bcee2b50>
>>> plt.show()
Vamos usar o numpy para criar uma série de números entre 0 e 2 e plotar a sequência
linear, quadrática e cúbica de série para ilustrar como criar um gráfico com mais de uma
curva.
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> x = np.linspace(0, 2, 100)
>>> plt.plot(x, x, label='linear')
>>> plt.plot(x, x**2, label='quadrática')
>>> plt.plot(x, x**3, label='cúbica')
>>> plt.ylabel('Eixo Y')
>>> plt.xlabel('Eixo X')
>>> plt.title("Gráfico Simples")
>>> plt.legend()
>>> plt.show()
3.Usando Python no QGIS
Vamos introduzir as classes do PyQGIS na medida que avançamos nos pontos cobertos.
Uma classe em python é a definição de um tipo de objeto e de métodos (funções)
associados a este objeto. Por exemplo um projeto, uma camada raster, uma camada
vetorial, etc.
A biblioteca PyQGIS é bastante extensa com diversas classes. Vamos aqui cobrir as
classes mais básicas e essenciais para a partir deste ponto termos uma boa base para
desenvolver scripts mais complexos.
Agora vamos sair do QGIS e entrar novamente para carregarmos o projeto que criamos
usando python.
>>> projeto=QgsProject.instance()
>>> projeto.read('c:/users/voce/meu_projeto.qgs')
>>> print(projeto.fileName())
c:/users/voce/meu_projeto.qgs
Na medida que formos vendo as outras classes, vamos ver outros métodos associados à
classe Projeto.
Agora vamos fazer uso de uma outra classe para podermos carregar uma camada
vetorial localizada em um banco de dados Postgis remoto. A classe é a QgsDataSourceUri
e usaremos os métodos setConnection() e setDataSource() para extrairmos uma tabela
espacial vetorial. Criaremos um projeto novo, adicionaremos uma camada local e uma
camada remota Postgis e por último vamos gravar o projeto.
>>> projeto = QgsProject.instance()
>>> #ajustar caminho dos arquivos de acordo com seu sistema
>>> projeto.write('c:/users/voce/meu_projeto2.qgs')
>>> am=QgsVectorLayer("c:/users/voce/amazonas.shp","AM","ogr")
>>> projeto.addMapLayer(am)
>>> uri = QgsDataSourceUri()
>>> uri.setConnection("pg.amazeone.com.br","5432","dnpmam","droid",
"devcor")
>>> uri.setDataSource("public", "indio", "geom")
>>> rindig = QgsVectorLayer(uri.uri(False), "Reserva Indígena",
"postgres")
>>> projeto.addMapLayer(rindig)
>>> projeto.write()
Podemos obter diversas informações sobre objetos vetoriais tais como, projeções,
extensão, número de elementos, valores e nomes dos campos de atributos (colunas) e
até criar um metadata da camada (com a informação existente).
A camada será carregada conforme a ilustração mostrada abaixo. Vamos agora acessar
as informações mais usadas de maneira geral. Outras informações existem no objeto
camada, veja a documentação para mais detalhes.
O sistema de referência de coordenadas CRS (Coordinate Reference System)
O método crs() retorna o sistema de referência de coordenada original do objeto
camada que o invoca.
>>> crs=rmp.crs()
>>> print(crs.description())
Unknown datum based upon the GRS 1980 ellipsoid
A extensão da Camada
Com o método extent() de um objeto camada podemos obter os valores máximos e
mínimos das coordenadas em X (Easting ou Longitude) e Y (Northing ou Latitude). O
método retorna um objeto do tipo retângulo com diversos parâmetros além de X e Y
máximos e mínimos tais como area, width, height, center, invert, etc. Veja a
documentação para mais informações.
>>> extensão=rmp.extent()
>>> min_x=extensão.xMinimum()
>>> max_x=extensão.xMaximum()
>>> min_y=extensão.yMinimum()
>>> max_y=extensão.yMaximum()
>>> print(min_x,min_y,max_x,max_y)
-70.1 -9.53860000030878 -56.7497 2.21390000007294
Quantidade de itens
O método featureCount() retorna quantos itens o objeto camada possui.
>>> num_elementos=rmp.featureCount()
>>> print("número de elementos: ", num_elementos)
número de elementos: 624
</body>
</html>
Comentário
Codificação
-70.0999999999999943,-9.5386000003087794 : -
Extensão
56.7496999999999971,2.2139000000729401
Unidade Graus
Contagem de
624
feições
Identificação
Identifier
Parent Identifier
Title
Type dataset
Language
Abstract
Categories
Keywords
Extensão
Spatial Extent
Temporal
Extent
Acesso
Fees
Licenses
Rights
Constraints
Campos
Contagem 26
codigo_obj text -1 0
TOPONIMIA text -1 0
Latitude float8 -1 0
Longitude float8 -1 0
SUBST_PRIN text -1 0
subst_sec text -1 0
Abrev text -1 0
STATUS_ECO text -1 0
grau_de_im text -1 0
metodo_geo text -1 0
erro_metod text -1 0
data_cad text -1 0
classe_uti text -1 0
Tipologia text -1 0
classe_gen text -1 0
modelo_dep text -1 0
assoc_geoq text -1 0
rocha_enca text -1 0
rocha_hosp text -1 0
textura_mi text -1 0
tipos_alte text -1 0
extrmin_x_ text -1 0
assoc_mine text -1 0
Origem text -1 0
Município text -1 0
Uf text -1 0
Contatos
No contact yet.
Links
No links yet.
Histórico
No history yet.
De forma semelhante ao que foi feito acima, podemos extrair informações relevantes
de um objeto raster também tais como dimensões, resoluções, número de bandas, valor
de um pixel, etc. Vamos carregar uma imagem inicialmente.
>>> projeto=QgsProject.instance()
>>> camadaR = QgsRasterLayer("c:/users/voce/praia_vermelha.TIF",
"img")
>>> projeto. addMapLayer(camadaR)
Nome Img
Caminho C:\\Users\\andre.costa\\Downloads\\part3\\pyqgys\\praia_vermelha.tif
687173.9999999998835847,7459532.4000000003725290 :
Extensão
688805.6999999998370185,7461990.0000000000000000
Unidade Metros
Largura 5439
Altura 8192
Descrição do
GTiff
driver GDAL
Metadados
do driver GeoTIFF
GDAL
Descrição do
C:/Users/andre.costa/Downloads/part3/pyqgys/praia_vermelha.tif
registro
Compressão
STATISTICS_APPROXIMATE=YES
STATISTICS_MAXIMUM=2047
STATISTICS_MEAN=220.86768822394
Banda 1
STATISTICS_MINIMUM=0
STATISTICS_STDDEV=156.88305888003
STATISTICS_VALID_PERCENT=100
AREA_OR_POINT=Area
TIFFTAG_MAXSAMPLEVALUE=2047
TIFFTAG_MINSAMPLEVALUE=0
Origem 687174,7.46199e+06
Tamanho do
0.2999999999999999889,-0.2999999999999999889
Pixel
Identificação
Identifier
Parent Identifier
Title
Type
Language
Abstract
Categories
Keywords
Extensão
CRS
Spatial Extent
Temporal Extent
Acesso
Fees
Licenses
Rights
Constraints
Bandas
Contagem de bandas 1
Contatos
No contact yet.
Referências
No links yet.
Histórico
No history yet.
Vamos ver agora métodos para raster de uma e de mais de uma banda.
>>> camadaR.rasterType()
0
A função dataProvider() funciona como uma interface entre o objeto raster os seus
dados individuais, seu método sample() toma dois valores, um objeto ponto
(coordenadas XZ) e o número da banda. Se a coordenada for dentro da imagem e a
banda existir o resultado será um tuple com o valor do pixel e se o dado é verdadeiro ou
não.
>>> valor = camadaR.dataProvider().sample(QgsPointXY(687567, 7460876),
1)
>>> valor
(163.0, True)
>>> valor2 = camadaR.dataProvider().sample(QgsPointXY(687567,
7463876), 1)
>>> valor2
(nan, False)
A rampa de cor assinalada ao objeto raster pode ser checada usando o método type()
do método renderer(). O tipo singlebandgray é o padrão inicial.
>>> camadaR.renderer().type()
'singlebandgray'
Podemos alterar via python a rampa de cores, o processo é mostrado abaixo. O processo
envolve na criação de um objeto do tipo ColorRampShader e definimos a rampa de cor
de preenchimento como sendo do tipo interpolado.
>>> fcn = QgsColorRampShader()
>>> fcn.setColorRampType(QgsColorRampShader.Interpolated)
Criamos agora uma lista com as cores representando os dois valores extremos do raster
(0 e 2046 que serão interpolados entre azul e amarelo. Em seguida adicionamos esta
lista como item do ColorRampShader criado acima.
>>> lista = [ QgsColorRampShader.ColorRampItem(0, QColor(0,0,255)),
QgsColorRampShader.ColorRampItem(2046, QColor(255,255,0))]
>>> fcn.setColorRampItemList(lista)
Finalmente criamos o objeto renderizador de cor com: dados do objeto raster, banda 1
e shader acima. Em seguida aplicamos este ao objeto raster e chamamos a repintura do
objeto
>>> renderer =
QgsSingleBandPseudoColorRenderer(camadaR.dataProvider(), 1, shader)
>>> camadaR.setRenderer(renderer)
>>> camadaR.triggerRepaint()
Vamos ver abaixo como modificar a imagem para que a banda 1 fique no canal azul (B)
e a banda 3 fique no canal Vermelho (R).
>>> camadaR.renderer().setBlueBand(1)
>>> camadaR.renderer().setRedBand(3)
>>> camadaR.triggerRepaint()
Note que o histograma da imagem não foi apropriadamente ajustado porque ainda usa
os valores de máximo e mínimo das bandas anteriores.
Vamos agora ver os passos para criarmos objetos vetoriais usando python no Qgis.
Vamos criar objetos do tipo ponto, linha e polígono para ilustrar o processo.
Ponto
Primeiro definimos o objeto ponto com CRS 4326 (WGS84) com o nome Cidades na
memória. Nesse objeto usamos um dataProvider para criar os campos de atributos do
objeto vetorial ponto com três atributos (nome, população e IDH) e adicionamos eles no
objeto ponto (vponto).
>>> vponto = QgsVectorLayer("Point?crs=EPSG:4326", "Cidades",
"memory")
>>> dPr = vponto.dataProvider()
>>> dPr.addAttributes([QgsField("nome", QVariant.String),
QgsField("populacao",QVariant.Int), QgsField("idh", QVariant.Double)])
>>> vponto.updateFields()
Uma vez criado o objeto ponto e seus campos de atributo vamos adicionar dados nele
usando um objeto feature (elemento). Definimos a geometria que será um ponto nesse
caso com coordenadas x e y e adicionaremos os atributos deste ponto.
>>> elem = QgsFeature()
>>> elem.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-59.9936,-
3.0925)))
>>> elem.setAttributes(["Manaus", 2182763, 0.737])
>>> dPr.addFeature(elem)
>>> elem.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-60.6253,-
3.2872)))
>>> elem.setAttributes(["Manacapuru ", 97377, 0.614])
>>> dPr.addFeature(elem)
>>> elem.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-60.1883,-
3.2756)))
>>> elem.setAttributes(["Iranduba ", 48296, 0.613])
>>> dPr.addFeature(elem)
>>> elem.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-59.7014,-
2.6968)))
>>> elem.setAttributes(["Rio Preto Da Eva ", 33347, 0.611])
>>> dPr.addFeature(elem)
Para finalizar vamos configurar a aparência do símbolo mostrado no mapa como estrelas
de cor laranjas e de tamanho 8. Atualizamos a extensão do mapa e adicionamos nosso
objeto no mapa.
>>> symbol = QgsMarkerSymbol.createSimple({'name': 'star', 'color':
'orange','size':'8'})
>>> vponto.renderer().setSymbol(symbol)
>>> vponto.updateExtents()
>>> QgsProject.instance().addMapLayer(vponto)
Veja a documentação para cada uma das opções que podem ser usadas com cada
parâmetro listado acima. Vamos Modificar a aparência do símbolo que criamos acima.
>>> prp = vponto.renderer().symbol().symbolLayer(0).properties()
>>> prp['color'] = 'blue'
>>> prp['name'] = 'square'
>>> vponto.renderer().setSymbol(QgsMarkerSymbol.createSimple(prp))
>>> vponto.triggerRepaint()
Definimos o objeto linha (linestring) com CRS 4326 (WGS84) com o nome Vias na
memória. Criamos o dataProvider para adicionar os campos de atributos do objeto
vetorial linestring com dois atributos (nome e número) e adicionamos eles no objeto
linestring (vlinha).
>>> vlinha = QgsVectorLayer("Linestring?crs=EPSG:4326", "Vias",
"memory")
>>> dPr = vlinha.dataProvider()
>>> dPr.addAttributes([QgsField("nome", QVariant.String),
QgsField("número",QVariant.Int)])
>>> vlinha.updateFields()
Adicionamos as linhas usando um objeto feature (elemento). Mas antes criamos a lista
de pontos que farão parte de cada um dos elementos do tipo linha e inserimos os
atributos de cada elemento. Vamos inserir três linhas.
>>> elem = QgsFeature()
>>> pontos =[QgsPoint(-124,48.4), QgsPoint(-123.5,48.6 ), QgsPoint(-
123,48.9),QgsPoint(-122.8,48.7)]
>>> elem.setGeometry(QgsGeometry.fromPolyline(pontos))
>>> elem.setAttributes(["Rota ", 1])
>>> dPr.addFeature(elem)
>>> pontos =[QgsPoint(-121,48.4), QgsPoint(-120.5,48.6 ), QgsPoint(-
120,48.9),QgsPoint(-119.8,48.7)]
>>> elem.setGeometry(QgsGeometry.fromPolyline(pontos))
>>> elem.setAttributes(["Rota ", 2])
>>> dPr.addFeature(elem)
>>> pontos =[QgsPoint(-124,45.4), QgsPoint(-123.5,45.6 ), QgsPoint(-
123,45.9),QgsPoint(-122.8,45.7)]
>>> elem.setGeometry(QgsGeometry.fromPolyline(pontos))
>>> elem.setAttributes(["Rota ", 3])
>>> dPr.addFeature(elem)
Para finalizar, vamos gravar o recém-criado vetor num arquivo do tipo shapefile.
>>> QgsVectorFileWriter.writeAsVectorFormat(vlinha,
'c:/users/voce/vias.shp', 'utf-8', driverName='ESRI Shapefile')
Polígono
Criamos polígonos usando python/Qgis de forma idêntica à forma que criamos linhas só
que nesse caso o último ponto se liga ao primeiro ponto informado.
Definimos o objeto polígono com CRS 4326 (WGS84) com o nome Fazendas na memória.
Criamos o dataProvider para adicionar os campos de atributos do objeto vetorial
polígono com dois atributos (nome e número) e adicionamos eles no objeto polígono
(vpgon).
>>> vpgon = QgsVectorLayer("Polygon?crs=EPSG:4326", "Fazendas",
"memory")
>>> dPr = vpgon.dataProvider()
>>> dPr.addAttributes([QgsField("nome", QVariant.String),
QgsField("número",QVariant.Int)])
>>> vpgon.updateFields()
Imagens raster também podem ser criadas via script de forma bem eficiente usando
uma lista de dados pontuais com um determinado valor. Vamos aqui criar um raster
mostrando a temperatura média de uma área com base em informações pontuais de
vários locais. O arquivo CSV tfinal.csv tem os dados com coordenadas, e respectivos
valores. Vamos carregar a informação em um objeto do tipo QsgInterpolator camada
de dados (layerData).
>>> uri="file:///c:/users/voce/tfinal.csv?
type=csv&xField=LONGITUDE&yField=LATITUDE&crs=epsg:4326"
>>> camada = QgsVectorLayer(uri, 'Converte', "delimitedtext")
>>> c_data = QgsInterpolator.LayerData()
>>> c_data.source = camada
>>> c_data.zCoordInterpolation = False
>>> c_data.interpolationAttribute = 6
>>> c_data.sourceType = QgsInterpolator.SourcePoints
Agora definimos qual arquivo será criado e os parâmetros do grid a ser usado.
>>> arquivo = "c:/users/voce/rasterDeTeste.asc"
>>> rect = camada.extent()
>>> res = 0.01
>>> ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
>>> nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
>>> saida = QgsGridFileWriter(interpolado,arquivo,rect,ncol,nrows)
>>> saida.writeFile()
Vamos mostrar como isso funciona criando um script que criará um grid raster a partir
de um arquivo texto CSV com alguns pontos. O mesmo procedimento do último exemplo
do capítulo anterior. Nomeie o arquivo de criaRaster.py. Substitua /home/usr
apropriadamente para o seu sistema.
from qgis.core import *
from qgis.analysis import *
QgsApplication.setPrefixPath("/usr", True)
qgs = QgsApplication([], False)
qgs.initQgis()
uri="file:////home/usr/tfinal.csv?
type=csv&xField=LONGITUDE&yField=LATITUDE&crs=epsg:4326"
camada = QgsVectorLayer(uri, 'Converte', "delimitedtext")
if not camada.isValid():
print("A camada não carregou apropriadamente!")
else:
c_data = QgsInterpolator.LayerData()
c_data.source = camada
c_data.zCoordInterpolation = False
c_data.interpolationAttribute = 6
c_data.sourceType = QgsInterpolator.SourcePoints
interpolado = QgsIDWInterpolator([c_data])
interpolado.setDistanceCoefficient(2)
arquivo = "/home/usr/rasterScript.asc"
rect = camada.extent()
res = 0.001
ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
saida = QgsGridFileWriter(interpolado,arquivo,rect,ncol,nrows)
saida.writeFile()
qgs.exitQgis()
- Termos certeza que a variável PATH aponta para a pasta correta de instalação do Qgis,
algo similar a e “C:/ProgramFiles/QGIS3.X/bin”
- Alterar a linha QgsApplication.setPrefixPath("/usr", True) para
QgsApplication.setPrefixPath("C:/ProgramFiles/QGIS3.X/bin/", True)
Na próxima apostila faremos um uso intensivo de scripts fora do ambiente Qgis, tenha
certeza de que o exemplo mostrado acima funcionou perfeitamente no seu sistema.