2009-02-20 46 views

答えて

23

2点(GPXファイルの各ウェイポイントのペア)間の距離を計算する伝統的な方法は、Haversine式です。

私は、アルゴリズムを実装するSQL Server機能を持っています。これは他の言語にも簡単に翻訳できるはずです:

create function dbo.udf_Haversine(@lat1 float, @long1 float, 
        @lat2 float, @long2 float) returns float begin 
    declare @dlon float, @dlat float, @rlat1 float, 
       @rlat2 float, @rlong1 float, @rlong2 float, 
       @a float, @c float, @R float, @d float, @DtoR float 

    select @DtoR = 0.017453293 
    select @R = 3959  -- Earth radius 

    select 
     @rlat1 = @lat1 * @DtoR, 
     @rlong1 = @long1 * @DtoR, 
     @rlat2 = @lat2 * @DtoR, 
     @rlong2 = @long2 * @DtoR 

    select 
     @dlon = @rlong1 - @rlong2, 
     @dlat = @rlat1 - @rlat2 

    select @a = power(sin(@dlat/2), 2) + cos(@rlat1) * 
        cos(@rlat2) * power(sin(@dlon/2), 2) 
    select @c = 2 * atn2(sqrt(@a), sqrt([email protected])) 
    select @d = @R * @c 

    return @d 
end 

これは距離をマイルで返します。キロメートルについては、地球半径をkm相当量に置き換えてください。

Hereは、より詳細な説明です。

編集:この機能は、郵便番号データベースで半径検索を行うのに十分速く、正確です。 this siteについては素晴らしい仕事をしてきました(しかし、今はリンクが壊れているので、これ以上はありません)。

+0

ありがとうございます。私はそれをjavaに移植し、ここに投稿します。 @DtoRとはどういう意味ですか?半径までの距離? – guerda

+1

これは、度をラジアン、π/ 180に変換する要因です。 – cdonner

+0

リンクをありがとう。すぐにJavaバージョンを投稿します – guerda

1

Vincenty formulaeのDelphi実装はhereです。

+0

更新されたリンクがありますか? –

+0

@Adam Carter:URLを確認しても問題ありません。 – menjaraz

1

ここにScalaの実装があります。

3958.761は、マイル単位でmean radius of the Earthです。 km(またはその他の単位)で結果を取得するには、この番号を変更します。

// The Haversine formula 
def haversineDistance(pointA: (Double, Double), pointB: (Double, Double)): Double = { 
    val deltaLat = math.toRadians(pointB._1 - pointA._1) 
    val deltaLong = math.toRadians(pointB._2 - pointA._2) 
    val a = math.pow(math.sin(deltaLat/2), 2) + math.cos(math.toRadians(pointA._1)) * math.cos(math.toRadians(pointB._1)) * math.pow(math.sin(deltaLong/2), 2) 
    val greatCircleDistance = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) 
    3958.761 * greatCircleDistance 
} 

// A sequence of gpx trackpoint lat,long pairs parsed from the track GPX data 
val trkpts: Seq[(Double, Double)] = { 
    val x = scala.xml.XML.loadString(track) 
    (x \\ "trkpt").map(trkpt => ((trkpt \ "@lat").text.toDouble, (trkpt \ "@lon").text.toDouble)) 
} 

// Distance of track in miles using Haversine formula 
val trackDistance: Double = { 
    trkpts match { 
    case head :: tail => tail.foldLeft(head, 0.0)((accum, elem) => (elem, accum._2 + haversineDistance(accum._1, elem)))._2 
    case Nil => 0.0 
    } 
} 
0

この質問はかなり古いですが、私は完全性のためにpythonオプションを追加したいと思います。 GeoPygreat-circle distanceVincenty distanceの両方を持っています。

関連する問題