Python을 사용하여 인쇄 / 맵 QGIS composer보기를 PNG / PDF로 저장합니까 (표시되는 레이아웃에서 아무것도 변경하지 않고)?


11

QGIS composer / print view를 열고 원하는대로 모든 요소를 ​​조정했습니다. 이제 이것을 Python 콘솔 / Python 스크립트에서 PNG 또는 PDF 파일로 인쇄 / 저장 / 내 보내야합니다.

현재 레이아웃에서 아무것도 변경하고 싶지 않습니다. 내가 찾은 대부분의 예 (예 : this )는 현재 작곡가보기에서 보는 것과 비교하여 출력 PDF에서지도 위치 또는 크기를 변경합니다. 인쇄-> 이미지로 내보내기를 클릭했을 때와 동일한 결과를 얻고 싶습니다 .

어떻게해야합니까? Atlas는 나를위한 해결책이 아닙니다.

답변:


7

Tim Sutton의 다음 스크립트를 기본으로 사용하는 것이 좋습니다 .- http://kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines- 파이썬

해당 기능에 관심이 없기 때문에 그가 사용하는 '대체 맵'대신 composition.loadFromTemplate () 함수에 빈 dict를 전달하십시오.

또한 "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 '속성이 없습니다. 어디에서 갈지에 대한 손실이 있습니다.
jamierob 2018

이 답변의 링크에서 코드를 어떻게 찾을 수 있습니까? 두 개의 다른 브라우저에서 시도했지만 게시물이 참조하는 "예제"를 찾을 수없는 것 같습니다python generate_pdf.py
raphael

3

직접 프로그래밍하거나 Maps Printer플러그인 에서 메소드를 재사용 할 수 있습니다 . 두 번째 옵션이 더 간단하므로 설명하겠습니다.

당신은 있어야합니다 Maps Printer, 플러그인이 설치되어 구성된 작곡가와 함께 QGIS 프로젝트를 열고 QGIS 파이썬 콘솔을 열고이 코드를 (당신이 당신의 자신의 설정을 조정해야 실행 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

어쩌면 이 도구 이후로 최신의 최신 도구가 생겼으므로 다른 대답 을 살펴볼 수도 있습니다 .


불행히도 완전히 작동하지 않는 아래 코드를 보았습니다. 이것은 위의 솔루션과 다른 질문에 근거합니다.

컴포지션을 프로그래밍 방식으로 이미지로 내보내는 방법은 무엇입니까?
XML에서 QgsPaperItem의 설정을 읽으려면 어떻게해야합니까?
QGIS를 사용하여 프로그래밍 방식으로 투명한 배경의 맵 캔버스를 PNG로 저장 하시겠습니까?

내 코드는 .qgs 파일에서 .qpt를 추출하고 템플릿에서 작곡가를 성공적으로로드 할 수 있습니다. 또한 작곡가를 .png 파일로 인쇄하고 작곡가에 저장된 레이블과 모양을 올바르게 표시합니다.

그러나 실제 맵 및 레이어와 관련된 모든 요소를로드하지 못합니다 (레이어의 표현식을 포함하는 레이블도 그려지지 않음). 프로젝트를로드하고 작곡가에게 어떻게 연결 해야하는지에 대해 조금 놓쳤다 고 생각합니다.

Tim Sutton 의 원본 기사 에 대한 일부 사람들은 Windows에서 같은 단계에 갇혀 있다고 언급했습니다 (제 경우입니다). 대답이 정말 가깝다는 느낌이 들기 때문에 정말 실망 스럽습니다. 친애하는 인터넷 도와주세요!

또한 이것은 파이썬에 대한 첫 번째 시도이므로 친절하게되기를 바랍니다.)

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



그들은 아무것도하지 않는 것처럼 보였으므로 이전 코드 에서이 줄을 삭제했습니다. 그들은 오류가 없었지만 더 잘하지 못했습니다.

# 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 (Osgeo4w64 설치로 Window10에서 테스트 됨)와 연결되어 있으므로 티켓이 이미 버그 추적기에 열려 있는지 확인합니다.
MarHoff

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.