In the code, first I am merging the Cooling_Tower(vector layer) with each raster layer and I want the output as an image, so created a layout, add a map, gave extents and page properties, and exported it as an image.
The issue with the code is, that it's only giving the correct image for the last layer and all the other layers are blank white when exporting it as an image.
Is it possible to refresh the map canvas for every new layer and export it as an image or Is there any other possibility to get a correct image for each layer?
from PyQt5.QtCore import QTimer
fileName = 'D:\\UCC\\exported' # exported is a prefix for the file names
boundaryLayer = QgsProject.instance().mapLayersByName('Cooling_Towers')[0]
QgsProject.instance().layerTreeRoot().findLayer(boundaryLayer.id()).setItemVisibilityChecked(True)
otherLayers = []
for layer in QgsProject.instance().mapLayers().values():
if layer.name().startswith("M_"):
otherLayers.append(layer.name())
count = 0
def prepareMap(): # Arrange layers
for layer in QgsProject.instance().mapLayers().values():
if layer.name().startswith("M_"):
QgsProject.instance().layerTreeRoot().findLayer(layer).setItemVisibilityChecked(False)
for layer in QgsProject.instance().mapLayers().values():
if layer.name().startswith(otherLayers[count]):
QgsProject.instance().layerTreeRoot().findLayer(layer).setItemVisibilityChecked(True)
qgis.utils.iface.setActiveLayer(layer)
qgis.utils.iface.zoomToActiveLayer()
project = QgsProject.instance()
manager = project.layoutManager()
layoutName = 'Layout'
layouts_list = manager.printLayouts()
# remove any duplicate layouts
for layout in layouts_list:
if layout.name() == layoutName:
manager.removeLayout(layout)
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layout.setName(layoutName)
manager.addLayout(layout)
page_size =QgsLayoutSize(5000, 5000, QgsUnitTypes.LayoutPixels)
pc = layout.pageCollection()
page = pc.pages()[0]
page.setPageSize(page_size)
# create map item in the layout
map = QgsLayoutItemMap(layout)
map.setRect(20, 20, 20, 20)
# set the map extent
#ms = QgsMapSettings()
#ms.setLayers([layer, boundaryLayer]) # set layers to be mapped
#rect = QgsRectangle(ms.fullExtent())
rect = QgsRectangle(-8232312.3, 4993694.4, -8231302.8, 4994703.9)
#ms.setExtent(rect)
map.setExtent(rect)
#map.setBackgroundColor(QColor(255, 255, 255, 0))
layout.addLayoutItem(map)
#map.attemptMove(QgsLayoutPoint(0, 0, QgsUnitTypes.LayoutMillimeters))
map.attemptResize(QgsLayoutSize(423.333, 423.333, QgsUnitTypes.LayoutMillimeters))
layout = manager.layoutByName(layoutName)
exporter = QgsLayoutExporter(layout)
fn = 'D:\\layout_export' + str(count) + '.png'
exporter.exportToImage(fn, QgsLayoutExporter.ImageExportSettings())
QTimer.singleShot(5000, exportMap) # Wait a second and export the map
def exportMap(): # Save the map as a PNG
global count # We need this because we'll modify its value
if count < len(otherLayers)-1:
QTimer.singleShot(10000, prepareMap)
count += 1
prepareMap() # Let's start the fun
Reference - Iterating over layers and exporting them as PNG images with PyQGIS in standalone script
https://data.library.virginia.edu/how-to-create-and-export-print-layouts-in-python-for-qgis-3/
1 Answer 1
Try this:
def exportMap(layer, count): # Arrange layers
global boundaryLayer # You have to define this layer
QgsProject.instance().layerTreeRoot().findLayer(layer).setItemVisibilityChecked(True)
qgis.utils.iface.setActiveLayer(layer)
qgis.utils.iface.zoomToActiveLayer()
project = QgsProject.instance()
manager = project.layoutManager()
layoutName = 'Layout'
layouts_list = manager.printLayouts()
# remove any duplicate layouts
for layout in layouts_list:
if layout.name() == layoutName:
manager.removeLayout(layout)
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layout.setName(layoutName)
manager.addLayout(layout)
page_size = QgsLayoutSize(5000, 5000, QgsUnitTypes.LayoutPixels)
pc = layout.pageCollection()
page = pc.pages()[0]
page.setPageSize(page_size)
# create map item in the layout
map = QgsLayoutItemMap(layout)
map.setRect(20, 20, 20, 20)
map.setKeepLayerSet(True)
map.setLayers([layer, boundaryLayer]) # set layers to be mapped
# set the map extent
rect = QgsRectangle(-8232312.3, 4993694.4, -8231302.8, 4994703.9)
map.setExtent(rect)
layout.addLayoutItem(map)
map.attemptResize(QgsLayoutSize(423.333, 423.333, QgsUnitTypes.LayoutMillimeters))
exporter = QgsLayoutExporter(layout)
fn = 'D:\\layout_export' + str(count) + '.png'
exporter.exportToImage(fn, QgsLayoutExporter.ImageExportSettings())
#QTimer.singleShot(5000, exportMap) # Wait a second and export the map
def runExportMap(): # Save the map as a PNG
#global count # We need this because we'll modify its value
count = 1
for layer in QgsProject.instance().mapLayers().values():
if layer.name().startswith("M_"):
exportMap(layer, count)
count += 1
-
Thank you for the response. You said 'List of layers you need, meaning? In my case, the boaundary layer and current layer, how can I put them in the list, they are variables? And at which line I must put the script you suggested? @s-chernyshovkanishka dubey– kanishka dubey2022年07月13日 11:52:29 +00:00Commented Jul 13, 2022 at 11:52
-
I am new to this. I would really appreciate it if you can detail it, please. @S.Chernyshovkanishka dubey– kanishka dubey2022年07月13日 11:53:50 +00:00Commented Jul 13, 2022 at 11:53
-
You already wrote it: #ms.setLayers([layer, boundaryLayer]). Just set layers for map, not for QgsMapSettings: map.setLayers([layer, boundaryLayer])RainForest– RainForest2022年07月13日 20:27:38 +00:00Commented Jul 13, 2022 at 20:27
-
I tried the method you suggested, but I am still getting the same issue. @S.Chernyshovkanishka dubey– kanishka dubey2022年07月14日 23:15:57 +00:00Commented Jul 14, 2022 at 23:15
-
Tried to moidify your code, please checkRainForest– RainForest2022年07月15日 07:00:06 +00:00Commented Jul 15, 2022 at 7:00