2011-01-17 9 views
8

Djangoアプリに登録されているユーザーがいくつかあります。地理的には、郵便番号に基づいて2人のユーザー間の距離を把握し、それに基づいてリストを並べ替えるだけです。私はこの機能がDjangoに組み込まれていないと思います。私はいくつかのオプションを見ていて、ジオジャンゴを遭遇しました。私のニーズが過大であるように思えます。Django - 2つの場所の距離を確認するにはどうすればよいですか?

+0

この目的のために[ActiveStateのレシピ](http://code.activestate.com/recipes/393241-calculating-the-distance-between-zip-codes/)です。 Djangoにはほとんど確実に組み込まれていません。 –

+1

[Zip Code Database Project](http://zips.sourceforge.net/)もご覧ください。リンクされたページ上の距離計算用のPythonコードも提供します。 –

+1

@Sven Marnach - 郵便番号データベースプロジェクトを回答として投稿してください。いいです。 (そして、はい、GeoDjangoはおそらくこのために残虐です。) – tcarobruce

答えて

6

は、ここでの答えとして私の上記のコメントです:

Zip Code Database ProjectはSQLとしてまたはCSVのいずれかとして、米国の郵便番号の緯度と経度のデータベースを持っています。彼らはまた、距離計算(私によって編集されたslighlty)のための次のコードを提供します:結果は法定マイルで与えられることに注意してください。

編集:John Machinによる修正。

+0

結果をテストせずに元のコードをわずかに編集するという誘惑に抵抗したはずです。私の答えを見てください。 –

0

http://code.google.com/apis/maps/documentation/directions/

各地域のルートを設定できます。総距離が与えられます。 APIがJSONを出力しているようです。サーバー側で解答を解析するか、JavaScriptによって距離を計算することができます。 tcarobruceの提案に続き

+0

これは、Google Maps for Businessのお客様(btw)でない限り、Googleの利用規約に違反します。 – Jordan

18

これは@Sven Marnachの(現在受け入れられている)回答に掲載されたコードの大きなコメントです。

私が編集インデント付きジッププロジェクトのウェブサイトからオリジナルのコード、:スヴェンによって投稿

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 

はコード:

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:間違った回答:必要があります2番目の最後の行の 経度差をラジアンに変換してください

問題3:変数名 "距離"は極端な誤称です。 この数量は、実際には、地球の中心から入力点までの2本の線の間の角度のcosです。 "cos_x"に変更

問題4:角度xを度に変換する必要はありません。選択した単位(キロ、NM、または「法定マイル」)で地球の半径によって単に 乗算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を固定した後、これを通常実現される「余弦の球法則」である。 "2つの米国の郵便番号間の距離"のようなアプリケーションでは問題ありません。

警告1:玄関から通りまでの距離が小さいため正確ではないので、2つの点が同じ場合はゼロ以外の距離を与えたり、例外を発生させたりすることができます(cos_x> 1.0)。 ;この状況は特別な場合があります。

警告2:2点が対角線(直線の軌跡が地球の中心を通る)であれば、例外が発生する可能性があります(cos_x < -1.0)。それを心配する人は、acos(cos_x)を実行する前にcos_xを調べることができます。

例:NYCに

SFO(37.676、-122.433)(40.733、-73.917)

calcDist - > 2570.7758043869976
calc_dist - > 5038.599866130089
calc_dist_fixed - > 2570.9028268899356

A米国政府のウェブサイト(http://www.nhc.noaa.gov/gccalc.shtml) - > 2569

このウェブサイト(http://www.timeanddate.com /worldclock/distanceresult.html?p1=179 & P2 = 224)、IはSFOとNYCの座標を持っているから、 - > 2577

+0

@Sven Marnach:コードを見直してください。ちょうど2つの「ラジアン」の出現があり、それぞれが緯度に適用され、経度には適用されません。コードを見直してください。ラジアンは、経度差に一度適用されます。コードをテストして、あなたの奇妙な人生の理由を説明してください。 –

+0

@Sven Marnach:面白いです。私はあなたが私のコードが間違っていたと言ったコメントを見たことを誓うことができました。監査証跡が必要です:-) –

+0

申し訳ありません。コメントは数秒間そこにあったが、私はすぐに間違っていることに気づいた。あなたはその小さな時間枠でページをロードしていたとは思わなかった:) –

0

別の簡単な方法:機能以下

計算後の2つの位置との間の距離を返します郵便番号からの緯度と経度。

lat1,は、最初の位置の緯度と経度です。

lat2,long2は、2番目の場所の緯度と経度です。ここ

from decimal import Decimal 
from math import sin, cos, sqrt, atan2, radians 

def distance(lat1, lat2, long1, long2): 
    r = 6373.0 

    lat1 = radians(lat1) 
    lat2 = radians(lat2) 
    long1 = radians(long1) 
    long2 = radians(long2) 

    d_lat = lat2 - lat1 
    d_long = long2 - long1 

    a = (sin(d_lat/2))**2 + cos(lat1) * cos(lat2) * (sin(d_long/2))**2 
    c = 2 * atan2(sqrt(a), sqrt(1-a)) 

    # distance in miles 
    dis = r * c 

    # distance in KM 
    dis /= 1.609344 

    return dis 
関連する問題