Charger par programme le compositeur à partir d'un modèle et générer un atlas à l'aide de PyQGIS


10

J'essaie de créer un plugin pour charger un compositeur d'impression à partir d'un fichier, générer un atlas et exporter vers l'image. Jusqu'à présent, j'ai réussi à charger le modèle et à l'exporter vers l'image.

Je n'ai pas pu ajouter aucune des couches de la légende (qui se trouvent également dans le toc) à la carte exportée, ce qui entraîne une carte vierge et aucune des expressions de champ ne fonctionne.

    # 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)

Voici un extrait du modèle chargé qui devrait configurer l'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"/>

Je ne suis pas sûr non plus de la meilleure façon d'ajouter toute la couche du toc à l'instance de QgsMapRenderer ().

Merci

Réponses:


18

Si quelqu'un est intéressé, voici le code avec lequel je me suis retrouvé. Cela activera / désactivera des couches spécifiques dans la table des matières (à partir d'une liste de couches), chargera un modèle de composeur sélectionné à partir d'un fichier, générera un atlas et exportera la carte. Enfin, le retour de la table des matières à son état d'origine.

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)

Pouvez-vous partager des exemples d'utilisation pour les différentes fonctions que vous avez créées? Est-ce tout cela dans la console QGIS Python?
raphael

@raphael J'ai construit ce plugin il y a longtemps, mais je vais essayer de trouver un exemple.
Matt

Merci Matt d'avoir partagé cela avec nous. Est-il possible d'obtenir un exemple d'utilisation de ces fonctions? Merci beaucoup ! Regards, Nathan
Nat Lebo

2

Cela peut peut-être vous aider à obtenir toutes les couches actuelles:

registry = QgsMapLayerRegistry.instance()
layers = registry.mapLayers().values()

ah votre façon d'obtenir toutes les couches devrait fonctionner réellement
akbargumbira
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.