Como criar seu primeiro plugin para QGIS usando Python e Qt Designer? Parte III
Aprenda a criar seu próprio plugin para QGIS. Nesta terceira parte, ensinamos a exportar seu mapa para PDF e PNG utilizando Python.
E chegamos à última parte do nosso tutorial de criação de plugins para o QGIS utilizando Python e o Qt Designer. Na primeira postagem, ensinamos como criar os arquivos base do plugin e como solicitar ao usuário pontos temporários para serem inseridos no mapa.
Na segunda postagem, vimos como salvar o shapefile do ponto inserido, como avaliar em qual região de um determinado zoneamento o ponto esta localizado e como corrigir erros no Python.
Caso você não tenha lido a primeira e segunda parte, você pode ler elas clicando nos links abaixo.
- Como criar plugins no QGIS com Python e Qt Designer (Parte 01);
- Como criar plugins no QGIS com Python e Qt Designer (Parte 02).
Nesta terceira parte do tutorial, iremos mostrar como criar um mapa no compositor de impressão, de forma que possamos exportar o ponto inserido e o zoneamento avaliado para outros usuários no formato PDF e PNG.
Preparando o Compositor de Impressão com PyQGIS
Antes de começarmos a inserirmos as funções relacionadas ao compositor de impressão, precisamos importar elas. Você deve inserir nas linhas iniciais do arquivo python (.py) as seguintes linhas:
from PyQt4.QtGui import QAction, QIcon, QFileDialog, QPrinter, QPainter, QImage, QColor # Nesta linha, foram adicionados os itens QPrinter, QPainter, QImage e QColor from qgis.utils import iface # Adicione esta linha para importar o item iface
Agora que já importamos as funções necessárias, vamos incorporar, passo a passo, os itens do nosso mapa.
As próximas linhas de código serão inseridas no final do nosso arquivo python, logo após a verificação se os checkbox da área de estudo estão selecionados ou não.
Primeiro, iremos criar uma composição do tipo QgsComposition a qual irá receber a informação visual do nosso mapa. Confira o código abaixo.
# Criação de uma composição QgsComposition mapRenderer = iface.mapCanvas().mapRenderer() c = QgsComposition(mapRenderer) c.setPlotStyle(QgsComposition.Print)
O próximo passo é definir onde será impresso nosso mapa em uma folha A4 (o QGIS define como padrão de saída folha A4 com resolução de 300 dpi). Note que após criar as variáveis, elas são inseridas dentro do nosso mapa usando a função addItem().
# Adicionando e definindo onde o mapa será inserido na folha x, y = 0, 0 w, h = c.paperWidth(), c.paperHeight() composerMap = QgsComposerMap(c, x, y, w, h) c.addItem(composerMap)
Agora, vamos criar um item que receberá nossos textos e irá colocar eles em uma determinada parte da impressão.
Veja que dentro da função setText() devemos inserir o texto que será apresentado e na função setItemPosition() recebe a posição do nosso texto.
# Adiciona texto (label) ao mapa gerado composerLabel = QgsComposerLabel(c) composerLabel.setText("Blog 2 Engenheiros") composerLabel.adjustSizeToText() composerLabel.setItemPosition(100, 0) c.addItem(composerLabel)
Por fim, vamos adicionar agora a legenda do nosso mapa.
# Adiciona legenda ao mapa legend = QgsComposerLegend(c) legend.model().setLayerSet(mapRenderer.layerSet()) legend.setItemPosition(10,10) c.addItem(legend)
Já temos os elementos do nosso mapa no formato de código Python. Podemos também incluir outros itens, tais como escala (QgsComposerScaleBar) e polígonos baseados em pontos (QgsComposerPolygon), mas deixaremos eles de fora, neste tutorial.
Itens como figuras, flechas e tabelas ainda não suportados, ou seja, não podem ser inseridos por meio de python no QGIS (Documentation QGIS 2.18).
Com os itens inseridos, precisamos agora exportar o resultado para PDF ou para PNG.
Exportando mapa no formato PDF
Para exportar o mapa criado, utilize o código abaixo, lembrando de substituir (na função setOutputFileName) o caminho onde será gerado o arquivo pdf.
Neste exemplo, utilizei o mesmo caminho onde foi salvo o arquivo shapefile.
# Exportando o resultado para PDF printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(localSalvo+"_mapa.pdf") printer.setPaperSize(QSizeF(c.paperWidth(), c.paperHeight()), QPrinter.Millimeter) printer.setFullPage(True) printer.setColorMode(QPrinter.Color) printer.setResolution(c.printResolution()) pdfPainter = QPainter(printer) paperRectMM = printer.pageRect(QPrinter.Millimeter) paperRectPixel = printer.pageRect(QPrinter.DevicePixel) c.render(pdfPainter, paperRectPixel, paperRectMM) pdfPainter.end()
Veja que podemos modificar várias opções, tais como tamanho do papel (setPaperSize), se a impressão é na folha toda (setFullPage) e resolução (setResolution).
Exportando o mapa no formato PNG
Agora, se você quer ter o mapa no formato png, você deverá utilizar o código abaixo, ao invés do código previamente apresentado.
# Exportando o mapa para PNG dpi = c.printResolution() dpmm = dpi / 25.4 width = int(dpmm * c.paperWidth()) height = int(dpmm * c.paperHeight()) # Cria uma imagem de saída e inicializa ela image = QImage(QSize(width, height), QImage.Format_ARGB32) image.setDotsPerMeterX(dpmm * 1000) image.setDotsPerMeterY(dpmm * 1000) image.fill(0) # Cria a composição imagePainter = QPainter(image) c.renderPage( imagePainter, 0 ) imagePainter.end() image.save(localSalvo+"_mapa.png", "png")
Caso você tenha seguido os passos corretamente e nenhum erro tenha acontecido, você obterá o seguinte mapa.
A aparência do nosso mapa não é a melhor de todas, por isso, vamos modificar um pouco os códigos que apresentamos para que ele fique mais apresentável, acrescentando também, em qual região de planejamento e bacia hidrográfica o ponto se encontra.
Melhorando a aparência do nosso mapa
A legenda será o primeiro item que iremos melhorar. Confira o código abaixo (as linhas com comentários são aquelas que foram inseridas).
# Adiciona legenda ao mapa legend = QgsComposerLegend(c) legend.model().setLayerSet(mapRenderer.layerSet()) legend.setItemPosition(10,10) legend.setTitle("Legenda: ") # Acrescenta ou modifica o título da legenda legend.setFrameOutlineWidth(0.5) # Modifica tamanho da linha no entorno da legenda legend.setFrameEnabled(1) # Acrescenta linha no entorno da legenda c.addItem(legend)
Com a legenda corrigida, vamos modificar o texto que foi inserido.
Além de aparecer “Blog 2 Engenheiros”, vamos fazer ele mostrar o local onde o ponto inserido pelo usuário caiu (conforme bacia hidrográfica e região de planejamento).
# Adiciona texto (label) ao mapa gerado composerLabel = QgsComposerLabel(c) composerLabel.setText("Blog 2 Engenheiros: ") composerLabel.adjustSizeToText() composerLabel.setItemPosition(c.paperWidth() - 100, c.paperHeight() - 24) c.addItem(composerLabel) # Adiciona texto referente à localização do ponto adicionado regiaoLabel = QgsComposerLabel(c) if self.dlg.checkBoxRP.isChecked(): try: regiaoLabel.setText(pnt_selection[0] + u" esta localizado em " + rp_selection[0]) except: regiaoLabel.setText(u"O ponto fornecido esta fora da área de interesse!!") else: regiaoLabel.setText(u"O item Região de Planejamento não foi selecionado.") regiaoLabel.adjustSizeToText() regiaoLabel.setItemPosition(c.paperWidth() - 100, c.paperHeight() - 19) c.addItem(regiaoLabel) baciaLabel = QgsComposerLabel(c) if self.dlg.checkBoxBH.isChecked(): try: baciaLabel.setText(pnt_selection[0] + " esta na " + bh_selection[0]) except: baciaLabel.setText(u"O ponto fornecido esta fora da área de interesse!!") else: baciaLabel.setText(u"O item Bacias Hidrográficas não foi selecionado.") baciaLabel.adjustSizeToText() baciaLabel.setItemPosition(c.paperWidth() - 100, c.paperHeight() - 14) c.addItem(baciaLabel)
Agora vamos adicionar uma grade de coordenadas e uma borda ao nosso mapa, lembrando que devemos modificar, para isso, a posição que o nosso mapa foi inserido.
# Adicionando e definindo onde o mapa será inserido na folha x, y = 25, 25 # Variáveis que mostram a origem do nosso mapa na folha de impressão w, h = c.paperWidth() - 50, c.paperHeight() - 50 # Variáveis mostrando o tamanho do nosso mapa composerMap = QgsComposerMap(c, x, y, w, h) composerMap.setFrameEnabled(1) # Liga a borda do nosso mapa composerMap.setGridEnabled(True) # Liga a grade de coordenadas composerMap.setGridIntervalX(20000) # Determina o intervalo da grade no eixo X composerMap.setGridIntervalY(20000) # Determina o intervalo da grade no eixo X composerMap.setShowGridAnnotation(True) # Mostra os valores das coordenadas #composerMap.setGridAnnotationPrecision(0) # Precisão das coordenadas (Zero = não há casas decimais) (Por alguma razão, essa função não funciona). composerMap.setGridStyle(QgsComposerMap.Cross) # Estilo da Grade # Determina a posição e direção das coordenadas no topo do mapa composerMap.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame, QgsComposerMap.Top) composerMap.setGridAnnotationDirection(QgsComposerMap.Horizontal, QgsComposerMap.Top) # Desabilita coordenadas na parte inferior do mapa composerMap.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Bottom) # Desabilita coordenadas na esquerda do mapa composerMap.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Left) # Determina a posição e direção das coordenadas na direita do mapa composerMap.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame, QgsComposerMap.Right) composerMap.setGridAnnotationDirection(QgsComposerMap.Vertical, QgsComposerMap.Right) #composerMap.setAnnotationFrameDistance(1) # Distância da coordenada do mapa (Por alguma razão, essa função não funciona). composerMap.setAnnotationFontColor(QColor(0, 0, 0)) # Cor da coordenada c.addItem(composerMap)
O resultado das nossas modificação é apresentado na figura abaixo.
Lembre-se de, antes de utilizar o plugin, determinar corretamente o sistema de coordenadas, ajustar a legenda e as cores do seu mapa, para que, ao utilizar o plugin, o mapa final sai corretamente.
Você pode baixar o arquivo python clicando em ponto_exato_final.
Confira o vídeo (aqui) que realizamos mostrando como o plugin funciona (aproveite e se inscreva no nosso canal do Youtube) e se você quer conferir as postagens anteriores deste plugin, confira os links abaixo:
- Parte 01: Como criar os arquivos de base do seu plugin e solicitar coordenadas para o usuário;
- Parte 02: Salve o shapefile de ponto e crie checkbox para avaliar a localização do ponto inserido.
Ficou com alguma dúvida? Deixa ela nos comentários que iremos responder assim que possível.
Referências Consultadas: Documentation QGIS 2.18: https://docs.qgis.org/2.18/en/docs/pyqgis_developer_cookbook/composer.html GIS StackExchange “Setting an item position (variable) from LowerRight?”: https://gis.stackexchange.com/questions/206150/setting-an-item-position-variable-from-lowerright GIS StackExchange “How can I add grid lines to a print composition using pyqgis?”: https://gis.stackexchange.com/questions/85724/how-can-i-add-grid-lines-to-a-print-composition-using-pyqgis