2

I seem to be encountering an issue where iface.mapCanvas().refresh() (as well as iface.mapCanvas().refreshAllLayers()) does not refresh the map canvas while a script is running, except under very specific conditions.

I am attempting to create and modify some vector layers, then save an image of the canvas during script operation. I have a script set to save the image once the map canvas has finished refreshing. To do this, I have employed the iface.mapCanvas().mapCanvasRefreshed.connect(function) signal, and placed my image save within the function. However, this results in an image without the vector layers.

The only way I have found to actually get the image to save with the vector layers included is to have the console open while the script is running and include a print statement within the script to have it print a useless line to the console.

Code is provided below. When print 1 is commented out, the save file becomes blank. What might be causing this type of behavior, and how can I fix it?

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


# Create save file location
outfile = os.path.join(Map_Save_Folder,"roadmap.png")
outPDF = os.path.join(Map_Save_Folder,"roadmap.pdf")

# 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, feat2, feat3 = QgsFeature(), QgsFeature(), 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])

# Load the layers
QgsMapLayerRegistry.instance().addMapLayers([layerP, layerL])

# --------------------- Using Map Composer -----------------
def saveMap():
    mapComp.exportAsPDF(outPDF)
    mapImage.save(outfile,"png")
    iface.mapCanvas().mapCanvasRefreshed.disconnect(saveMap)
    return

layerList = []
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
    layerList.append(layer.id())
print 1

mapCanv = iface.mapCanvas()
mapCanv.setExtent(layerP.extent())

mapRend = mapCanv.mapRenderer()
mapComp = QgsComposition(mapRend)
mapComp.setPaperSize(250,250)
mapComp.setPlotStyle(QgsComposition.Print)

composerMap = QgsComposerMap(mapComp, 0, 0, 250, 250)
composerMap.zoomToExtent(layerP.extent())
mapComp.addItem(composerMap)

mapRend.setLayerSet(layerList)
mapRend.setExtent(layerP.extent())

dpmm = dpmm = mapComp.printResolution() / 25.4
mapImage = QImage(QSize(int(dpmm*250),int(dpmm*250)), 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()
iface.mapCanvas().refresh()
iface.mapCanvas().mapCanvasRefreshed.connect(saveMap)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.