2009-02-20 6 views

답변

23

두 포인트 (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 

이렇게하면 거리가 마일로 반환됩니다. 킬로미터의 경우 지구의 반지름을 킬로미터로 대체하십시오.

Here에 대한 자세한 설명입니다.

편집 :이 기능은 우편 번호 데이터베이스로 반경 검색을 수행하기에 충분히 빠르며 정확합니다. 수년간 this site에서 훌륭한 작업을 해오 고 있습니다. (링크가 깨 졌으므로 더 이상하지 않습니다.)

+0

고맙습니다. 나는 그것을 java에 포팅하고 여기에 게시 할 것이다. @DtoR은 무엇을 의미합니까? 반경까지의 거리? – guerda

+1

도를 라디안, 파이/180로 변환하는 요소입니다. – cdonner

+0

링크를 제공해 주셔서 감사합니다. 곧 Java 버전을 게시 할 것입니다. – guerda

1

Vincenty formulae의 델파이 구현은 here입니다.

+0

업데이트 된 링크가 있습니까? –

+0

@Adam Carter : URL을 확인한 결과 여전히 괜찮습니다. – menjaraz

1

다음은 스칼라 구현입니다.

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 옵션을 추가하고 싶습니다. GeoPy에는 great-circle distanceVincenty distance이 있습니다.