Baskı / Harita QGIS besteci görünümünü Python kullanarak PNG / PDF olarak kaydetme (görünür düzende hiçbir şey değiştirmeden)?


11

İstediğim gibi ayarlanmış tüm öğelerle bir QGIS besteci / baskı görünümüm var. Şimdi bunu Python konsolu / Python betiğinden bir PNG veya PDF dosyası olarak yazdırmam / kaydetmem / dışa aktarmam gerekiyor.

Geçerli mizanpajdaki hiçbir şeyi değiştirmek istemiyorum. Bulduğum çoğu örnek (örneğin: bu ), çıktı bestecisinde bir harita konumunu veya boyutunu mevcut besteci görünümümde gördüklerime göre değiştirin. Yazdır -> Görüntü Olarak Dışa Aktar'ı tıkladığımda alacağımla aynı sonucu almak istiyorum .

Bunu nasıl yapabilirim? Atlas benim için bir çözüm değil.

Yanıtlar:


7

Ben Tim Sutton tarafından bir baz olarak aşağıdaki komut dosyası kullanmanızı öneririz, benim için iyi çalıştı: - http://kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines- of-piton /

Bu işlevsellikle ilgilenmediğiniz için, kullandığı 'ikame haritası' yerine Composition.loadFromTemplate () işlevine boş bir diksiyon iletin.

Ayrıca, "PDF olarak dışa aktar" yerine "görüntü olarak dışa aktar" ı sorduğunuzdan, exportAsPDF () üye işlevini kullanmaktan biraz daha fazla iş yapmanız gerekir.

Aşağıda, Tim'in kodunun, harici bir Python betiğinden çalışarak hile yapması gereken değiştirilmiş bir sürümü bulunmaktadır. DPI ve project + composer dosya değişkenlerini gerektiği gibi ayarlayın.

(Bunu harici bir komut dosyası olarak yapmak yerine QGIS içinde Python konsolunu kullanıyorsanız, qgis.iface komutunu kullanarak geçerli harita tuvalini alabilirsiniz ve tüm proje yükleme vb. Kodlarını kullanmanıza gerek yoktur).

import sys
from qgis.core import (
    QgsProject, QgsComposition, QgsApplication, QgsProviderRegistry)
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo
from PyQt4.QtXml import QDomDocument

gui_flag = True
app = QgsApplication(sys.argv, gui_flag)

# Make sure QGIS_PREFIX_PATH is set in your env if needed!
app.initQgis()

# Probably you want to tweak this
project_path = 'project.qgs'

# and this
template_path = 'template.qpt'

# Set output DPI
dpi = 300

canvas = QgsMapCanvas()
# Load our project
QgsProject.instance().read(QFileInfo(project_path))
bridge = QgsLayerTreeMapCanvasBridge(
    QgsProject.instance().layerTreeRoot(), canvas)
bridge.setCanvasLayers()

template_file = file(template_path)
template_content = template_file.read()
template_file.close()
document = QDomDocument()
document.setContent(template_content)
ms = canvas.mapSettings())
composition = QgsComposition(ms)
composition.loadFromTemplate(document, {})
# You must set the id in the template
map_item = composition.getComposerItemById('map')
map_item.setMapCanvas(canvas)
map_item.zoomToExtent(canvas.extent())
# You must set the id in the template
legend_item = composition.getComposerItemById('legend')
legend_item.updateLegend()
composition.refreshItems()

dpmm = dpi / 25.4
width = int(dpmm * composition.paperWidth())
height = int(dpmm * composition.paperHeight())

# create output image and initialize it
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(0)

# render the composition
imagePainter = QPainter(image)
composition.renderPage(imagePainter, 0)
imagePainter.end()

image.save("out.png", "png")

QgsProject.instance().clear()
QgsApplication.exitQgis()

Kodunuzu kullanmakla ilgileniyorum. Ancak, boş bir harita alıyorum ... Eğer herhangi bir fikriniz olursa, burada bir soru gönderdim: gis.stackexchange.com/questions/216376/…
user25976 3:16

