2

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 Answers1

0

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

RainForest
  • 1,160
  • 5
  • 13
  • 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-chernyshov – kanishka dubey Jul 13 '22 at 11:52
  • I am new to this. I would really appreciate it if you can detail it, please. @S.Chernyshov – kanishka dubey Jul 13 '22 at 11:53
  • You already wrote it: #ms.setLayers([layer, boundaryLayer]). Just set layers for map, not for QgsMapSettings: map.setLayers([layer, boundaryLayer]) – RainForest Jul 13 '22 at 20:27
  • I tried the method you suggested, but I am still getting the same issue. @S.Chernyshov – kanishka dubey Jul 14 '22 at 23:15
  • Tried to moidify your code, please check – RainForest Jul 15 '22 at 07:00
  • Thank you for your time but I am still getting the same issue. I tried your updated code, but the issue I am getting now is, that all the layer's visibility is turned on, so all the layers are getting merged again and giving the blank white images. @S.Chernyshov – kanishka dubey Jul 15 '22 at 21:27
  • Can you open layout 'Layout' after export? Check layout pages, on what page the map is placed, extent and layers of the map. – RainForest Jul 19 '22 at 05:35