Sto tentando di scrivere una sceneggiatura che salverà un rendering di più livelli usando il compositore di mappe. Il problema che sto riscontrando è che lo script salva prima che qgis abbia terminato il rendering di tutti i livelli.
Sulla base di diverse altre risposte ( 1 , 2 , 3 ), ho tentato di utilizzare iface.mapCanvas.mapCanvasRefreshed.connect()
e inserire il salvataggio dell'immagine all'interno di una funzione, ma sto ancora riscontrando lo stesso problema: le immagini non includono tutti i livelli.
Il codice che sto usando, così come le immagini di come appaiono la finestra principale e i rendering sono elencati di seguito.
Ho notato che se ho la finestra della console aperta e decommenta le tre print layerList
righe, il programma attenderà il completamento del rendering prima di salvare le immagini. Non sono sicuro se ciò sia dovuto al tempo di elaborazione aumentato o se sta cambiando il modo in cui il programma viene eseguito.
Come posso implementarlo correttamente in modo che tutti i livelli siano inclusi nell'immagine?
from qgis.core import *
from qgis.utils import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import os.path
##StackExchange Version=name
##Map_Save_Folder=folder
##Map_Save_Name=string roadmap
# Create save file location
mapName = "%s.png" %Map_Save_Name
outfile = os.path.join(Map_Save_Folder,mapName)
pdfName = "%s.pdf" %Map_Save_Name
outPDF = os.path.join(Map_Save_Folder,pdfName)
# Create point and line layers for later
URIstrP = "Point?crs=EPSG:3035"
layerP = QgsVectorLayer(URIstrP,"pointsPath","memory")
provP = layerP.dataProvider()
URIstrL = "LineString?crs=EPSG:3035"
layerL = QgsVectorLayer(URIstrL,"linePath","memory")
provL = layerL.dataProvider()
# Add points to point layer
feat1 = QgsFeature()
feat2 = QgsFeature()
feat3 = QgsFeature()
feat1.setGeometry(QgsGeometry.fromPoint(QgsPoint(5200000,2600000)))
feat2.setGeometry(QgsGeometry.fromPoint(QgsPoint(5300000,2800000)))
provP.addFeatures([feat1, feat2])
# Add line to line layer
feat3.setGeometry(QgsGeometry.fromPolyline([feat1.geometry().asPoint(),feat2.geometry().asPoint()]))
provL.addFeatures([feat3])
# Set symbology for line layer
symReg = QgsSymbolLayerV2Registry.instance()
metaRegL = symReg.symbolLayerMetadata("SimpleLine")
symLayL = QgsSymbolV2.defaultSymbol(layerL.geometryType())
metaL = metaRegL.createSymbolLayer({'width':'1','color':'0,0,0'})
symLayL.deleteSymbolLayer(0)
symLayL.appendSymbolLayer(metaL)
symRendL = QgsSingleSymbolRendererV2(symLayL)
layerL.setRendererV2(symRendL)
# Set symbology for point layer
metaRegP = symReg.symbolLayerMetadata("SimpleMarker")
symLayP = QgsSymbolV2.defaultSymbol(layerP.geometryType())
metaP = metaRegP.createSymbolLayer({'size':'3','color':'0,0,0'})
symLayP.deleteSymbolLayer(0)
symLayP.appendSymbolLayer(metaP)
symRendP = QgsSingleSymbolRendererV2(symLayP)
layerP.setRendererV2(symRendP)
# Load the layers
QgsMapLayerRegistry.instance().addMapLayer(layerP)
QgsMapLayerRegistry.instance().addMapLayer(layerL)
iface.mapCanvas().refresh()
# --------------------- Using Map Composer -----------------
def custFunc():
mapComp.exportAsPDF(outPDF)
mapImage.save(outfile,"png")
mapCanv.mapCanvasRefreshed.disconnect(custFunc)
return
layerList = []
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
layerList.append(layer.id())
#print layerList
#print layerList
#print layerList
mapCanv = iface.mapCanvas()
bound = layerP.extent()
bound.scale(1.25)
mapCanv.setExtent(bound)
mapRend = mapCanv.mapRenderer()
mapComp = QgsComposition(mapRend)
mapComp.setPaperSize(250,250)
mapComp.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = mapComp.paperWidth(), mapComp.paperHeight()
composerMap = QgsComposerMap(mapComp, x, y, w, h)
composerMap.zoomToExtent(bound)
mapComp.addItem(composerMap)
#mapComp.exportAsPDF(outPDF)
mapRend.setLayerSet(layerList)
mapRend.setExtent(bound)
dpmm = dpmm = mapComp.printResolution() / 25.4
mapImage = QImage(QSize(int(dpmm*w),int(dpmm*h)), QImage.Format_ARGB32)
mapImage.setDotsPerMeterX(dpmm * 1000)
mapImage.setDotsPerMeterY(dpmm * 1000)
mapPaint = QPainter()
mapPaint.begin(mapImage)
mapRend.render(mapPaint)
mapComp.renderPage(mapPaint,0)
mapPaint.end()
mapCanv.mapCanvasRefreshed.connect(custFunc)
#mapImage.save(outfile,"png")
Come appare nella finestra principale di QGIS (c'è una mappa raster casuale su cui viene visualizzata):
Come ulteriore informazione, sto usando QGIS 2.18.7 su Windows 7
mapCanv.mapCanvasRefreshed.connect(custFunc)
con mapCanv.renderComplete.connect(custFunc)
?
layerP .commitChanges()
). Anche se non vedo il motivo per cui dovrebbe essere utile poiché stai solo salvando l'immagine, ma vale la pena provare. Altrimenti si spera che altri possano consigliare :)
commitChanges()
, ma senza fortuna, sfortunatamente. Grazie per il suggerimento