Lưu chế độ xem của nhà soạn nhạc In / Bản đồ QGIS dưới dạng PNG / PDF bằng Python (mà không thay đổi bất cứ điều gì trong bố cục có thể nhìn thấy)?


11

Tôi có một chế độ xem / soạn thảo của QGIS được mở với tất cả các yếu tố được điều chỉnh theo ý muốn. Bây giờ tôi cần in / lưu / xuất tệp này dưới dạng tệp PNG hoặc PDF từ bảng điều khiển Python / tập lệnh Python.

Tôi không muốn thay đổi bất cứ điều gì trong bố trí hiện tại. Hầu hết các ví dụ mà tôi tìm thấy (ví dụ: này ), thay đổi vị trí hoặc kích thước bản đồ trong tệp PDF đầu ra so với những gì tôi thấy trong chế độ xem của nhà soạn nhạc hiện tại. Tôi muốn nhận được kết quả chính xác như tôi sẽ nhận được khi nhấp vào In -> Xuất dưới dạng hình ảnh .

Làm thế nào tôi có thể làm điều đó? Atlas không phải là một giải pháp cho tôi.

Câu trả lời:


7

Tôi khuyên bạn nên sử dụng tập lệnh sau của Tim Sutton làm cơ sở, nó hoạt động tốt với tôi: - http://kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines- của trăn /

Chỉ cần chuyển một lệnh trống cho hàm comp.loadFromTemplate () thay vì 'bản đồ thay thế' mà anh ta sử dụng, vì bạn không quan tâm đến chức năng đó.

Ngoài ra, vì bạn đã hỏi về "xuất dưới dạng hình ảnh" thay vì "xuất dưới dạng PDF", bạn phải thực hiện công việc nhiều hơn một chút so với sử dụng hàm thành viên exportAsPDF ().

Dưới đây là phiên bản sửa đổi của mã Tim nên thực hiện thủ thuật, hoạt động từ tập lệnh Python bên ngoài. Đặt các biến tệp DPI và dự án + trình soạn thảo theo yêu cầu.

.

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

Tôi quan tâm đến việc sử dụng mã của bạn. Tuy nhiên, tôi đang nhận được một bản đồ trống ... tôi đã đăng câu hỏi về nó ở đây nếu bạn có bất kỳ ý tưởng nào: gis.stackexchange.com/questions/216376/ Lỗi
user25976

Tôi cũng thích sử dụng cái này. Tôi nghĩ rằng tôi khá thân thiết, nhưng tôi nhận được 'AttributionError:' Đối tượng QssComposerItem 'không có thuộc tính' setMapCanvas '' Tôi không biết phải đi đâu từ đó.
jamierob

Làm thế nào tôi có thể tìm thấy mã trong liên kết trong câu trả lời này? Tôi đã thử trên hai trình duyệt khác nhau và dường như không thể tìm thấy "ví dụ" mà bài viết đề cập đếnpython generate_pdf.py
raphael

3

Bạn có thể tự lập trình hoặc sử dụng lại một phương thức từ Maps Printerplugin. Tôi sẽ mô tả tùy chọn thứ hai vì nó đơn giản hơn.

Bạn cần Maps Printercài đặt plugin, mở dự án QGIS với trình soạn thảo được định cấu hình của bạn, mở bảng điều khiển Python của QGIS và chạy đoạn mã này (bạn sẽ cần điều chỉnh nó với các cài đặt của riêng bạn trong Your settingsphần).

# 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

Sau khi chạy nó, bạn sẽ kết thúc với một tập tin mới /path/to/export_folder/my composer.png. Bạn cũng có thể sử dụng '.pdf'làm phần mở rộng để xuất trình soạn thảo dưới dạng PDF.


3

Có lẽ cũng nên xem câu trả lời khác của tôi khi các công cụ cập nhật mới hơn đã xuất hiện kể từ câu hỏi này.


Tôi đã đến với mã dưới đây rất tiếc là không đầy đủ chức năng. Điều này dựa trên giải pháp trên và dựa trên các câu hỏi khác:

Làm thế nào để lập trình xuất một tác phẩm như hình ảnh?
Làm cách nào tôi có thể đọc các cài đặt cho QssPaperItem từ XML?
Lưu Map Canvas dưới dạng PNG với nền trong suốt theo chương trình với QGIS?

Mã của tôi có thể trích xuất .qpt từ tệp .qss và tải thành công một trình soạn thảo từ mẫu. Nó cũng in một trình soạn thảo thành tệp .png và hiển thị chính xác các nhãn và hình dạng được lưu trữ trong trình soạn thảo.

Tuy nhiên, nó không tải được tất cả các yếu tố liên quan đến Bản đồ & Lớp thực tế (nhãn chứa biểu thức từ lớp này cũng không được vẽ). Tôi nghĩ rằng tôi đã bỏ lỡ một chút về cách dự án phải được tải và liên kết với nhà soạn nhạc.

Một số người trong bình luận của bài viết gốc từ Tim Sutton đã đề cập rằng họ bị kẹt ở cùng một giai đoạn trong Windows (đó là trường hợp của tôi). Điều này thực sự gây bực bội vì tôi cảm thấy câu trả lời thực sự rất gần. Kính gửi Internet xin giúp đỡ!

Ngoài ra đây là lần thử đầu tiên của tôi tại python nên tôi hy vọng bạn sẽ tử tế;)

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



Tôi đã bỏ các dòng này từ mã trước đó vì chúng dường như không làm gì cả. Họ sinh ra không có lỗi nhưng không làm gì tốt hơn.

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

và các mục cũng bị xóa vì chúng dường như không cần thiết khi sử dụng 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()

Tôi vừa thiết lập một máy ảo với Unbfox 14.04 và mã này hoạt động như một làn gió. Vì vậy, vấn đề được liên kết với phiên bản Windows của PyQgis (đã được thử nghiệm trên Window10 với cài đặt Osgeo4w64), tôi sẽ xem xét nếu một vé đã được mở trong trình theo dõi lỗi.
MarHoff

1

Một tùy chọn cập nhật khác sẽ là xem xét 2 bộ công cụ được phát triển bởi cộng đồng QGIS. Vì Map-sprinter được hỗ trợ tích cực, bạn nên mong đợi rằng các tập lệnh sẽ được cập nhật với các phiên bản sắp tới của QGIS.

Cả hai công cụ đều cung cấp GUI nhưng các tập lệnh cơ bản được viết bằng Python

Xuất các nhà soạn nhạc thành các tệp - https://github.com/DelazJ/MapsPrinter
Xuất các nhà soạn nhạc từ nhiều dự án - https://github.com/gacarrillor/QGIS-Resource

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.