如何从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")

但是,我找不到一种方法来获取结果输出。

Answers:


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

1
我对您找到的答案很感兴趣。您是否知道是否存在创建内存层的类似方法,并且无需执行runandload就可以访问它?我希望对处理输出进行一些后期处理,然后再将其添加到画布上-并且想知道是否有可能...
Katalpa

1
当时我找不到一个,不是说这是不可能的……我想您可以加载并隐藏它,如果有帮助的话。
Oystein

如果使用以下方法找不到图层名称,请QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]尝试以下操作:QgsMapLayerRegistry.instance().mapLayers()
Che同志

您可以尝试@ 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是键,值是临时路径。您可以看到带有processeing.alghelp(“ name processing”)处理的密钥,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>

在这种情况下,键为output,请注意必须使用大写字母或大写字母,否则请不要使用大写字母。


请遵循堆栈交换策略避免重复的答案(gis.stackexchange.com/a/211730/8104)。更多详细信息:meta.stackexchange.com/q/104227
亚伦

这是最终为我工作的人。唯一缺少的其他地方的关键信息是,你可以通过output['OUTPUT']路径QgsVectorLayerprovider_name"ogr"。这将在.shp路径中读取并创建一个内存层。这种方法不会将图层添加到注册表中,因此不会在“图层面板”中闪烁。
尼克K9

根据您参考的手册页,“ runalg方法返回一个字典,其中输出名称(算法说明中显示的名称)为键,而这些输出的文件路径为值。” 因此,这种方法似乎不使用存储层-所有中间结果都将存储在文件系统中。
哈瓦德·特维特(HåvardTveite)

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和生成临时文件相比没有任何优势吗?你确定吗?
Oystein

None如果在注册表中找不到该层,则仅通过。它不会创建一个临时文件,您仍然需要手动对其进行检查。我使用此功能查询QGIS中已加载的图层。无法在控制台之外为您提供帮助。
Curlew

我想您误会了,我说的是传递Noneprocessing.runalg作为输出参数,我相信它会创建一个临时输出文件。
Oystein

仅供参考:再次遇到了QgsMapLayerRegistry函数,它被称为mapLayersByName
Oystein,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.