Как использовать карту 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 в автономном приложении вы можете создать свой собственный экземпляр средства визуализации карты так же, как показано в разделе выше, и передать его в композицию.

Этот бит я не смог сделать, все мои попытки либо получить пустую карту, либо segfault. Я использую Linux Mint 13, используя qgis 1.8.0. Было бы здорово, если бы кто-нибудь показал мне, как изменить простой пример на тот, который использует композитор.

rjad
источник

Ответы:

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()
rjad
источник
Когда я делаю это, я получаю PDF, но он пуст. Я использую 2.10 (я должен изменить .getLayerID () на .id ())
Конли Оуэнс
Да, извини, у меня это больше не работает. Работает на 1.8.0, но я только что проверил его на 2.4.0 и больше не работает.
rjad
Добавление composerMap.setNewExtent (mapRectangle), кажется, заставляет его работать.
rjad
К сожалению, это не работает на 2.8.3 больше. Я изменил getLayerID () на .id () и до сих пор получаю только пустую страницу. Рендеринг статического текста и т. Д. Работает. Есть идеи, в чем может быть проблема?
chriserik
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()
Товарищ Че
@ Mr.Che пожалуйста включите вашу ОС и QGIS версии
Рафаил
Win 7 и версия QGIS: i.stack.imgur.com/8u8Ed.png
Товарищ Че
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

Ради
источник
Спасибо, но моя проблема в том, что я не знаю, как получить действительный объект mapRenderer для передачи QgsCompositionбез вызова iface.mapCanvas().mapRenderer().
rjad