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.

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!!

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.


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)


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.