두 좌표 간의 거리를 구하라는 task가 떨어졌습니다.

어떻게 계산하면 좋을까요?


저는 처음에 피타고라스의 정리를 이용하면 될 것 같았어요.

피타고라스의 정리에 대한 이미지 검색결과

a^{2}+b^{2}=c^{2}\,


이 그림 어때요? 오랜만이죠??



그런데, 지구 상의 두 좌표의 거리를 구하기 위해서는 Haversine formula를 적용해야 할 필요가 있습니다.

왜냐하면 지구는 평면이 아니기 때문입니다.


그 공식은 아래와 같습니다.



코딩해 보죠...

자 그럼 먼저...



으음...




하아...


찾아봅시다... :)



function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}

Stack overflow를 보니 Chunck라는 친구가 javascript function을 작성해서 공유해 주었습니다.

친절하게 단위도 km네요. 저는 mile을 써야 하는데 ㅋ


그리고 Salvador Dali라는 친구가 코드를 최적화 해 줬습니다.

처리 속도가 2배 빠르다고 합니다.


function distance(lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p)/2 + 
          c(lat1 * p) * c(lat2 * p) * 
          (1 - c((lon2 - lon1) * p))/2;

  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

이렇게요.

최종 반환 값에 mile 변환을 위한 상수 0.621371를 곱하면 원하는 mile단위의 거리를 가져올 수 있겠네요.



결과를 검증해 보겠습니다.



google map에서 사무실 근처의 좌표를 가져왔습니다.

좌표는 각각 37.4137701, 127.1284930 / 37.4073826, 127.1338793이구요.

직선 거리는 약 853.75m가 나왔습니다.




jsFiddle에서 해당 function을 테스트해 보았습니다. (#)

좌표를 넣고 계산한 값을 console로 출력했습니다. km/mile 단위로


그 결과는 아래와 같습니다.

distance 0.854860114404647 km

distance 0.5311852841477299 mile


853.75 | 854.86 약 1km 거리에서 약 1m 정도 차이가 나네요.

허용 가능한 오차 수준이라고 우겨봅니다.



References

https://en.wikipedia.org/wiki/Haversine_formula

https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula

https://jsfiddle.net/n5d7tgez/

'Javascript' 카테고리의 다른 글

Ionic 2 Unit test  (0) 2017.07.31
Implement base controller  (0) 2017.07.26
Service workers.  (0) 2017.07.06
npm lite-server  (0) 2017.07.06

+ Recent posts