Как загрузить вывод памяти при обработке QGIS?

11

Многие алгоритмы обработки имеют возможность сохранить вывод в виде памяти. Если запустить из панели инструментов, это работает нормально, потому что вы можете поставить галочку «Открыть выходной файл после запуска алгоритма».

Глядя на исходный код QGIS, кажется, что код для загрузки слоя памяти определен в функции Postprocessing.handleAlgorithmResults. Функция использует доступ к alg.outputsсписку и выполняет следующие действия:

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

Когда вы запускаете алгоритмы обработки из консоли, есть ли способ загрузить слой без доступа к этому объекту? Я могу бегать

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

или даже

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

Однако я не могу найти способ получить результат.

Oystein
источник

Ответы:

15

Аааа а я нашел. Используйте processing.runandload, который загружает выходной слой в оглавление после запуска алгоритма.

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
источник
1
Я заинтригован ответом, который вы нашли. Знаете ли вы, есть ли аналогичные способы создания слоя памяти и возможности доступа к нему без использования runandload? Я надеюсь сделать некоторую постобработку на выходе обработки перед добавлением его на холст - и подумал, возможно ли это вообще ...
Katalpa
1
Я не мог найти один в то время, не сказать, что это невозможно ... Я думаю, вы могли бы загрузить его и спрятать, если это поможет.
Ойстейн
Если вы не можете найти название слоя, QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]попробуйте это:QgsMapLayerRegistry.instance().mapLayers()
Товарищ Че
@Katalpa, вы можете попробовать, processing.runalg ("qgis: intersection", layer1, layer2, 'out.shp')
драма
4

это правильный путь, это объясняется в документации http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

следующий код работает с в памяти все, кроме последнего, что он загружен

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

processing.runalgвозвращает словарь в данном случае bu['OUTPUT']. OUTPUTЯВЛЯЕТСЯ КЛЮЧОМ, а значение - временным путем. Вы можете увидеть ключ с processseing.alghelp («обработка имени») в качестве обработки, alghelp («grass: r.drain»)

возвращение

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>

в этом случае ключ выводится , будьте осторожны с заглавными буквами, которые вы должны написать заглавными или без заглавных букв, в данном случае не заглавными.

corting
источник
Пожалуйста, избегайте повторяющихся ответов ( gis.stackexchange.com/a/211730/8104 ), следуя политике Stack Exchange. Более подробная информация: meta.stackexchange.com/q/104227
Аарон
Это был тот, который в конечном итоге работал для меня. Ключевой информацией, которая отсутствовала в другом месте, было то, что вы можете передать output['OUTPUT']путь QgsVectorLayerс помощью provider_nameof "ogr". Это будет читать по пути .shp и создаст слой в памяти. Этот подход не добавляет слой в реестр, поэтому он не мигает на панели слоев.
Ник К9
Согласно странице справочника, на которую вы ссылаетесь: «Метод runalg возвращает словарь с именами выходных данных (показанными в описании алгоритма) в качестве ключей и путями к файлам этих выходных данных в качестве значений». Таким образом, этот подход, похоже, не использует слои памяти - все промежуточные результаты будут сохранены в файловой системе.
Håvard Tveite
0

Я не уверен, поможет ли это вам в вашем контексте (хотите ли вы запустить свой код как автономный или в QGIS после завершения алгоритма обработки?). Если это последнее, вы можете легко запросить загруженные QGsVector-и QGsRasterlayerобъекты, заглянув в реестр 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

В общем случае все слои должны иметь источник где-то на жестком диске, даже если результат просто добавляется после того, как обработчик завершает свои вычисления. Если вы посмотрите на метаданные слоев, вы сможете найти фактический источник слоя (если он возник в результате обработки, обычно где-то во временной папке).

кроншнеп
источник
Спасибо за ваш ответ. Я думаю, что уже есть getLayersByNameфункция для реестра карт, но я хочу запустить алгоритм из консоли самостоятельно, так что это не очень поможет (слой памяти никогда не загружается в реестр, вот что я пытаюсь сделать) , Но вы говорите, что нет никакого преимущества в использовании вывода памяти по сравнению с передачей Noneи генерацией временного файла? Вы уверены, что?
Ойстейн
Noneпросто передается, если слой не может быть найден в реестре. Он не создает временный файл, и вам все равно нужно проверять его вручную. Я использую эту функцию для запроса загруженных слоев в QGIS. Не могу помочь вам снаружи в консоли.
Керлью
Я думаю, вы не поняли, я говорил о передаче Noneв processing.runalgкачестве выходного параметра, который, я считаю, создает временный выходной файл.
Ойстейн
К вашему сведению: Только что снова наткнулся на функцию QgsMapLayerRegistry, она называетсяmapLayersByName
Oystein