Como carregar a saída de memória do processamento QGIS?

11

Muitos algoritmos de processamento têm uma opção para salvar a saída como memória. Se executado a partir da caixa de ferramentas, isso funciona bem, porque você pode marcar a caixa "Abrir arquivo de saída após executar o algoritmo".

Observando o código fonte do QGIS, o código para carregar a camada de memória parece estar definido na função Postprocessing.handleAlgorithmResults. A função usa o acesso a uma alg.outputslista e faz o seguinte:

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

Quando você executa algoritmos de processamento no console, existe uma maneira de carregar a camada sem acesso a esse objeto? eu posso correr

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

ou mesmo

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

No entanto, não consigo encontrar uma maneira de obter a saída resultante.

Oystein
fonte

Respostas:

15

Aaaand eu encontrei. Use processing.runandload, que carrega a camada de saída no sumário após executar o 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
fonte
11
Estou intrigado com a resposta que você encontrou. Você sabe se existe um meio semelhante de criar uma camada de memória - e poder acessá-la sem implementar a execução e a carga de carga? Espero fazer alguma pós-processamento na saída de processamento antes de adicionar-lo para a tela - e se perguntou se tal é mesmo possível ...
Katalpa
11
Não consegui encontrar um de cada vez, para não dizer que é impossível ... Acho que você pode carregá-lo e escondê-lo, se isso ajudar.
Oystein
Se você não conseguir encontrar o nome da camada, QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]tente o seguinte:QgsMapLayerRegistry.instance().mapLayers()
Mr. Che
@Katalpa você pode tentar, processing.runalg ("qgis: interseção", camada1, camada2, 'out.shp')
drama
4

é o caminho correto, está explicado na documentação http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

o próximo código funciona na memória, exceto o último que é carregado

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

o processing.runalgretorna um dicionário neste caso bu['OUTPUT']. OUTPUTÉ A CHAVE, e o valor é um caminho temporário. Você pode ver a chave com processeing.alghelp ("name processing") como processing, alghelp ("grass: r.drain")

Retorna

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>

neste caso, a chave é emitida , tome cuidado com letras maiúsculas que você deve escrever em maiúsculas ou sem maiúsculas, neste caso não maiúsculas.

corting
fonte
Evite respostas duplicadas ( gis.stackexchange.com/a/211730/8104 ), seguindo a política do Stack Exchange. Mais detalhes: meta.stackexchange.com/q/104227
Aaron
Este foi o que finalmente funcionou para mim. A informação principal que estava faltando em outro lugar era para a qual você pode passar o output['OUTPUT']caminho QgsVectorLayercom um provider_namede "ogr". Isso será lido no caminho .shp e criará uma camada na memória. Essa abordagem não adiciona a camada ao registro e, portanto, não pisca no painel Camadas.
Nick K9
De acordo com a página de manual que você menciona, "O método runalg retorna um dicionário com os nomes de saída (os mostrados na descrição do algoritmo) como chaves e os caminhos de arquivo dessas saídas como valores". Portanto, essa abordagem parece não usar camadas de memória - todos os resultados intermediários serão armazenados no sistema de arquivos.
Håvard Tveite
0

Não tenho certeza se isso o ajudará em seu contexto (você deseja executar seu código como autônomo ou no QGIS após a conclusão de um algoritmo de processamento?). Se for o último, você poderá consultar facilmente objetos QGsVector-e carregados QGsRasterlayer, olhando para o registro do 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

Em geral, todas as camadas devem ter uma fonte em algum lugar no disco rígido, mesmo que o resultado seja adicionado apenas após um alg de processamento concluir seus cálculos. Se você examinar os metadados das camadas, poderá encontrar a fonte real de uma camada (se originada do processamento normalmente estiver em algum lugar de uma pasta temporária)

Maçarico
fonte
Obrigado pela sua resposta. Acho que já existe uma getLayersByNamefunção para o registro do mapa, mas quero executar o algoritmo a partir do console, para que isso realmente não ajude (a camada de memória nunca é carregada no registro, é isso que estou tentando fazer) . Mas você está dizendo que não há vantagem em usar uma saída de memória comparada à passagem Nonee geração de um arquivo temporário? Você tem certeza sobre isso?
Oystein
Noneé passado apenas se a camada não puder ser encontrada no registro. Ele não cria um arquivo temporário e você precisa procurá-lo manualmente de qualquer maneira. Eu uso essa função para consultar camadas carregadas no QGIS. Não posso ajudá-lo fora no console.
Curlew
Eu acho que você entendeu errado, eu estava falando de passar Nonepara processing.runalgcomo o parâmetro de saída, que acredito criar um arquivo de saída temporário.
Oystein
FYI: Apenas me deparei com a função QgsMapLayerRegistry novamente, ele é chamadomapLayersByName
Oystein