因为地球是球面,所以地球平面间的距离也得根据球面来计算。
连个问题:
- 两经纬度点之间的距离
- 根据一个给定经纬度的点,进行附近若干距离地点查询
# 根据经纬度计算距离
def __distance(lon1, lat1, lon2, lat2): # 经度1,纬度1,经度2,纬度2 (十进制度数)
"""
根据经纬度计算距离
:param lon1: 点1经度
:param lat1: 点1纬度
:param lon2: 点2经度
:param lat2: 点2纬度
:return:distance
"""
# 将十进制度数转化为弧度
lon1, lat1, lon2, lat2 = map(radians, [float(lon1), float(lat1), float(lon2), float(lat2)])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * asin(sqrt(a))
r = 6371.137 # 地球平均半径,单位为公里
return float('%.2f' % (c * r))
需求:已知当前位置,查找附近10km内的所有站点
效果应该是地图上有一个圆形的范围,但是这种思路只想到对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于500米时,认为匹配。这样做确实能够得到结果,但是效率极其低下,因为每条记录都要去循环匹配n条数据,其消耗的时间可想而知。
看到网上有个思路:利用我们想要得到圆的外接正方形,然后拿正方形的经纬度范围去搜索数据库。
# 确定查询经纬度范围
def __get_area(latitude, longitude, dis):
"""
确定查询经纬度范围
:param latitude:中心纬度
:param longitude:中心经度
:param dis:半径
:return:(minlat, maxlat, minlng, maxlng)
"""
r = 6371.137
dlng = 2 * math.asin(math.sin(dis / (2 * r)) / math.cos(latitude * math.pi / 180))
dlng = dlng * 180 / math.pi
dlat = dis / r
dlat = dlat * 180 / math.pi
minlat = latitude - dlat
maxlat = latitude + dlat
minlng = longitude - dlng
maxlng = longitude + dlng
return minlat, maxlat, minlng, maxlng
leason | 博客