1

I'm trying to make a plugin for printing automatically PDF showing 3 different views from a set of layers in the same page. For this I have created a QgsComposition and I have added 3 QgsComposerMap to it. Each QgsComposer has its own zoom, and its own layers enabled or disabled. The code for créate de QgsCompostion and two of the maps is this:

    # crear objeto de la clase QgsComposition
    map_settings = iface.mapCanvas().mapSettings() # Get access to properties used for map rendering
    composer = QgsComposition(map_settings)
    composer.setPlotStyle(QgsComposition.Print) # establece el tipo de impresion (preview, print, postscript)

    # establece dimensiones de papel y resolucion de impresion
    paper_width = 420.0
    paper_height = 297.0
    composer.setPaperSize(paper_width, paper_height)
    composer.setPrintResolution(100)

    # MAPA 1: 

    # intialize the map object
    map_origin_x_mm = 10
    map_origin_y_mm = 21
    map_width_mm = 190
    map_height_mm = 107.0
    composer_map = QgsComposerMap(composer,
                                  map_origin_x_mm,
                                  map_origin_y_mm,
                                  map_width_mm,
                                  map_height_mm)

    composer_map.zoomToExtent(rect)  # Zooms the map so that the specified extent is fully visible within the map item


    # Map 1 settings
    composer_map.setGridAnnotationPrecision(0)
    composer_map.setAnnotationFrameDistance(1)    
    composer_map.setAnnotationFontColor(QColor(0, 0, 0))    
    composer_map.setCrossLength(1.0)   
    composer_map.setGridEnabled(True) 

    grid_interval = 100.0
    composer_map.setGridIntervalX(grid_interval)  
    composer_map.setGridIntervalY(grid_interval) 
    composer_map.setGridPenWidth(0.1) 
    composer_map.setGridFrameWidth(1.5)  
    composer_map.setGridFrameStyle(QgsComposerMap.Zebra) 
    composer_map.setGridFramePenSize(0.2)
    composer_map.setGridPenColor(QColor(0, 176, 246))
    composer_map.setGridBlendMode(QPainter.CompositionMode_DestinationOver)
    composer_map.setShowGridAnnotation(True)  
    composer_map.setGridStyle(QgsComposerMap.Cross) 
    composer_map.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Top)
    composer_map.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame,QgsComposerMap.Bottom)
    composer_map.setGridAnnotationDirection(QgsComposerMap.Horizontal,QgsComposerMap.Bottom)
    composer_map.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame, QgsComposerMap.Left)
    composer_map.setGridAnnotationDirection(QgsComposerMap.Vertical,QgsComposerMap.Left)
    composer_map.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Right)

    composer.addComposerMap(composer_map) 
    iface.mapCanvas().freeze(False)

     #SEGUNDO MAPA: P
     factor_escala_zoom = 2
     iface.mapCanvas().setExtent(rect)
     scale_map_canvas = iface.mapCanvas().scale()
     rect.scale(factor_escala_zoom)
     scale_map_canvas_factor = scale_map_canvas * factor_escala_zoom

     #HERE I HAVE A FUNCTION TO ENABLE/DISABLE THE LAYERS I WANT IN THE MAP
     activarCapas(2)


     iface.mapCanvas().refresh()
     iface.mapCanvas().freeze(True)

     # intialize the map object
     map_origin_x_mm = 215
     map_origin_y_mm = 21
     map_width_mm = 195
     map_height_mm = 234.0
     composer_map_2 = QgsComposerMap(composer,
                          map_origin_x_mm,
                          map_origin_y_mm,
                          map_width_mm,
                          map_height_mm)
     composer_map_2.zoomToExtent(rect)  

     # Create the map grid
     composer_map_2.setGridAnnotationPrecision(0)  
     composer_map_2.setAnnotationFrameDistance(1)  
     composer_map_2.setAnnotationFontColor(QColor(0, 0, 0))  
     composer_map_2.setCrossLength(1.0)  
     composer_map_2.setGridEnabled(True)  

     grid_interval = 500.0
     composer_map_2.setGridIntervalX(grid_interval)  
     composer_map_2.setGridIntervalY(grid_interval)  
     composer_map_2.setGridPenWidth(0.1)  
     composer_map_2.setGridFrameWidth(1.5)  
     composer_map_2.setGridFrameStyle(QgsComposerMap.Zebra)  
     composer_map_2.setGridFramePenSize(0.2)  
     composer_map_2.setGridPenColor(QColor(0, 176, 246))  
     composer_map_2.setGridBlendMode(QPainter.CompositionMode_DestinationOver)  
     composer_map_2.setShowGridAnnotation(True)  
     composer_map_2.setGridStyle(QgsComposerMap.Cross)  

     composer_map_2.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Top)
     composer_map_2.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame, QgsComposerMap.Bottom)
     composer_map_2.setGridAnnotationDirection(QgsComposerMap.Horizontal, QgsComposerMap.Bottom)
     composer_map_2.setGridAnnotationPosition(QgsComposerMap.OutsideMapFrame, QgsComposerMap.Left)
     composer_map_2.setGridAnnotationDirection(QgsComposerMap.Vertical, QgsComposerMap.Left)
     composer_map_2.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Right)

     composer.addComposerMap(composer_map_2)
     #FIN DEL SEGUNDO MAPA

     iface.mapCanvas().freeze(False)

     # **IMPRESION DEL PDf**
    printer = QPrinter() 
    printer.setOutputFormat(QPrinter.PdfFormat) 
    pdf_output_filename = "mapa.pdf"
    path_file_output = "D:/Descargas/mapa.pdf"
    printer.setOutputFileName(path_file_output)
    printer.setPaperSize(QSizeF(composer.paperWidth(),
                                composer.paperHeight()),
                         QPrinter.Millimeter) 
    printer.setFullPage(True) 
    printer.setColorMode(QPrinter.Color)
    printer.setResolution(composer.printResolution()) 
    pdfPainter = QPainter(printer) 
    paperRectMM = printer.pageRect(QPrinter.Millimeter)
    paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
    composer.render(pdfPainter,
                    paperRectPixel,
                    paperRectMM)
    pdfPainter.end() # Ends painting

The composers are working well, the zoom is OK,and I can see in QGIS that the layers are enabled and disabled during the process, but the result I get is the same printing in all the maps. It seems like if the printer only 'remember' the last configuration, instead of each configuration for each map....

Maybe there is a function to print in PDF only a Map, and after that do the others?

I know this can be done in qgis GUI with an atlas and blocking de view, so I tried to use de freeze() function, but still nothing.

1

Finally I solved the problem using setLayerSet(). For each QgsComposerMap I set up a list with the layers I wanted to be visible in each map and I've used setLayerSet() to establish this list in each map.

For make it more clear, the code for one of the maps will be the following:

#Set the layers you want to be visible in the map. 
capasMapa1 = [layer_C.id(),layer_B.id(),layer_A.id(),layer_RGB.id()] 

# Create the QGsComposerMap
composer_map = QgsComposerMap(composer, 
                              map_origin_x_mm,
                              map_origin_y_mm,
                              map_width_mm,
                              map_height_mm)

#SetLayerSet: Select the layers to use in this map.
composer_map.setLayerSet(capasMapa1)
composer_map.setKeepLayerSet(True)

Doing this for all the maps (changing the name of each list of layers and changing the name of each QGsComposerMap), I finally get the correct composition in which I had 3 maps, and different visible layers in each one.

Your Answer

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

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