KDTree返回了半径之外的点

3
我有一个经纬度坐标的数组,我想使用KDTree和scipy的query_ball_point来返回指定纬度和经度的1英里半径内的所有数据点。
问题是query_ball_point返回的点超出了指定的1英里半径。以下是我的代码:
import pandas as pd
import scipy as sp
import geocoder
import pysal as psl


search_list = df['coordinates'].tolist()
tree = psl.cg.KDTree(search_list, distance_metric='Arc', radius=psl.cg.RADIUS_EARTH_MILES)
latlong = (39.698840000000004, -104.975916)
index = tree.query_ball_point(latlong,r=1)

结果是一个类似以下坐标的数组:
+---------------------------------------+
|              coordinates              |
+---------------------------------------+
| (39.676973877551, -104.966231826172)  |
| (39.6777407534644, -104.988982458831) |
| ...                                   |
+---------------------------------------+

当我尝试使用球面距离公式验证这些结果时,我发现第一个坐标相差1.6英里

from haversine import haversine
haversine((39.676973877551, -104.966231826172),
         (39.698840000000004, -104.975916),miles=True)

1.5961362762187963
2个回答

1

Pysal在计算query_ball_point方法的距离时不使用haversine函数,而是使用pysal.cg.sphere.arcdist函数,两者不同。

import pysal
from pysal.cg.kdtree import KDTree    

locations = [(40.702566, -73.816859),
         (40.70546, -73.810708),
         (40.709179, -73.820574),
         (40.700486, -73.807969),
         (40.694624, -73.820593),
         (40.695132, -73.820841),
         (40.694095, -73.821334),
         (40.694165, -73.822368),
         (40.695077, -73.822817),
         (40.6747769261, -73.8092618174)] 
tree = KDTree(locations, distance_metric='Arc', radius=pysal.cg.RADIUS_EARTH_MILES)
current_point = (40.709523, -73.802472)
# get all points within X miles of 'current_point'
indices = tree.query_ball_point(current_point, 1)
for i in indices:
    print(locations[i])

在1英里范围内有3个点

(40.70546, -73.810708)
(40.700486, -73.807969)
(40.6747769261, -73.8092618174)

并非所有这些点根据haversine公式都在1英里范围内:

from haversine import haversine
for i in indices:
    print(haversine(current_points, locations[i], miles = True))

0.5146716729994124
0.6875825817591269
2.4269297885659022

但是根据pysal的arcdist公式,使用半径为3958.756英里,它们之间的距离在1英里以内:

from pysal.cg.sphere import arcdist
for i in indices:
    print(arcdist(current_points, locations[i], 3958.756))

0.5744128196875283
0.4178272122350164
0.8175408580090955

0

PySAL期望输入为(经度,纬度) (即x,y),而haversine Python包期望输入为(纬度,经度)。否则arcdist和haversine应该返回几乎相同的结果。

from libpysal.cg.sphere import arcdist, RADIUS_EARTH_MILES
from haversine import haversine

locations = [(40.702566, -73.816859),
         (40.70546, -73.810708),
         (40.709179, -73.820574),
         (40.700486, -73.807969),
         (40.694624, -73.820593),
         (40.695132, -73.820841),
         (40.694095, -73.821334),
         (40.694165, -73.822368),
         (40.695077, -73.822817),
         (40.6747769261, -73.8092618174)] 
current_point = (40.709523, -73.802472)

H = [haversine(current_point, loc, unit='mi') for loc in locations]
print(', '.join(["%0.5f"%dist for dist in H]))
A = [arcdist(current_point[::-1], loc[::-1], radius=RADIUS_EARTH_MILES) for loc in locations]
print(', '.join(["%0.5f"%dist for dist in A]))
print(', '.join(['%0.8f'%(h-a) for h,a in zip(H,A)]))

输出:

0.89381, 0.51467, 0.94839, 0.68758, 1.40024, 1.38364, 1.45343, 1.48732, 1.46011, 2.42693
0.89381, 0.51467, 0.94838, 0.68758, 1.40024, 1.38364, 1.45343, 1.48732, 1.46011, 2.42693
0.00000123, 0.00000071, 0.00000131, 0.00000095, 0.00000193, 0.00000191, 0.00000201, 0.00000205, 0.00000202, 0.00000335

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接