¿Cómo cargar la salida de memoria del procesamiento QGIS?

11

Muchos algoritmos de procesamiento tienen una opción para guardar la salida como memoria. Si se ejecutó desde la caja de herramientas, esto funciona bien, porque puede marcar la casilla "Abrir archivo de salida después de ejecutar el algoritmo".

Mirando el código fuente de QGIS, el código para cargar la capa de memoria parece estar definido en la función Postprocessing.handleAlgorithmResults. La función utiliza el acceso a una alg.outputslista y hace lo siguiente:

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:
                # ... 

Cuando ejecuta algoritmos de procesamiento desde la consola, ¿hay alguna forma de cargar la capa sin acceso a este objeto? puedo correr

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

o incluso

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

Sin embargo, no puedo encontrar una manera de obtener el resultado resultante.

Oystein
fuente

Respuestas:

15

Aaa y lo encontré. Use processing.runandload, que carga la capa de salida en la tabla de contenido después de ejecutar el algoritmo.

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
fuente
1
Me intriga la respuesta que encontraste. ¿Sabes si hay un medio similar para crear una capa de memoria y poder acceder a ella sin implementar runandload? Espero hacer algún procesamiento posterior en la salida de procesamiento antes de añadirla a la lona - y se preguntó si tal es incluso posible ...
Katalpa
1
No pude encontrar uno en ese momento, por no decir que es imposible ... Supongo que podrías cargarlo y ocultarlo, si eso ayuda.
Oystein
Si no puede encontrar el nombre de la capa usando QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]intente esto:QgsMapLayerRegistry.instance().mapLayers()
Sr. Che
@Katalpa puedes probar, processing.runalg ("qgis: intersection", layer1, layer2, 'out.shp')
drama
4

es la forma correcta, se explica en la documentación http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

el siguiente código funciona en la memoria todo excepto el último que es carga

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

el processing.runalgdevuelve un diccionario en este caso bu['OUTPUT']. OUTPUTES LA CLAVE, y el valor es un camino temporal. Puede ver la clave con processeing.alghelp ("procesamiento de nombres") como procesamiento, alghelp ("grass: r.drain")

regreso

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>

en este caso la clave es la salida , tenga cuidado con las letras mayúsculas que debe escribir en mayúscula o sin mayúscula, en este caso no mayúscula.

corting
fuente
Evite respuestas duplicadas ( gis.stackexchange.com/a/211730/8104 ), siguiendo la política de Stack Exchange. Más detalles: meta.stackexchange.com/q/104227
Aaron
Este fue el que finalmente funcionó para mí. La información clave que faltaba en otra parte es que puede pasar el output['OUTPUT']camino a QgsVectorLayercon una provider_namede "ogr". Esto se leerá en la ruta .shp y creará una capa en memoria. Este enfoque no agrega la capa al registro, por lo que no parpadea en el Panel de capas.
Nick K9
Según la página del manual a la que hace referencia, "El método runalg devuelve un diccionario con los nombres de salida (los que se muestran en la descripción del algoritmo) como claves y las rutas de archivo de esas salidas como valores". Por lo tanto, este enfoque no parece usar capas de memoria: todos los resultados intermedios se almacenarán en el sistema de archivos.
Håvard Tveite
0

No estoy seguro de si esto lo ayudará en su contexto (¿desea ejecutar su código de forma independiente o dentro de QGIS después de que termine un algoritmo de procesamiento?). Si es lo último, puede consultar fácilmente objetos QGsVector-y QGsRasterlayerobjetos cargados al buscar en el registro 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 general, todas las capas deben tener una fuente en algún lugar del disco duro, incluso si el resultado se acaba de agregar después de que un alg-tratamiento termine sus cálculos. Si observa los metadatos de las capas, puede encontrar la fuente real de una capa (si se origina del procesamiento normalmente está en algún lugar de una carpeta temporal)

Zarapito
fuente
Gracias por su respuesta. Creo que ya hay una getLayersByNamefunción para el registro del mapa, pero quiero ejecutar el algoritmo desde la consola, así que esto realmente no ayudará (la capa de memoria nunca se carga en el registro, eso es lo que estoy tratando de hacer) . ¿Pero estás diciendo que no hay ninguna ventaja en usar una salida de memoria en comparación con pasar Noney generar un archivo temporal? ¿Estás seguro de eso?
Oystein
Nonesolo se pasa si la capa no se puede encontrar en el registro. No crea un archivo temporal y de todos modos debe verificarlo manualmente. Utilizo esta función para consultar capas cargadas dentro de QGIS. No puedo ayudarte afuera en la consola.
Curlew
Creo que entendiste mal, estaba hablando de pasar Nonea processing.runalgcomo el parámetro de salida, que creo que crea un archivo de salida temporal.
Oystein
FYI: Acabo de encontrar la función QgsMapLayerRegistry nuevamente, se llamamapLayersByName
Oystein