Bagaimana cara menggunakan komposer peta dalam skrip yang berdiri sendiri?

9

Saya mencoba mengikuti bagian rendering peta dari buku masak pyqgis, tetapi saya ingin menguji ini sebagai aplikasi mandiri. Saya dapat melakukan bagian pertama, menggunakan rendering sederhana, tapi saya agak terjebak melakukan contoh kedua menggunakan komposer peta sebagai skrip mandiri.

Ini adalah contoh mandiri yang bisa saya lakukan:

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

Apa yang benar-benar ingin saya lakukan adalah sama, tetapi gunakan QgsComposition, dan simpan seperti pdf misalnya. Buku masak itu mengatakan:

Saat menggunakan komposer dalam aplikasi mandiri, Anda dapat membuat instance peta renderer Anda sendiri dengan cara yang sama seperti yang ditunjukkan pada bagian di atas dan meneruskannya ke komposisi.

Bit ini saya tidak bisa lakukan, semua usaha saya mendapatkan peta kosong, atau segfault. Saya menjalankan linux mint 13, menggunakan qgis 1.8.0. Akan lebih bagus jika seseorang dapat menunjukkan kepada saya bagaimana memodifikasi contoh sederhana menjadi contoh yang menggunakan komposer.

rjad
sumber

Jawaban:

8

Berdasarkan komentar, jawaban ini berfungsi untuk versi sebelum2.4
Untuk referensi di masa mendatang, berikut adalah contoh mandiri yang berfungsi.

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
sumber
Ketika saya melakukan ini, saya mendapatkan pdf, tetapi itu kosong. Saya menggunakan 2.10 (saya harus mengubah .getLayerID () menjadi .id ())
Conley Owens
Ya, maaf, itu tidak berfungsi lagi untuk saya juga. Bekerja pada 1.8.0, tapi saya baru mengujinya pada 2.4.0 dan sepertinya tidak lagi berfungsi.
rjad
Menambahkan composerMap.setNewExtent (mapRectangle) tampaknya membuatnya berfungsi.
rjad
Sayangnya, ini tidak berfungsi pada 2.8.3 lagi. Saya mengubah getLayerID () menjadi .id () dan masih hanya mendapatkan halaman kosong. Rendering teks statis dll berfungsi. Adakah gagasan tentang apa masalahnya?
chriserik
QgsMapRenderer sudah usang di dalam 2.4dan di atas, lihat jawaban ini berdasarkan contoh yang sama yang seharusnya berfungsi gis.stackexchange.com/a/223127/36886
raphael
3

QgsMapRenderer sudah ditinggalkan di 2,4 dan di atas, saya telah memperbarui bagian yang dihentikan dari jawaban ini untuk sesuatu yang harus bekerja dari 2.4ke 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()
raphael
sumber
layer.getLayerID()tidak berfungsi dan harus diubah ke:layer.id()
Kamerad Che
@ Mr.Che tolong sertakan versi OS dan QGIS Anda
raphael
Menangkan versi 7 dan QGIS: i.stack.imgur.com/8u8Ed.png
Kamerad Che
2

Mungkin kode ini bermanfaat, meskipun itu bukan aplikasi mandiri:

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

Peta ini didasarkan pada proyek QGIS. Anda dapat menemukan contoh lengkap di sini: http://www.qgis.nl/media/2013/08/composerimage_demo.zip

Demi
sumber
Terima kasih, tetapi masalah saya adalah saya tidak tahu cara mendapatkan objek mapRenderer yang valid untuk dilewati QgsCompositiontanpa menelepon iface.mapCanvas().mapRenderer().
rjad