如何在独立脚本中使用Map Composer?


9

我正在尝试遵循pyqgis食谱中的地图渲染部分,但是我想将其作为独立的应用程序进行测试。我可以使用简单的渲染来完成第一部分,但使用地图编辑器作为独立脚本来完成第二个示例时,我会有些卡住。

这是我可以做的一个独立示例:

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

QgsApplication.setPrefixPath("/usr/", True)
QgsApplication.initQgis()

fh = open("eg.csv","w")
fh.write("""
x,y,name
153.0278, -27.4679, Brisbane
144.2500, -23.4500, Longreach
145.7753, -16.9256, Cairns
""")
fh.close()

uri = "eg.csv?delimiter=%s&xField=%s&yField=%s" % (",", "x", "y")
layer = QgsVectorLayer(uri, "eglayer", "delimitedtext")
QgsMapLayerRegistry.instance().addMapLayer(layer)
img = QImage(QSize(800,600), QImage.Format_ARGB32_Premultiplied)
color = QColor(255,255,255)
img.fill(color.rgb())
p = QPainter()
p.begin(img)
render = QgsMapRenderer()
lst = [ layer.getLayerID() ]  # add ID of every layer
render.setLayerSet(lst)
rect = QgsRectangle(render.fullExtent())
rect.scale(1.1)
render.setExtent(rect)
render.setOutputSize(img.size(), img.logicalDpiX())
render.render(p)
p.end()
img.save("render.png","png")

我真正想做的是相同的,但是使用QgsComposition,另存为pdf。食谱说:

在独立应用程序中使用composer时,可以按照上一节中所示的方式创建自己的地图渲染器实例,并将其传递给合成。

这一点我做不到,我的所有尝试都得到了一个空的映射或一个段错误。我正在使用qgis 1.8.0运行linux mint 13。如果有人可以向我展示如何将简单示例修改为使用作曲家的示例,那将是很好的。

Answers:


8

根据评论,此答案适用于之前的版本。2.4
供以后参考,这是一个有效的独立示例。

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

QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()
app = QgsApplication([], True)

fh = open("eg.csv","w")
fh.write("""
x,y,name
153.0278, -27.4679, Brisbane
144.2500, -23.4500, Longreach
145.7753, -16.9256, Cairns
""")
fh.close()

uri = "eg.csv?delimiter=%s&xField=%s&yField=%s" % (",", "x", "y")
layer = QgsVectorLayer(uri, "eglayer", "delimitedtext")
print layer.isValid()
layerset = []
QgsMapLayerRegistry.instance().addMapLayer(layer)
layerset.append(layer.getLayerID())

myMapRenderer = QgsMapRenderer()
myMapRenderer.setLayerSet(layerset)
mapRectangle = QgsRectangle(140,-28,155,-15)
myMapRenderer.setExtent(mapRectangle)

comp = QgsComposition(myMapRenderer)
comp.setPlotStyle(QgsComposition.Print)
composerMap = QgsComposerMap(comp, 5,5,200,200)
composerMap.setNewExtent(mapRectangle)
comp.addItem(composerMap)
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("out.pdf")
printer.setPaperSize(QSizeF(comp.paperWidth(), comp.paperHeight()),    QPrinter.Millimeter)
printer.setFullPage(True)
printer.setColorMode(QPrinter.Color)
printer.setResolution(comp.printResolution())

pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
comp.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()
app.exitQgis()

当我这样做时,我得到一个pdf,但是它是空白的。我正在使用2.10(我必须将.getLayerID()更改为.id())
Conley Owens

是的,对不起,它也不再对我有用。可以在1.8.0上运行,但我只是在2.4.0上进行过测试,似乎不再起作用。
rjad

添加composerMap.setNewExtent(mapRectangle)似乎可以使其正常工作。
rjad

不幸的是,这在2.8.3上不再起作用。我将getLayerID()更改为.id(),但仍然只得到一个空白页。渲染静态文本等有效。关于可能是什么问题的任何想法?
chriserik '16

QgsMapRenderer在2.4以上版本中已弃用,请根据同一示例查看此答案,该示例应适用gis.stackexchange.com/a/223127/36886
raphael

3

QgsMapRenderer在2.4及更高版本中已弃用,我已将此答案中已弃用的部分更新为应该从2.4到起作用的部分2.18.2

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

QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()
app = QgsApplication([], True)

fh = open("eg.csv","w")
fh.write("""
x,y,name
153.0278, -27.4679, Brisbane
144.2500, -23.4500, Longreach
145.7753, -16.9256, Cairns
""")
fh.close()

uri = "eg.csv?delimiter=%s&xField=%s&yField=%s" % (",", "x", "y")
layer = QgsVectorLayer(uri, "eglayer", "delimitedtext")
print layer.isValid()
layerset = []
QgsMapLayerRegistry.instance().addMapLayer(layer)
layerset.append(layer.getLayerID())

def create_composition(layer_list, extent):
#New code for versions 2.4 and above
    ms = QgsMapSettings()
    ms.setLayers(layer_list)
    ms.setExtent(extent)
    comp = QgsComposition(ms)
    return comp, ms

comp, ms = create_composition(layerset, QgsRectangle(140,-28,155,-15))

comp.setPlotStyle(QgsComposition.Print)
composerMap = QgsComposerMap(comp, 5,5,200,200)

#Uses mapsettings value
composerMap.setNewExtent(ms.extent())

comp.addItem(composerMap)
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("out.pdf")
printer.setPaperSize(QSizeF(comp.paperWidth(), comp.paperHeight()),    QPrinter.Millimeter)
printer.setFullPage(True)
printer.setColorMode(QPrinter.Color)
printer.setResolution(comp.printResolution())

pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
comp.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()
app.exitQgis()

layer.getLayerID()无效,必须更改为:layer.id()
Che同志

@ Mr.Che请提供您的操作系统和版本QGIS
拉斐尔

Win 7和QGIS版本:i.stack.imgur.com/8u8Ed.png
Che同志

2

尽管它不是一个独立的应用程序,但是以下代码可能会有所帮助:

from qgis.core import *
from qgis.utils import iface
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import os   
# Clear map canvas
QgsMapLayerRegistry.instance().removeAllMapLayers()
iface.mapCanvas().refresh()
# Open QGIS project
QgsProject.instance().setFileName('composerimage_demo.qgs')
QgsProject.instance().read()
# Set up composition
mapRenderer = iface.mapCanvas().mapRenderer()
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
# Set dimensions and resolution
c.setPaperSize(160,185)
dpi = c.printResolution()
dpmm = (dpi / 25.4)
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())
# Add map to composition
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x,y,w,h)
composerMap.setFrame(True) # Does not work with QGIS 1.9-Master. Use hasFrame() instead.
c.addItem(composerMap)
# 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 composition
imagePainter = QPainter(image)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)
c.render(imagePainter, targetArea, sourceArea)
imagePainter.end()
# Save image to disk (other extensions possible)
image.save('composerimage_demo.jpg')
# Clear map canvas
QgsMapLayerRegistry.instance().removeAllMapLayers()
iface.mapCanvas().refresh()

该地图基于QGIS项目。您可以在此处找到完整的示例:http : //www.qgis.nl/media/2013/08/composerimage_demo.zip


谢谢,但是我的问题是,我不知道如何在QgsComposition不调用的情况下传递有效的mapRenderer对象iface.mapCanvas().mapRenderer()
rjad
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.