匹配不同长度的片段


13

我正在尝试将较小的段与较大的段进行匹配,这些段最可能与以下段相关:相对紧密,相似的方位并且彼此相对。

这是我拥有的数据的典型示例:

段

在这里,我需要将段652与198969匹配,而使711和707不匹配任何内容。

我一直在寻找不同的方法,尤其是Hausdorff距离(基于此处的答案)。我使用PostGIS进行了计算,但结果却很奇怪:例如,我得到的最短距离是在707和198985之间,而652到198969的距离要比到198985的距离大(我可以在需要时添加查询和结果)。

Hausdorff实际上是解决此问题的正确方法吗?还有其他方法吗?我想到了简单地对我提到的参数(距离,方位等)创建一组检查的方法,但是我担心不得不添加一大堆条件来处理边缘情况或诸如阈值之类的事情面对对方。

更新:我发现了一种似乎可以接受的折衷方法:

  • 我首先找到了我要匹配的蓝色部分中10个最接近的黑色部分(使用PostGIS <->运算符),它们相距不到10米。
  • 然后,我通过找到每个黑色片段上蓝色片段末端的最近点来创建一个新片段(使用ST_ClosestPoint),并过滤出长度小于蓝色片段90%的结果(这意味着片段不是面,或者轴承差异大于〜20°)
  • 然后,我得到按距离和Hausdorff距离(如果有)排序的第一个结果。

可能需要做一些微调,但目前看来可以接受。如果我错过了一些边缘情况,仍在寻找其他方法或其他检查来运行。


1
为什么不仅仅使用(蓝色)线段的端点来识别目标(黑色)线段之间的潜在匹配?当两个端点都接近一个公共目标时,就会发生您要查找的段匹配,这是一个简单的查询。此方法处理由于段端点的位置错误而导致的差异,否则可能很难解决:注意,很短的(蓝色)段的精度要比更长的段差得多。
Whuber

1
是的,我实际上正在按照这些思路进行尝试,我将用详细信息更新问题。
Jukurrpa

1
不确定我是否理解正确,但是您是否尝试过为蓝线创建质心,然后检查它们与最近的线之间的距离,从而使距离最短?
西里尔·米哈里琴科

1
嗨,西里尔(Cyril),我不再致力于这个问题,但是问题还在于,根据蓝色片段的方向以及它们“面向”黑色片段的数量来匹配它们。这意味着在这种情况下,即使711非常接近黑色部分
也不

Answers:


1

这是我写的几个函数,可以让您执行所需的操作。检查并查看线是多段线还是线段(如果多段线使线爆炸),然后比较线上第一个点和最后一个点的方位角和倒数,为代码设置可接受的标准,以便为您做出决策。这些是arcpy方法,但可以修改。

从线段ESRI @shape返回方位角

def returnAzimuth(shape):
    point1 = shape.firstPoint
    point2 = shape.lastPoint
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az
    return az

从ESRI点返回逆

def returnInverse(point1,point2):
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    dis = sqrt(dX**2+dY**2)
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az,dis
    return az,dis

将折线分解为线段

def explodePolyline(shape):
    sr = "insert your spatial reference"
    lines=[]
    pnts = shape.getPart(0)
    for x in range(len(pnts)-1):
        array = arcpy.Array()
        point1 = arcpy.Point(pnts.getObject(x).X,pnts.getObject(x).Y,pnts.getObject(x).Z)
        point2 = arcpy.Point(pnts.getObject(x+1).X,pnts.getObject(x+1).Y,pnts.getObject(x+1).Z)
        array.add(point1)
        array.add(point2)
        line = arcpy.Polyline(array,sr,True,True)
        print(line)
        lines.append(line)
    return lines

像这样遍历你的桌子

for shape in Table:
    for shape2 in Table:
         check if shape is polyline:
            if yes, explode and compare returned line segments with shape2
                for seg in returnedlinesegments
                    if seg.firstpoint=shape2.lastpoint and shape.az=shape2.az
                        do stuff.....
            if no, compare shape and shape2
                if shape.firstpoint=shape2.lastpoint and shape.az=shape2.az
                   do stuff.....

这些属性应该在postgis中可用-firstpoint,lastpoint,pointarray我假设上面是esri属性,因为这是我最了解的,但是上面的内容可以很容易地更改为与postgis一起使用。

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.