Python 测试从解码多段线返回的元组(float,float)是否相等

Python 测试从解码多段线返回的元组(float,float)是否相等,python,floating-point,tuples,Python,Floating Point,Tuples,当从中返回浮点元组时,我应该如何测试它们的相等性 背景: 我正在使用Google Directions API查找区域内的道路 我的应用程序通常会返回重复的路段,但我希望“清理”这些路段。也就是说,我想知道我什么时候已经有了一个给定的片段 由于道路网络中的每个节点都是由元组(float,float)(纬度/经度对)表示的地理位置,因此这意味着测试浮点元组的相等性 一方面,众所周知,浮点数在相等比较方面是不可靠的。另一方面,当GoogleDirections API两次返回给定的相同位置时,它总

当从中返回浮点元组时,我应该如何测试它们的相等性


背景:

我正在使用Google Directions API查找区域内的道路

我的应用程序通常会返回重复的路段,但我希望“清理”这些路段。也就是说,我想知道我什么时候已经有了一个给定的片段

由于道路网络中的每个节点都是由
元组(float,float)
(纬度/经度对)表示的地理位置,因此这意味着测试浮点元组的相等性

一方面,众所周知,浮点数在相等比较方面是不可靠的。另一方面,当GoogleDirections API两次返回给定的相同位置时,它总是(根据定义,我认为)完全相同,因为它返回包含编码多段线的JSON

更新:

以下是我当前用于解码方向服务返回的多段线的代码(我添加了注释):

def解码多段线(点):
coord_块=[]]
对于点_str中的字符:
值=ord(字符)-63
split_after=not(值&0x20)
值&=0x1F
coord_块[-1]。追加(值)
如果在以下时间之后拆分_:
coord_chunks.append([])
del coord_块[-1]
coords=[]
对于协调块中的协调块:
坐标=0
对于i,枚举中的块(协调块):
坐标|=块>=1
##将整数“移位”为浮点
coord/=100000.0
coords.append(coord)
点数=[]
prev_x=0
上一个y=0
对于x范围内的i(0,len(coords)-1,2):
如果coords[i]==0和coords[i+1]==0:
持续
上一个x+=坐标[i+1]
上一个y+=坐标[i]
#进一步限制十进制精度
点。追加([四舍五入(上一个,6),四舍五入(上一个,6)])
返回点
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
打印解码多段线(“U p~iF~ps”U_ullnqc_mqNvxq`@”)
更新二:

可能对类似应用程序中可能的API升级或更换感兴趣:

MapQuest平台服务使用Google多段线编码格式的一个微小变体。算法的MapQuest平台服务变体允许编码数据的任意精度。编码数据的默认精度为5位(与Google格式相同),但MapQuest行数据的精度通常为6位

请注意,编码过程中使用的精度必须与解码过程中使用的精度相同,否则您的数据将解压缩到与输入数据相差几个数量级的值


你有没有试过用一个解码成十进制而不是浮点的解码器?@IgnacioVazquez Abrams没有,还没有,尽管这个主意看起来很完美!我会研究的,任何额外的提示都是非常受欢迎的!现在谢谢你!转换为字符串并检查相等性,或者设置“足够接近”的阈值。@cammil我考虑过了。当我绘制一组结果时,由最低精度(约1e-5)形成的“网格”清晰可见,因此我可以使用更小的阈值,当然。但我相信,在这种情况下,可能会有更直接、计算成本更低的方法来做同样的事情,所以我将把它作为计划B。@heltonbiker为什么你认为计算成本会更高?浮点加法和比较可能是所有芯片上的单一操作。小数或字符串表示形式将为O(n),除非您创建一个自定义类型,该类型利用字符串和小数的位数相同。您是否尝试过使用解码为
小数的解码器,而不是
浮点
?@IgnacioVazquez Abrams不,还没有,尽管这个想法似乎很完美!我会研究的,任何额外的提示都是非常受欢迎的!现在谢谢你!转换为字符串并检查相等性,或者设置“足够接近”的阈值。@cammil我考虑过了。当我绘制一组结果时,由最低精度(约1e-5)形成的“网格”清晰可见,因此我可以使用更小的阈值,当然。但我相信,在这种情况下,可能会有更直接、计算成本更低的方法来做同样的事情,所以我将把它作为计划B。@heltonbiker为什么你认为计算成本会更高?浮点加法和比较可能是所有芯片上的单一操作。十进制或字符串表示形式将为O(n),除非您创建一个自定义类型,该类型利用了字符串和小数是相同位数的优势。
def decodePolyline(point_str):

    coord_chunks = [[]]

    for char in point_str:

        value = ord(char) - 63

        split_after = not (value & 0x20)
        value &= 0x1F

        coord_chunks[-1].append(value)

        if split_after:
                coord_chunks.append([])

    del coord_chunks[-1]

    coords = []

    for coord_chunk in coord_chunks:
        coord = 0

        for i, chunk in enumerate(coord_chunk):
            coord |= chunk << (i * 5)
            print coord

        if coord & 0x1:
            coord = ~coord
        coord >>= 1

        ## "shifting" an integer to float
        coord /= 100000.0   

        coords.append(coord)

    points = []
    prev_x = 0
    prev_y = 0
    for i in xrange(0, len(coords) - 1, 2):
        if coords[i] == 0 and coords[i + 1] == 0:
            continue

        prev_x += coords[i + 1]
        prev_y += coords[i]

        # further restricting decimal precision
        points.append([round(prev_x, 6), round(prev_y, 6)])

    return points


if __name__ == '__main__':
    print decodePolyline('_p~iF~ps|U_ulLnnqC_mqNvxq`@')