订购线串方向算法

时间:2013-11-11 17:19:13

标签: python arrays algorithm polyline

我想在python中构建一个算法,在线串集合中翻转线串(坐标数组),表示沿着道路的段,这样我就可以将所有坐标合并到一个坐标上升单调的数组中。

所以我的Segmentcollection看起来像这样:

segmentCollection = [['1,1', '1,3', '2,3'],
                     ['4,3', '2,3'],
                     ['4,3', '7,10', '5,5']]

编辑:结构是2D笛卡尔坐标元组列表的列表(例如,'1,1'是x = 1且y = 1的点,'7,10'是x = 7处的点和y = 10,依此类推)。整个问题是将所有这些列表合并到一个坐标元组列表中,这些坐标元组是在一个方向上跟随道路的意义上排序的...实际上这些是我从道路网络路由服务获得的段,但我只得到段,每个段指向它在数据库中数字化的方式,而不是指向您必须驱动的方向。我想从导航路线中获得一条折线。

所以:   - 我可以假设,所有细分都是正确的顺序   - 我不能假设每个细分的坐标顺序正确   - 因此我也不能假设第一段的第一个坐标是开头   - 而且我也不能假设最后一段的最后一个坐标是结束   - (编辑)即使我知道,我的导航请求的起点和终点位于哪里,这些也不必与这些列表中的一个坐标元组相同,因为它们只需要在路由图附近的某处元件。

算法应迭代每个段,必要时将其翻转,然后将其附加到生成的数组中。对于第一个分段,挑战是找到起点(未连接到下一个分段的点)。然后,所有其他段与一个点连接到订单中的最后一个段(有向图)。

我想知道是否没有某种排序数据结构(排序树或任何东西)就是这样。你能提出一些想法吗?在用循环和数组比较搞乱一段时间之后,我的大脑被淘汰了,我只需要在正确的意义上向正确的方向踢一脚。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,你甚至不需要对事情进行排序。我刚把你的英文文本翻译成Python:

def joinSegments( s ):
    if s[0][0] == s[1][0] or s[0][0] == s[1][-1]:
        s[0].reverse()
    c = s[0][:]
    for x in s[1:]:
        if x[-1] == c[-1]:
            x.reverse()
        c += x
    return c

它仍然包含重复点,但删除它们应该很简单。

答案 1 :(得分:1)

def merge_seg(s):
   index_i = 0
   while index_i+1<len(s):
      index_j=index_i+1
      while index_j<len(s):
         if c[index_i][-1] == c[index_j][0]:
            c[index_i].extend(c[index_j][1:])
            del c[index_j]
         elif c[index_i][-1] == c[index_j][-1]:
            c[index_i].extend(c[index_j].reverse()[1:])
            del c[index_j]
         else:
            index_j+=1
      index_i+=1
   result = []
   s.reverse()
   for seg_index in range(len(s)-1):
      result+=s[seg_index][:-1]#use [:-1] to delete the duplicate items
   result+=s[-1]
   return result

在内部while循环中,s [index_i]的每个连续段都附加到s [index_i] 然后index_i ++直到处理完每个段。 因此很容易证明在这些while循环之后,s [0] [0] == s [1] [ - 1],s [1] [0] == s [2] [ - 1]等。所以只需将列表反转并将它们组合在一起,最后您将得到结果。

注意:这是简单和直接方式,但不是最节省时间

了解更多算法:http://en.wikipedia.org/wiki/Sorting_algorithm

答案 2 :(得分:0)

你说你可以假设所有段都是正确的顺序,这意味着独立于坐标顺序,你的问题基本上是合并排序的数组。

如果没有按照正确的顺序定义片段,则必须翻转片段,但这不会对主算法产生单一影响。

简单地定义此重新排序功能:

def reorder(seg):
    s1 = min(seg)
    e1 = max(seg)
    return (s1, e1)

和这个比较功能

def cmp(seg1, seg2):
    return cmp(reorder(seg1), reorder(seg2))

你已经完成了设置,只需运行一个典型的合并算法:

http://en.wikipedia.org/wiki/Merge_algorithm

如果我不明白你的问题陈述,这是另一个想法:

使用segment tree,这是一个完全用于存储片段的结构:)