任意kd树实现的最近点查询
KdQuer的Python项目详细描述
kdquery是一个包,它使用python列表定义了kd树的一个可能实现,以避免递归,最重要的是,它定义了一个通用方法来查找任何kd树实现的最近节点。
开始
先决条件
- 本地安装的Python 3.6版
- PIP在本地安装
安装
该软件包可以通过pip轻松安装:
pip install kdquery
用法
具有默认设置的树类
fromkdqueryimportTree# Create a kd-tree (k = 2 and capacity = 10000 by default)tree=Tree()# Insert points with some attached data (or not)tree.insert((9,1),{'description':'point in the plane','label':6})tree.insert((1,-8))tree.insert((-3,3),data=None)tree.insert((0.2,3.89),["blue","yellow","python"])# Recover the data attached to (0, 3)node_id=tree.insert((0,3),'Important data')node=tree.get_node(node_id)print(node.data)# 'Important data'# Find the node in the tree that is nearest to a given pointquery=(7.2,1.2)node_id,dist=tree.find_nearest_point(query)print(dist)# 1.8110770276274832
具有可选参数的树类
fromkdqueryimportTreex_limits=[-100,100]y_limits=[-10000,250]z_limits=[-1500,10]region=[x_limits,y_limits,z_limits]capacity=3000000# 3d-tree with capacity of 3000000 nodestree=Tree(3,capacity,region)
最近点法
假设您在应用程序中处理地球表面上的某些位置,并且为了存储这些数据,您实现了一个kd树,其中每个节点都表示为具有以下规范的数组元素:
importnumpyasnpnode_dtype=np.dtype([('longitude','float64'),('latitude','float64'),('limit_left','float64'),('limit_right','float64'),('limit_bottom','float64'),('limit_top','float64'),('dimension','float64'),('left','int32'),('right','int32')])
如果给定一个点在地球表面上,你需要找到数据库的最近位置,你可以使用这个包中的最近点方法。您只需要定义一个方法,该方法接收此表示中某个节点的索引,并返回该节点的坐标、该节点所在的区域以及左、右子节点的索引。对于上面提到的实现,它可能类似于:
defget_properties(node_id):node=tree[node_id]horizontal_limits=[node['limit_left'],node['limit_right']]vertical_limits=[node['limit_bottom'],node['limit_top']]# The region of the space definied by the noderegion=[horizontal_limits,vertical_limits]# The position of the point in the spacecoordinates=(node['longitude']),node['latitude']))# The dimension of the space divided by this node# 0 for longitude and 1 for latitude in this casedimension=node['dimension']# If you want this node to be considered# Set to true if this feature is not predicted by your implementationactive=True# Indices to left and right childrenleft,right=node['left'],node['right']returncoordinates,region,dimension,active,left,right
调用方法:
importkdquerydefspherical_dist(point1,point2):<statement-1>...<statement-N>returndistquery=(2.21,48.65)root_id=0# index of the rootnode_id,dist=kdquery.nearest_point(query,root_id,get_properties,spherical_dist)