在QGIS中将多个点对齐到线?


11

我想使用指定的公差或围绕线对象的缓冲区将多点对齐到一条线或一层内的线。请参考附件中的示例草图。

出于本示例的考虑,在图片之前,最接近直线的点在直线的5个地图单位内,而最外面的点则在10个地图单​​位之外。我想使用5个地图单位的公差将最近的点捕捉到最近的线上,以在AFTER图片中获得结果。

在此处输入图片说明


因此,该点在线的横向上必须为0个地图单​​位,但是您是否在乎该点相对于该点的原始位置在线的纵向终点?
乔(Joe)

理想的情况是使用垂直于直线的路径移动点。但是,目的是使用相当小的公差。如果这些点沿直线纵向或横向移动,则不会从理想的垂直位置偏移很多点。
Ed Camden

不确定这是否是最好的方法,但是我能想到的一种方法是编写一些python代码来分析两个数据集并生成一些点坐标。如果这是您想要的,请告诉我,我可以为您提供答案。例如,对于每个点,如果距线的lat绝对值<= 5单位,则横向距离=0。您必须导入gdal库才能将x,y值转换为坐标。看到评论: gis.stackexchange.com/questions/185445/…–

使用PyQGIS,可以生成一个存储层,根据先前考虑的5个地图单位的公差和到该线的垂直路径在其中捕捉点。看我的答案。
xunilk

Answers:


15

在(未发布的)QGIS 3.0版本中,有一个内置工具可以执行此操作。您可以从QGIS网站获取每晚快照,以进行提前测试。

去做这个:

  1. 运行“将几何体捕捉到图层”处理算法
  2. 选择您的点图层作为“输入图层”
  3. 选择线层作为“参考层”
  4. 输入合适的公差(捕捉时移动点的最大距离)
  5. 将行为更改为“首选最近的点”

在此处输入图片说明

结果如下,原始点显示为“ x”,捕捉点显示为绿点。我在这里使用了公差,以便仅捕捉一些输入点。

在此处输入图片说明


这正是我所需要的。不幸的是,我的雇主只安装了QGIS的LTR版本,我们都被禁止下载和安装测试版本。(叹气)我想这是等待的问题。这是标准/内置功能还是插件?
Ed Camden

标准功能依赖于c ++类中的更改-无法将其手动复制到较旧的版本。您可能会尝试在另一台计算机上使用OSGEO4W安装,然后将osgeo4w文件夹复制到USB记忆棒上以在工作站上运行。过去我对这种方法很幸运。
ndawson '17

1
对于旧版本,请查看此插件。 docs.qgis.org/2.14/en/docs/user_manual/plugins/…–
iRfAn

看来该插件不支持点的图层。
Mykola Kozyr

7

这可以通过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个地图单位的公差和到该线的垂直路径在此处捕捉点。

在此处输入图片说明


2

您也可以使用refFunctions插件在字段计算器中执行此操作。您可以使用字段计算器来更新图层几何以及字段。refFunctions为您提供“ geomdistance”函数,以查找给定距离内的最近直线(如果您不希望阈值,则为“ geomnearest”),并返回属性或几何图形,而“ closest_point”函数将找到最接近的直线在给定几何图形上的点。将它们串在一起,以便为您的点层计算新的几何形状:

closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)

可以直接使用捕捉的几何来计算字段,而不是直接更新几何。我存储了多个用于将涵点捕捉到不同流层的几何图形,并且可以根据需要使用的流线轻松地在“字段计算器”中更新点几何图形。

这样做有一些限制,两层都必须使用相同的CRS,如果您拥有100,000点以上,则geomdistance函数会给您一个错误,但是如果您编辑refFunctions插件文件,则可以更改此限制。

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.