Pythonを使用して、印刷/マップQGISコンポーザービューをPNG / PDFとして保存します(表示レイアウトの変更なし)。


11

QGISコンポーザー/印刷ビューを開いて、すべての要素を希望どおりに調整しました。ここで、これをPythonコンソール/ PythonスクリプトからPNGまたはPDFファイルとして印刷/保存/エクスポートする必要があります。

現在のレイアウトで何も変更したくない。私が見つけたほとんどの例(例:this)は、現在の作曲家ビューに表示されているものと比較して、出力PDFのマップの位置またはサイズを変更します。[印刷]-> [ 画像としてエクスポート ]をクリックしたときに得られる結果とまったく同じ結果を受け取りたい。

どうやってやるの?アトラスは私にとって解決策ではありません。

回答:


7

私はそれが私のためによく働いた、ベースとしてティム・サットンによって次のスクリプトを使用してお勧めします- http://kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines- of-python /

あなたがその機能に興味がないので、彼が使用する「置換マップ」の代わりに、composition.loadFromTemplate()関数に空の辞書を渡すだけです。

また、「PDFとしてエクスポート」ではなく「イメージとしてエクスポート」について質問したため、exportAsPDF()メンバー関数を使用するよりも少し作業が必要です。

以下は、外部のPythonスクリプトから動作する、トリックを行うべきTimのコードの修正バージョンです。必要に応じて、DPI、およびproject + composerファイル変数を設定します。

(これを外部スクリプトとしてではなくQGIS内でPythonコンソールを使用している場合、qgis.ifaceを使用して現在のマップキャンバスを取得でき、プロジェクトの読み込みなどのコードをすべて使用する必要はありません)。

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()

あなたのコードの使用に興味があります。:しかし、私は空白のマップを取得しています...私はあなたが任意のアイデアを持っているために起こる場合は、ここでそれについての質問を掲載しましたgis.stackexchange.com/questions/216376/...
user25976

私もこれを使用することに興味があります。私はかなり近いと思いますが、「AttributeError: 'QgsComposerItem'オブジェクトには属性 'setMapCanvas' 'がありません。そこからどこに行くか迷っています。
ジャミエロブ

この回答のリンクでコードを見つけるにはどうすればよいですか?私は2つの異なるブラウザで試してみたとポストは超えを意味し、「例」を見つけることができないようpython generate_pdf.py
ラファエル

3

自分でプログラムするか、Maps Printerプラグインのメソッドを再利用できます。2番目のオプションは簡単なので、説明します。

あなたは持っている必要がありますMaps Printer(あなたが独自の設定でそれを調整する必要があるだろう、プラグインがインストールされ設定済みの作曲でQGISプロジェクトを開き、QGIS Pythonのコンソールを開き、このコードスニペットを実行Your settings節)。

# 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

実行後、に新しいファイルが作成され/path/to/export_folder/my composer.pngます。また'.pdf'、拡張機能として使用して、作曲家をPDFとしてエクスポートすることもできます。


3

また、今回から新しい最新のツールが登場したので、他の回答もご覧ください。


残念ながら、完全に機能していない以下のコードに行きました。これは、上記のソリューションとこれらの他の質問に基づいています。

構成を画像としてプログラムでエクスポートする方法は?
QgsPaperItemの設定をXMLから読み取るにはどうすればよいですか?
QGISを使用してプログラムでMap Canvasを透明な背景を持つPNGとして保存しますか?

私のコードは、.qgsファイルから.qptを抽出し、テンプレートから作曲家を正常にロードできます。また、コンポーザを.pngファイルに印刷し、コンポーザに保存されているラベルと形状を正しく表示します。

ただし、実際のマップとレイヤーに関連するすべての要素の読み込みに失敗します(レイヤーからの式を含むラベルも描画されません)。プロジェクトをロードして作曲家にリンクする方法について少し見逃したと思います。

ティムサットンの元の記事のコメントの一部の人々は、彼らがWindowsで同じ段階で立ち往生していると述べました(私の場合です)。答えが本当に近いと感じているので、これは本当にイライラします。親愛なるインターネットは助けてください!

また、これはPythonでの私の最初の試みですので、あなたが親切になることを願っています;)

#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 : /gis//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()



まったく何もしないように見えたため、以前のコードからこれらの行を削除しました。エラーは発生しませんでしたが、それ以上改善することはありませんでした。

# 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()

また、それらはprintPageAsRaster()を使用する際に不要と思われるため削除されます

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でVMをセットアップしたところ、このコードは簡単に機能します。そのため、問題はWindowsバージョンのPyQgis(Window10でOsgeo4w64インストールでテスト済み)にリンクされているため、バグトラッカーでチケットが既に開かれているかどうかを確認します。
MarHoff

1

もう1つの最新のオプションは、QGISコミュニティによって開発されたこれら2つのツールセットを調べることです。Map-sprinterは積極的にサポートされているため、今後のバージョンのQGISでスクリプトが更新されることを期待する必要があります。

どちらのツールもGUIを提供しますが、基礎となるスクリプトはPythonで記述されています

ファイルへのエクスポート作曲- https://github.com/DelazJ/MapsPrinter
複数のプロジェクトからエクスポート作曲- https://github.com/gacarrillor/QGIS-Resources

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.