我想使用指定的公差或围绕线对象的缓冲区将多点对齐到一条线或一层内的线。请参考附件中的示例草图。
出于本示例的考虑,在图片之前,最接近直线的点在直线的5个地图单位内,而最外面的点则在10个地图单位之外。我想使用5个地图单位的公差将最近的点捕捉到最近的线上,以在AFTER图片中获得结果。
我想使用指定的公差或围绕线对象的缓冲区将多点对齐到一条线或一层内的线。请参考附件中的示例草图。
出于本示例的考虑,在图片之前,最接近直线的点在直线的5个地图单位内,而最外面的点则在10个地图单位之外。我想使用5个地图单位的公差将最近的点捕捉到最近的线上,以在AFTER图片中获得结果。
Answers:
在(未发布的)QGIS 3.0版本中,有一个内置工具可以执行此操作。您可以从QGIS网站获取每晚快照,以进行提前测试。
去做这个:
结果如下,原始点显示为“ x”,捕捉点显示为绿点。我在这里使用了公差,以便仅捕捉一些输入点。
这可以通过PyQGIS提供。对于下一种情况:
在QGIS的Python控制台上运行了以下代码,考虑了5个地图单位的公差:
from math import sqrt
registry = QgsMapLayerRegistry.instance()
points = registry.mapLayersByName('points')
line = registry.mapLayersByName('line')
feat_points = [ feat for feat in points[0].getFeatures() ]
feat_line = line[0].getFeatures().next()
new_points = []
for feat in feat_points:
pt = feat.geometry().asPoint()
sqrdist, point, vertex = feat_line.geometry().closestSegmentWithContext(pt)
if sqrt(sqrdist) <= 5:
new_points.append(point)
else:
new_points.append(pt)
epsg = points[0].crs().postgisSrid()
uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
'new_points',
'memory')
prov = mem_layer.dataProvider()
feats = [ QgsFeature() for i in range(len(new_points)) ]
for i, feat in enumerate(feats):
feat.setAttributes([i])
feat.setGeometry(QgsGeometry.fromPoint(new_points[i]))
prov.addFeatures(feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
它产生了一个存储层,根据先前考虑的5个地图单位的公差和到该线的垂直路径在此处捕捉点。
您也可以使用refFunctions插件在字段计算器中执行此操作。您可以使用字段计算器来更新图层几何以及字段。refFunctions为您提供“ geomdistance”函数,以查找给定距离内的最近直线(如果您不希望阈值,则为“ geomnearest”),并返回属性或几何图形,而“ closest_point”函数将找到最接近的直线在给定几何图形上的点。将它们串在一起,以便为您的点层计算新的几何形状:
closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)
可以直接使用捕捉的几何来计算字段,而不是直接更新几何。我存储了多个用于将涵点捕捉到不同流层的几何图形,并且可以根据需要使用的流线轻松地在“字段计算器”中更新点几何图形。
这样做有一些限制,两层都必须使用相同的CRS,如果您拥有100,000点以上,则geomdistance函数会给您一个错误,但是如果您编辑refFunctions插件文件,则可以更改此限制。