在KD-Tree中读取Z维度

时间:2016-12-02 06:43:41

标签: python coordinates geospatial data-mining kdtree

关于如何最好地编写一个程序来分析多个表以获得地理坐标中的相似性,我已经玩了几个月。我现在已经尝试了从嵌套的for循环到当前使用KD-Tree的所有东西,它看起来效果很好。但是,在我的第三维读取时,我不确定它是否正常工作,在这种情况下被定义为Z.

import numpy
from scipy import spatial
import math as ma

def d(a,b):
d = ma.acos(ma.sin(ma.radians(a[1]))*ma.sin(ma.radians(b[1]))
            +ma.cos(ma.radians(a[1]))*ma.cos(ma.radians(b[1]))*(ma.cos(ma.radians((a[0]-b[0])))))
return d

filename1 = "A"
pos1 = numpy.genfromtxt(filename1,
                 skip_header=1,
                 usecols=(1, 2))
z1 = numpy.genfromtxt(filename1,
                 skip_header=1,
                 usecols=(3))
filename2 = "B"
pos2 = numpy.genfromtxt(filename2,
                 #skip_header=1,
                 usecols=(0, 1))
z2 = numpy.genfromtxt(filename2,
                 #skip_header=1,
                 usecols=(2))

filename1 = "A"
data1 = numpy.genfromtxt(filename1,
                 skip_header=1)
                 #usecols=(0, 1))
filename2 = "B"
data2 = numpy.genfromtxt(filename2,
                  skip_header=1)
                  #usecols=(0, 1)
tree1 = spatial.KDTree(pos1)

match = tree1.query(pos2)
#print match
indices_pos1, indices_pos2 = [], []
for idx_pos1 in range(len(pos1)):
    # find indices in pos2 that match this position (idx_pos1)
    matching_indices_pos2 = numpy.where(match[1]==idx_pos1)[0]

    for idx_pos2 in matching_indices_pos2:
        # distance in sph coo
        distance = d(pos1[idx_pos1], pos2[idx_pos2])

        if distance < 0.01 and z1[idx_pos1]-z2[idx_pos2] > 0.001:
            print pos1[idx_pos1], pos2[idx_pos2], z1[idx_pos1], z2[idx_pos2], distance

如您所见,我首先将(x,y)位置计算为以球坐标测量的单个单位。 file1中的每个元素都与file2中的每个元素进行比较。问题出在Z维度的某个地方,但我似乎无法解决这个问题。打印结果时,Z坐标通常不会彼此靠近。似乎我的程序完全忽略了和声明。下面我从我的数据中发布了一系列结果,显示了z值实际上相距很远的问题。

[ 358.98787832   -3.87297365] [ 358.98667162   -3.82408566] 0.694282 0.5310796 0.000853515096105
[ 358.98787832   -3.87297365] [ 359.00303872   -3.8962745 ] 0.694282 0.5132215 0.000484847441066
[ 358.98787832   -3.87297365] [ 358.99624509   -3.84617685] 0.694282 0.5128636 0.000489860962243
[ 359.0065807    -8.81507801] [ 358.99226267   -8.8451829 ] 0.6865379 0.6675241 0.000580562641945
[ 359.0292886     9.31398903] [ 358.99296163    9.28436493] 0.68445694 0.45485374 0.000811677349685

输出结构如何构成:[position1(x,y)] [position2(x,y)] [Z1] [Z2]距离

正如你所看到的,特别是在最后一个例子中,Z坐标的大约是.23,这超过了我在上面输入的.001限制。

您可以分享的任何见解都会非常精彩!

1 个答案:

答案 0 :(得分:0)

至于您的原始问题, sign 有一个简单的问题。您测试的是z1-z2 > 0.001,但您可能需要abs(z1-z2) < 0.001(请注意<而不是>。)

您可以让树也考虑z坐标,然后您需要将数据作为(x,y,z)而不仅仅是(x,y)。 如果它不知道z值,则无法使用它。

应该可以(尽管sklearn API可能不允许这样)直接查询树的窗口,您可以在其中独立地绑定坐标范围和z范围。想想一个在x,y,z中有不同扩展名的盒子。但由于z将具有不同的值范围,因此难以组合这些不同的比例。

请注意k-d-tree不了解球面坐标。 +180度的点和-180度的一个点 - 或者一个在0和一个在360-是k-d树非常远,但非常接近球面距离。所以它会遗漏一些观点!