Bunu da kullanmakla ilgileniyorum. Oldukça yakın olduğumu düşünüyorum, ama 'AttributeError:' QgsComposerItem 'nesnesinin' setMapCanvas 'özniteliği yok, oradan nereye gideceğim konusunda kaybım var.
jamierob

Bu cevaptaki bağlantıda kodu nasıl bulabilirim? İki farklı tarayıcı üzerinde denedim ve yazı ötesinde atıfta "örnek" bulmak gibi görünmüyorpython generate_pdf.py
raphael

3

Kendiniz programlayabilir veya Maps Printereklentiden bir yöntemi yeniden kullanabilirsiniz . İkinci seçeneği açıklayacağım çünkü daha basit.

Sen olmalı Maps Printer, eklentisi yüklü yapılandırılmış besteci ile QGIS projeyi açmak, QGIS Python konsolunu açın ve bu kod parçacığını (eğer kendi ayarları ile ayarlamak gerekir çalıştırmak Your settingsbölüm).

# Your settings
composerTitle = 'my composer' # Name of the composer you want to export
folder = '/path/to/export_folder/'
extension = '.png' # Any extension supported by the plugin

mp = qgis.utils.plugins['MapsPrinter']

for composer in iface.activeComposers():
    title = composer.composerWindow().windowTitle()
    if title == composerTitle:
        mp.exportCompo( composer, folder, title, extension )
        break

Çalıştırdıktan sonra, içinde yeni bir dosya olacak /path/to/export_folder/my composer.png. '.pdf'Besteciyi PDF olarak dışa aktarmak için uzantı olarak da kullanabilirsiniz .


3

Belki de bundan sonra yeni daha güncel araçlar ortaya çıktığı için diğer cevabıma da bir göz atın .


Ne yazık ki tam olarak işlevsel olmayan aşağıdaki koda geldim. Bu, yukarıdaki çözüme ve diğerlerinin sorularına dayanmaktadır:

Bir kompozisyonu programlı olarak resim olarak nasıl dışa aktarabilirim?
QgsPaperItem ayarlarını XML'den nasıl okuyabilirim?
QGIS ile Harita Tuvalini saydam arka planla PNG olarak kaydetme?

Kodum .qpt bir .qgs dosyasından ayıklamak ve başarıyla şablondan bir besteci yükleyebilirsiniz. Ayrıca, bir besteciyi bir .png dosyasına yazdırır ve bestecide saklanan etiketleri ve şekilleri doğru şekilde görüntüler.

Ancak, gerçek Harita ve Katmanlarla ilgili tüm öğeleri yükleyemez (katmandan ifade içeren etiket de çizilmez). Projenin nasıl yüklenip besteciye bağlanması gerektiği konusunda biraz özlediğimi düşünüyorum.

Tim Sutton'ın orijinal makalesinin yorumunda yer alan bazı insanlar, Windows altında aynı aşamada sıkıştıklarını söyledi (benim durumum). Bu gerçekten sinir bozucu çünkü cevabın gerçekten çok yakın olduğunu hissediyorum. Sevgili İnternet lütfen yardım edin!

Ayrıca bu benim python benim ilk denemeleri olduğunu umarım nazik olacak;)

#This python code aim to programmatically export the first composer stored in a qgs file using PyQgis API v 2.10
#Version 0.4 (non functional) WTFPL MarHoff 2015 - This code is mostly a "frankenstein" stub made with a lot of other snippets. Feel welcome to improve!
#Credits to gis.stackexchange community : drnextgis,ndawson,patdevelop,dakcarto,ahoi, underdark & Tim Sutton from kartoza
#More informations and feedback can be found at /gis/144792/

#This script assume your environement is setup for PyGis as a stand-alone script. Some nice hints for windows users : https://gis.stackexchange.com/a/130102/17548

import sys
from PyQt4.QtCore import *
from PyQt4.QtXml import *
from qgis.core import *
from qgis.gui import *

