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/

0

1 Answer 1

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


7
  • 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 Jul 13, 2022 at 11:52
  • I am new to this. I would really appreciate it if you can detail it, please. @S.Chernyshov 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
    Jul 13, 2022 at 20:27
  • I tried the method you suggested, but I am still getting the same issue. @S.Chernyshov Jul 14, 2022 at 23:15
  • Tried to moidify your code, please check
    – RainForest
    Jul 15, 2022 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.