Comment charger la sortie mémoire du traitement QGIS?

11

De nombreux algorithmes de traitement ont une option pour enregistrer la sortie en mémoire. Si exécuté à partir de la boîte à outils, cela fonctionne très bien, car vous pouvez cocher la case "Ouvrir le fichier de sortie après l'exécution de l'algorithme".

En regardant le code source de QGIS, le code de chargement de la couche mémoire semble être défini dans la fonction Postprocessing.handleAlgorithmResults. La fonction utilise l'accès à une alg.outputsliste et effectue les opérations suivantes:

for out in alg.outputs:
    progress.setPercentage(100 * i / float(len(alg.outputs)))
    if out.hidden or not out.open:
        continue
    if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
        try:
            if out.value.startswith('memory:'):
                layer = out.memoryLayer                                # NOTE!!
                QgsMapLayerRegistry.instance().addMapLayers([layer])   # NOTE!!
            else:
                # ... 

Lorsque vous exécutez des algorithmes de traitement à partir de la console, existe-t-il un moyen de charger la couche sans accéder à cet objet? je peux courir

processing.runalg("qgis:intersection", layer1, layer2, "memory:")

ou même

processing.runalg("qgis:intersection", layer1, layer2, "memory:myLayerName")

Je ne peux cependant pas trouver un moyen de saisir la sortie résultante.

Oystein
la source

Réponses:

15

Aaaand je l'ai trouvé. Utilisez processing.runandload, qui charge la couche de sortie dans la table des matières après l'exécution de l'algorithme.

processing.runandload("qgis:intersection", layer1, layer2, "memory:myLayerName")
layer = QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]
# Should do error checking as well, but this works!!
Oystein
la source
1
Je suis intrigué par la réponse que vous avez trouvée. Savez-vous s'il existe un moyen similaire de créer une couche mémoire - et de pouvoir y accéder sans implémenter runandload? J'espère faire un post-traitement sur la sortie de traitement avant de l'ajouter à la toile - et je me demandais si c'était même possible ...
Katalpa
1
Je n'ai pas pu en trouver un à l'époque, pour ne pas dire que c'est impossible ... Je suppose que vous pourriez le charger et le cacher, si cela vous aide.
Oystein le
Si vous ne trouvez pas le nom du calque en utilisant, QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]essayez ceci:QgsMapLayerRegistry.instance().mapLayers()
Camarade Che
@Katalpa vous pouvez essayer, processing.runalg ("qgis: intersection", layer1, layer2, 'out.shp')
drama
4

c'est la bonne façon, c'est expliqué dans la documentation http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

le prochain code fonctionne avec en mémoire tout sauf le dernier qu'il est chargé

MDT=path/mdt.tif
drain=processing.runalg("grass:r.drain",MDT,"",(pun),False,False,False,"%f,%f,%f,%f"% (xmin, xmax, ymin, ymax),0,-1,0.00100,None)
vect=processing.runalg("grass:r.to.vect",drain['output'],0,False,"%f,%f,%f,%f"% (xmin, xmax, ymin, ymax),0,None)
bu=processing.runalg("qgis:fixeddistancebuffer",vect['output'],Metros_afecta,1,False,None)
buf=bu['OUTPUT']
bufe= QgsVectorLayer(buf,"area", "ogr")
#the last load the layer 
QgsMapLayerRegistry.instance().addMapLayers([bufe])

le processing.runalgretourne un dictionnaire dans ce cas bu['OUTPUT']. OUTPUTEST LA CLÉ, et la valeur est un chemin temporaire. Vous pouvez voir la clé avec processeing.alghelp ("traitement de nom") comme traitement, alghelp ("grass: r.drain")

revenir

processing.alghelp("grass:r.drain")
ALGORITHM: r.drain - Traces a flow through an elevation model on a raster map.
input <ParameterRaster>
coordinate <ParameterString>
vector_points <ParameterMultipleInput>
-c <ParameterBoolean>
-a <ParameterBoolean>
-n <ParameterBoolean>
GRASS_REGION_PARAMETER <ParameterExtent>
GRASS_REGION_CELLSIZE_PARAMETER <ParameterNumber>
GRASS_SNAP_TOLERANCE_PARAMETER <ParameterNumber>
GRASS_MIN_AREA_PARAMETER <ParameterNumber>
output <OutputRaster>

dans ce cas la clé est sortie , attention aux majuscules vous devez écrire en majuscule ou sans majuscule, dans ce cas pas de majuscule.

corting
la source
Veuillez éviter les réponses en double ( gis.stackexchange.com/a/211730/8104 ), conformément à la politique Stack Exchange. Plus de détails: meta.stackexchange.com/q/104227
Aaron
C'est celui qui a finalement fonctionné pour moi. L'information clé qui manquait ailleurs était que vous pouvez passer le output['OUTPUT']chemin à QgsVectorLayeravec un provider_namede "ogr". Cela lira dans le chemin .shp et créera une couche en mémoire. Cette approche n'ajoute pas la couche au registre, elle ne clignote donc pas dans le panneau Calques.
Nick K9
Selon la page de manuel à laquelle vous faites référence, "La méthode runalg renvoie un dictionnaire avec les noms de sortie (ceux indiqués dans la description de l'algorithme) sous forme de clés et les chemins de fichier de ces sorties sous forme de valeurs." Cette approche ne semble donc pas utiliser de couches de mémoire - tous les résultats intermédiaires seront stockés dans le système de fichiers.
Håvard Tveite
0

Je ne sais pas si cela vous aidera dans votre contexte (voulez-vous exécuter votre code de manière autonome ou dans QGIS après la fin d'un algorithme de traitement?). Si c'est le dernier, vous pouvez facilement interroger les objets chargés QGsVector-et QGsRasterlayeren consultant le registre QGIS MapLayer.

# General function to retrieve a layer with a given name
def getLayerByName( layerName ):
  layerMap = QgsMapLayerRegistry.instance().mapLayers()
  for name, layer in layerMap.iteritems():
    if layer.name() == layerName:
        if layer.isValid():
          return layer
        else:
          return None

En général, tous les calques doivent avoir une source quelque part sur le disque dur, même si le résultat est ajouté juste après qu'un alg de traitement ait terminé ses calculs. Si vous examinez les métadonnées des couches, vous pouvez trouver la source réelle d'une couche (si elle provient du traitement, elle est normalement quelque part dans un dossier temporaire)

Courlis
la source
Merci pour votre réponse. Je pense qu'il existe déjà une getLayersByNamefonction pour le registre de carte, mais je veux exécuter l'algorithme moi-même depuis la console, donc cela n'aidera pas vraiment (la couche mémoire n'est jamais chargée dans le registre, c'est ce que j'essaie de faire) . Mais dites-vous qu'il n'y a aucun avantage à utiliser une sortie mémoire par rapport au passage Noneet à la génération d'un fichier temporaire? Êtes-vous sûr de cela?
Oystein
Noneest juste passé si la couche est introuvable dans le registre. Il ne crée pas de fichier temporaire et vous devez quand même le vérifier manuellement. J'utilise cette fonction pour interroger les couches chargées dans QGIS. Je ne peux pas vous aider à l'extérieur dans la console.
Courlis
Je pense que vous avez mal compris, je parlais de passer Noneen processing.runalgtant que paramètre de sortie, ce qui, je crois, crée un fichier de sortie temporaire.
Oystein
FYI: Je viens de rencontrer la fonction QgsMapLayerRegistry à nouveau, elle s'appellemapLayersByName
Oystein