gui_flag = True
app = QgsApplication(sys.argv, gui_flag)

# Make sure QGIS_PREFIX_PATH is set in your env if needed!
app.initQgis()

# Name of the .qgs file without extension
project_name = 'myproject'

#Important : The code is assuming that the .py file is in the same folder as the project
folderPath = QString(sys.path[0])+'/'
projectPath = QString(folderPath+project_name+'.qgs')
templatePath = QString(folderPath+project_name+'_firstcomposer.qpt')
imagePath = QString(folderPath+project_name+'.png')

#Getting project as Qfile and the first composer of the project as a QDomElement from the .qgs
projectAsFile = QFile(projectPath)
projectAsDocument = QDomDocument()
projectAsDocument.setContent(projectAsFile)
composerAsElement = projectAsDocument.elementsByTagName("Composer").at(0).toElement()

#This block store the composer into a template file
templateFile = QFile(templatePath)
templateFile.open(QIODevice.WriteOnly)
out = QTextStream(templateFile)
#I need next line cause UTF-8 is somewhat tricky in my setup, comment out if needed
out.setCodec("UTF-8")
param = QString
composerAsElement.save(out,2)
templateFile.close()

#And this block load back the composer into a QDomDocument
#Nb: This is ugly as hell, i guess there is a way to convert a QDomElement to a QDomDocument but every attemps failed on my side...
composerAsDocument = QDomDocument()
composerAsDocument.setContent(templateFile)

#Now that we got all we can open our project
canvas = QgsMapCanvas()
QgsProject.instance().read(QFileInfo(projectAsFile))
bridge = QgsLayerTreeMapCanvasBridge(
    QgsProject.instance().layerTreeRoot(), canvas)
bridge.setCanvasLayers()


#Lets try load that composer template we just extracted
composition = QgsComposition(canvas.mapSettings())
composition.loadFromTemplate(composerAsDocument, {})


#And lets print in our .png
image = composition.printPageAsRaster(0)
image.save(imagePath,'png')

#Some cleanup maybe?
QgsProject.instance().clear()
QgsApplication.exitQgis()



Hiç bir şey yapmamış gibi görünüyordu tez satırları önceki koddan düştü. Onlar hiçbir hata yumurtladı ama daha iyi yapmadım.

# You must set the id in the template
map_item = composition.getComposerItemById('map')
map_item.setMapCanvas(canvas)
map_item.zoomToExtent(canvas.extent())
# You must set the id in the template
legend_item = composition.getComposerItemById('legend')
legend_item.updateLegend()
composition.refreshItems()

ve printPageAsRaster () kullanılırken gereksiz göründükleri için bunlar da kaldırıldı

dpmm = dpi / 25.4
width = int(dpmm * composition.paperWidth())
height = int(dpmm * composition.paperHeight())    

# create output image and initialize it
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(0)    

# render the composition
imagePainter = QPainter(image)
composition.renderPage(imagePainter, 0)
imagePainter.end()

Unbuntu 14.04 ile bir VM kurdum ve bu kod bir esinti gibi çalışıyor. Bu yüzden sorun PyQgis'in Windows sürümüne bağlı (Osgeo4w64 kurulumu ile Window10'da test edildi), hata izleyicide zaten bir biletin açık olup olmadığına bakacağım.
MarHoff

1

Bir başka daha güncel seçenek, QGIS topluluğu tarafından geliştirilen 2 araç setine bakmak olacaktır. Map-sprinter aktif olarak desteklendiğinden, komut dosyalarının QGIS'in gelecek sürümleriyle güncellenmesini beklemelisiniz.

Her iki araç da bir GUI sağlar ancak temel komut dosyaları Python'a yazılır

Bestecileri dosyalara dışa aktar - https://github.com/DelazJ/MapsPrinter
Birden fazla projeden bestecileri dışa aktar - https://github.com/gacarrillor/QGIS-Resources

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.