2024-09-26 18:00:23 发布
网友
我在我的Django应用程序中注册了一些用户,我只想根据他们的邮政编码计算出两个用户在地理位置上的距离,然后根据它们对列表进行排序。我想这个功能并没有内置到Django中。我在寻找一些选择,无意中发现了吉德扬戈,这似乎是对我的需要是过分的杀伤力。
根据tcarbuce的建议,以下是我的上述意见:
Zip Code Database Project有一个美国邮政编码纬度和经度的数据库,可以是SQL或CSV。它们还提供以下距离计算代码(slighlty由我编辑):
from math import sin, cos, radians, degrees, acos def calc_dist(lat_a, long_a, lat_b, long_b): lat_a = radians(lat_a) lat_b = radians(lat_b) long_diff = radians(long_a - long_b) distance = (sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(long_diff)) return degrees(acos(distance)) * 69.09
注意,结果以法定英里数表示。
编辑:约翰·梅钦的更正。
这是对@Sven Marnach在(目前接受的)答案中发布的代码的一个很大的评论。
zip项目网站的原始代码,缩进由我编辑:
from math import * def calcDist(lat_A, long_A, lat_B, long_B): distance = (sin(radians(lat_A)) * sin(radians(lat_B)) + cos(radians(lat_A)) * cos(radians(lat_B)) * cos(radians(long_A - long_B))) distance = (degrees(acos(distance))) * 69.09 return distance
Sven发布的代码:
from math import sin, cos, radians, degrees def calc_dist(lat_a, long_a, lat_b, long_b): lat_a = radians(lat_a) lat_b = radians(lat_b) distance = (sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(long_a - long_b)) return degrees(acos(distance)) * 69.09
问题1:不会运行:需要导入acos
acos
问题2:错误答案:需要转换 最后一行弧度的经度差
问题3:变量名“distance”是一个非常错误的名称。 这个量实际上是两条直线夹角的cos 从地球中心到输入点。更改为“cos_x”
问题4:不需要将角度x转换为度。简单地 以选定的单位(公里、海里或“法定英里”)乘以地球半径x
在修复所有这些之后,我们得到:
from math import sin, cos, radians, acos # http://en.wikipedia.org/wiki/Earth_radius # """For Earth, the mean radius is 6,371.009 km (˜3,958.761 mi; ˜3,440.069 nmi)""" EARTH_RADIUS_IN_MILES = 3958.761 def calc_dist_fixed(lat_a, long_a, lat_b, long_b): """all angles in degrees, result in miles""" lat_a = radians(lat_a) lat_b = radians(lat_b) delta_long = radians(long_a - long_b) cos_x = ( sin(lat_a) * sin(lat_b) + cos(lat_a) * cos(lat_b) * cos(delta_long) ) return acos(cos_x) * EARTH_RADIUS_IN_MILES
注意:在解决问题1和2之后,这就是通常实现的“余弦球面定律”。 它适用于“两个美国邮政编码之间的距离”等应用。
警告1:对于从前门到街道这样的小距离,它并不精确,因此如果两点相同,它可以给出非零距离或引发异常(cos_x>;1.0);这种情况可以特殊处理。
注意事项2:如果两点是反方向的(直线路径穿过地球中心),则会引发异常(cos_x<;-1.0)。任何担心这一点的人都可以在做acos(cos)之前检查cos_x。
示例:
SFO(37.676,-122.433)至纽约(40.733,-73.917)
计算列表->;2570.7758043869976 计算距离->;5038.599866130089 计算距离固定->;2570.9028268899356
美国政府网站(http://www.nhc.noaa.gov/gccalc.shtml)->;2569
本网站(http://www.timeanddate.com/worldcock/distanceresult.html?p1=179&p2=224),从中获得SFO和纽约坐标,->;2577
http://code.google.com/apis/maps/documentation/directions/
你可以为每个地点做指示。给出了总距离。API似乎输出JSON;您可以在服务器端解析答案,也可以使用JavaScript计算距离。
根据tcarbuce的建议,以下是我的上述意见:
Zip Code Database Project有一个美国邮政编码纬度和经度的数据库,可以是SQL或CSV。它们还提供以下距离计算代码(slighlty由我编辑):
注意,结果以法定英里数表示。
编辑:约翰·梅钦的更正。
这是对@Sven Marnach在(目前接受的)答案中发布的代码的一个很大的评论。
zip项目网站的原始代码,缩进由我编辑:
Sven发布的代码:
问题1:不会运行:需要导入
acos
问题2:错误答案:需要转换 最后一行弧度的经度差
问题3:变量名“distance”是一个非常错误的名称。 这个量实际上是两条直线夹角的cos 从地球中心到输入点。更改为“cos_x”
问题4:不需要将角度x转换为度。简单地 以选定的单位(公里、海里或“法定英里”)乘以地球半径x
在修复所有这些之后,我们得到:
注意:在解决问题1和2之后,这就是通常实现的“余弦球面定律”。 它适用于“两个美国邮政编码之间的距离”等应用。
警告1:对于从前门到街道这样的小距离,它并不精确,因此如果两点相同,它可以给出非零距离或引发异常(cos_x>;1.0);这种情况可以特殊处理。
注意事项2:如果两点是反方向的(直线路径穿过地球中心),则会引发异常(cos_x<;-1.0)。任何担心这一点的人都可以在做acos(cos)之前检查cos_x。
示例:
SFO(37.676,-122.433)至纽约(40.733,-73.917)
计算列表->;2570.7758043869976
计算距离->;5038.599866130089
计算距离固定->;2570.9028268899356
美国政府网站(http://www.nhc.noaa.gov/gccalc.shtml)->;2569
本网站(http://www.timeanddate.com/worldcock/distanceresult.html?p1=179&p2=224),从中获得SFO和纽约坐标,->;2577
http://code.google.com/apis/maps/documentation/directions/
你可以为每个地点做指示。给出了总距离。API似乎输出JSON;您可以在服务器端解析答案,也可以使用JavaScript计算距离。
相关问题 更多 >
编程相关推荐