有没有一种方法可以从多边形图层中选择一个属性,然后使用字段计算器中的“内”将值插入点图层的虚拟字段中?

CASE
 WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END




评论

为什么不为此使用“点采样工具”插件?

因为创建新点或移动现有点时需要动态更新。

您最好对这种交互进行脚本编写,而不要依赖开箱即用的工具。

不幸的是我没有任何脚本编写经验。

@LunarSea我在下面编写了一个示例供您遵循,但是您可能必须对其进行调整以满足您的需求。

#1 楼

安装refFunctions插件后,字段计算器中将提供空间连接。

geomwithin(targetLayer,targetField)


评论


插件比使用自定义脚本简单得多。谢谢!

– jpmc26
17年1月30日在22:55

geomwithin('targetLayer','targetField')。

–拉贾
17年3月13日在8:28

#2 楼

开箱即用的字段计算器不支持跨要素图层的空间连接。但是,如果您看一下NathanW在qgis表达式的函数编辑器上的帖子,您将能够发现我们可以编写自己的数据交互脚本。

以下脚本将允许您表达你在追。它通过迭代多边形层上的所有要素(如果存在空间连接)来工作,然后从指定的列中引用表格数据:

 from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

allfeatures = None
index = QgsSpatialIndex()
indexMade = 0
refLayer = None

@qgsfunction(args="auto", group='Custom')
def spatialJoinLookup(layerName, refColumn, defaultValue, geom, feature, parent):

    if geom is None:
        return defaultValue

    # globals so we don't create the index, refLayer more than once
    global allfeatures
    global index
    global indexMade
    global refLayer

    # Get the reference layer
    if refLayer is None:
        for layer in iface.mapCanvas().layers():
            if layerName == layer.name():
                refLayer = layer
                break
    if refLayer is None:
        raise Exception("Layer [" + layerName + "] not found")

    # Create the index if not exists
    if indexMade == 0:
        index = QgsSpatialIndex()
        allAttrs = layer.pendingAllAttributesList()
        layer.select(allAttrs)
        allfeatures = {feature.id(): feature for (feature) in refLayer.getFeatures()}
        for f in allfeatures.values():
            index.insertFeature(f)
        indexMade = 1

    # Use spatail index to find intersect 
    fid = None
    ids = index.intersects(geom.boundingBox())
    for id in ids:
        fid = id
        break # Only get the first match.
    if fid is not None:
        return allfeatures[fid].attribute(refColumn)

    # Default
    return defaultValue
 


多边形层示例

下面是您可能拥有的多边形层的示例。我还创建了一个相应的点图层,您将在最终图像中看到该图层。



表达用法

注意,如果需要要使用单独的列,必须更改第二个参数以匹配面数据集中的列名。例如,您可以使用“ AreaNumber”列,但必须与字段计算器设置中的列类型匹配。



结果

您会看到,在没有空间连接的情况下已应用了默认列值,而另一个已匹配了正确的数据。请注意,我提供的脚本只会在第一个比赛中加入。如果多边形重叠,则需要创建其他业务逻辑。



评论


非常感谢,您的脚本在第一个“ if”语句中使用“ geom”而不是“ geometry”可以正常工作。以这种方式连接几何体可能非常有用,例如用于在多边形上创建多个标签。

–月球海
15年6月29日在10:01

抱歉,我不知道我怎么想的。希望没有性能问题-我只用了很小的一部分记录就尝试了。

– nagytech
15年6月29日在10:08

QGIS仅具有100多个点要素,因此难以解决性能问题。即使在原始画布中没有显示任何点特征,添加新的点特征也确实很痛苦。否则,放大QGIS时会加快速度。我已经尝试了`CASE WHEN $ scale <10000 THENspaceJoinLookupI('Polygons','AreaName','None',$ geometry)END',但是它不起作用。有什么我可以做来改善性能的吗?

–月球海
15年7月4日在19:15



@LunarSea我已经更新了功能以使用空间索引。它应该合理地更快。

– nagytech
2015年7月6日在10:00

谢谢你的帮助。现在,空间连接的速度要快得多,但不幸的是某些操作无法正常进行。对于同一多边形内的点,我得到的结果不同。

–月球海
2015年7月6日,11:10



#3 楼

可以在具有功能aggregate()的字段计算器中完成此操作。在点图层中,使用如下字段计算器表达式创建新字段:等等),layer是将从值中获取的字段,aggreagate是连接字符串(即使在这种情况下,也必须设置),而expression是根据表达式过滤特征(在这种情况下,层几何与父层的几何相交) 。

有关更多信息,请查看聚合QGIS文档。

对于自动更新,可以使用虚拟字段,也可以在“图层属性”中的“属性表单”设置中将表达式设置为“默认值”(属性表单设置文档)。



评论


应该注意的是,仅从QGIS 3开始才支持空间函数(带有geometry(@parent))。以防万一有人阅读本文仍在使用2.18 ...

– she_weeds
19 Mar 24 '19在8:02

谢谢。奇迹般有效。

–空间思想
19年4月10日在10:01