Django-我怎样才能找到两个地点之间的距离?

2024-09-26 18:00:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我在我的Django应用程序中注册了一些用户,我只想根据他们的邮政编码计算出两个用户在地理位置上的距离,然后根据它们对列表进行排序。我想这个功能并没有内置到Django中。我在寻找一些选择,无意中发现了吉德扬戈,这似乎是对我的需要是过分的杀伤力。


Tags: django用户功能应用程序距离列表排序地理位置
3条回答

根据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

问题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计算距离。

相关问题 更多 >

    热门问题