Answers:
这不是一个完美的解决方案,但您可以使用“ 几何图形生成器”,该几何图形生成器添加了一条可视化的线来表示相交。然后,您可以将其设置为与原始线要素重叠。
通过单击加号添加新的符号层,然后选择Geometry generator
作为符号层类型。将geoemtry类型设置为LineString / MultiLineString
并使用以下表达式:
intersection($geometry, geometry(get_feature( 'polygonLayer','fieldName','value')))
您需要在以下位置添加有关特定多边形的详细信息:
polygonLayer
是多边形图层的名称fieldName
是字段的名称value
是您特定多边形的要素值请注意,要为视线着色,您可能需要在Draw Effects属性中完成:
这是结果(请注意,可视线未与原始线完全重叠,因此我稍微修改了偏移量):
并且没有多边形:
编辑:
如果要将其应用于与多边形要素相交的每个线要素,请转到函数编辑器并使用以下函数(更改名称polygon example_2
以匹配多边形层的名称):
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def func(feature, parent):
polygon_layer = QgsMapLayerRegistry.instance().mapLayersByName( "polygon example_2" )[0]
feat_list = []
geoms = QgsGeometry.fromWkt('GEOMETRYCOLLECTION()')
for polygon_feat in polygon_layer.getFeatures():
if feature.geometry().intersects(polygon_feat.geometry()):
intersection = feature.geometry().intersection(polygon_feat.geometry())
feat_list.append(intersection)
for x in feat_list:
geoms = geoms.combine(x)
return geoms
单击“ 加载”,然后转到“ 表达式”选项卡并键入func()
。希望结果应如下所示(使用上述相同的样式属性):
get_feature
需要字段名称和值。我只有一个多边形图层,想使用该图层上的所有要素进行遮罩。那可能吗?
Geometry Generator
会func
为图层上用于样式设置的每个要素调用该方法吗?因此,如果我的线层具有3个要素,那么func
被称为3次并绘制相同结果3次?
func
现在仅应按每个线要素调用,并且只会绘制一次结果(似乎是这种情况,如多边形内部的顶点标记所示,然后隐藏在我错过的下方)。感谢您指出:)
扩展约瑟夫的答案,我想出了这个功能。它考虑了不同的坐标系,我需要查找两个遮罩层,因此它也可以处理。此外,我希望能够掩盖多边形内的线或多边形外的线。
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
@qgsfunction(args='auto', group='Custom')
def mask_line_with_polygon(mask_type, line_layer_name, polygon_layer_name_1, polygon_layer_name_2, feature, parent):
line_layer = QgsMapLayerRegistry.instance().mapLayersByName( line_layer_name )[0]
# This is the geometry outside the polygon mask.
outside = QgsGeometry(feature.geometry())
polygon_layer_names = [polygon_layer_name_1, polygon_layer_name_2]
line_feature_extent = outside.boundingBox()
geoms = QgsGeometry.fromWkt('MultiLineString()')
for polygon_layer_name in polygon_layer_names:
if polygon_layer_name is None or len(polygon_layer_name) == 0:
continue
# If the line and the polygon layers have different projections, handle them here.
polygon_layer = QgsMapLayerRegistry.instance().mapLayersByName(polygon_layer_name)[0]
trs = QgsCoordinateTransform(line_layer.crs(), polygon_layer.crs())
polygon_extent = trs.transform(line_feature_extent)
trs = QgsCoordinateTransform(polygon_layer.crs(), line_layer.crs())
# Go through the features in the polygon layer, but only those within the line feature bounding box.
for feature in polygon_layer.getFeatures(QgsFeatureRequest().setFilterRect(polygon_extent)):
polygon_geometry = QgsGeometry(feature.geometry())
# Transform the polygon to line space.
polygon_geometry.transform(trs)
if outside.intersects(polygon_geometry):
if mask_type.lower() == 'outside':
inside = outside.intersection(polygon_geometry)
if inside.isMultipart():
for x in inside.asMultiPolyline():
geoms.addPart(x)
else:
geoms.addPart(inside.asPolyline())
outside = outside.difference(polygon_geometry)
if mask_type.lower() == 'inside':
if outside.isMultipart():
for x in outside.asMultiPolyline():
geoms.addPart(x)
else:
geoms.addPart(outside.asPolyline())
return geoms
这项练习向我展示了QGIS不太喜欢使用大型数据集,并且这种带有QGIS的算法经常崩溃。我怀疑QGIS渲染器不喜欢渲染费时的Geometry Generators。