Cargue programáticamente el compositor desde la plantilla y genere atlas usando PyQGIS

10

Estoy tratando de construir un complemento para cargar un compositor de impresión desde un archivo, generar un atlas y exportarlo a la imagen. Hasta ahora he tenido éxito al cargar la plantilla y exportarla a la imagen.

No he podido agregar ninguna de las capas de la leyenda (que también están en el toc) al mapa exportado, lo que da como resultado un mapa en blanco y ninguna de las expresiones de campo funciona.

    # Get layers in the legend and append, must be a cleaner way to do this?
    layers = self.iface.legendInterface().layers()
    layerStringList = []
    for layer in layers:
        layerID = layer.id()
        layerStringList.append(layerID)

    # Add layer to map render
    myMapRenderer = QgsMapRenderer()
    myMapRenderer.setLayerSet(layerStringList)
    myMapRenderer.setProjectionsEnabled(False)

    # Load template
    myComposition = QgsComposition(myMapRenderer)
    myFile = os.path.join(os.path.dirname(__file__), 'MMR_Template.qpt')
    myTemplateFile = file(myFile, 'rt')
    myTemplateContent = myTemplateFile.read()
    myTemplateFile.close()
    myDocument = QDomDocument()
    myDocument.setContent(myTemplateContent)
    myComposition.loadFromTemplate(myDocument)

    # Save image
    myImagePath = os.path.join(os.path.dirname(__file__), 'come_on.png')
    myImage = myComposition.printPageAsRaster(0)
    myImage.save(myImagePath)

Aquí hay un fragmento de la plantilla cargada que debe configurar el atlas:

 <Atlas hideCoverage="false" featureFilter="reference = '61922'"    coverageLayer="desktop_search20130615160118593" fixedScale="true" composerMap="0" singleFile="false" filenamePattern="&quot;reference&quot;" enabled="true" filterFeatures="true" sortFeatures="true" sortKey="0" sortAscending="true" margin="1"/>

Tampoco estoy seguro de la mejor manera de agregar toda la capa en el toc a la instancia de QgsMapRenderer ().

Gracias

Mate
fuente

Respuestas:

18

Si alguien está interesado aquí es el código con el que terminé. Esto activará / desactivará capas específicas en la tabla de contenido (de una lista de capas), cargará una plantilla de compositor seleccionada del archivo, generará un atlas y exportará el mapa. Finalmente, devolviendo la tabla de contenido a su estado original.

def sort_toc(self):

    # Turn on/off layers as required by search type
    legend = self.iface.legendInterface()
    layers = legend.layers()
    wanted_layers = metal_wanted
    global turn_on, turn_off, atlas_desktop
    turn_off = []
    turn_on = []
    all_layers = []
    for layer in layers:
        layername = layer.name()
        all_layers.append(layername)
        layerid = layer.id()
        if layername == "desktop_search":
            atlas_desktop = layer
        if layername in wanted_layers and legend.isLayerVisible(layer) is False:
            turn_off.append(layer)
            legend.setLayerVisible(layer, True)
        if layername not in wanted_layers and legend.isLayerVisible(layer) is True:
            turn_on.append(layer)
            legend.setLayerVisible(layer, False)
        else:
            pass

    # Checks for required layers missing from map file
    for layer in wanted_layers:
        missing = []
        if layer not in all_layers:
            missing.append(layer)
        else:
            pass
    if not missing:
        pass
    else:
        QMessageBox.warning(self.iface.mainWindow(), "Missing layers", "Required layers are missing from your map file. Details: %s" % (str(missing)))
    return atlas_desktop

def quick_export(self, ref, stype, scale):

    # Add all layers in map canvas to render
    myMapRenderer = self.iface.mapCanvas().mapRenderer()

    # Load template from file
    myComposition = QgsComposition(myMapRenderer)
    myFile = os.path.join(os.path.dirname(__file__), 'MMR_Template.qpt')
    myTemplateFile = file(myFile, 'rt')
    myTemplateContent = myTemplateFile.read()
    myTemplateFile.close()
    myDocument = QDomDocument()
    myDocument.setContent(myTemplateContent)
    myComposition.loadFromTemplate(myDocument)

    # Get map composition and define scale
    myAtlasMap = myComposition.getComposerMapById(0)
    myAtlasMap.setNewScale(int(scale))

    # Setup Atlas
    myAtlas = QgsAtlasComposition(myComposition)
    myAtlas.setCoverageLayer(atlas_desktop) # Atlas run from desktop_search
    myAtlas.setComposerMap(myAtlasMap)
    myAtlas.setFixedScale(True)
    myAtlas.fixedScale()
    myAtlas.setHideCoverage(False)
    myAtlas.setFilterFeatures(True)
    myAtlas.setFeatureFilter("reference = '%s'" % (str(ref)))
    myAtlas.setFilterFeatures(True)

    # Generate atlas
    myAtlas.beginRender()
    for i in range(0, myAtlas.numFeatures()):
        myAtlas.prepareForFeature( i )
        jobs = r"\\MSUKSERVER\BusinessMan Docs\Jobs"
        job_fol = os.path.join(jobs, str(ref))
        output_jpeg = os.path.join(job_fol, ref + "_BMS_plan.jpg")
        myImage = myComposition.printPageAsRaster(0)
        myImage.save(output_jpeg)
    myAtlas.endRender()

def return_toc(self):

    # Revert layers back to pre-script state (on/off)
    legend = self.iface.legendInterface()
    for wanted in turn_on:
        legend.setLayerVisible(wanted, True)
    for unwanted in turn_off:
        legend.setLayerVisible(unwanted, False)
Mate
fuente
¿Puedes compartir ejemplos de uso para las diferentes funciones que creaste? ¿Está todo esto dentro de la consola QGIS Python?
raphael
@raphael Creé este complemento hace bastante tiempo, pero intentaré encontrar un ejemplo.
Matt
Gracias Matt por compartir esto con nosotros. ¿Es posible obtener un ejemplo de uso para estas funciones? Muchas gracias ! Saludos, Nathan
Nat Lebo
2

Quizás esto pueda funcionar en usted para obtener todas las capas actuales:

registry = QgsMapLayerRegistry.instance()
layers = registry.mapLayers().values()
akbargumbira
fuente
ah su manera de conseguir todas las capas deben trabajar realmente
akbargumbira