메뉴 건너뛰기

GPS 경위도 값을 이용한 거리 및 방위각 구하기

2013.04.08 01:55

류짜장 조회 수:2625

[Android] GPS 위도/경도를 이용한 두지점 거리계산 총집합!

 

 

 

 

 

 

GPS를 이용한 두지점간 거리계산 방법입니다.

 

안드로이드에서 기본적으로 제공해주는 직선거리 구하는 방법

지구는 타원으로 되어있기에 가까운지역인 경우 오차가 없지만,

거리가 멀어지면 오차가 발생하는걸 알 수 있습니다.

 

방법1.

 

double distance;
 
Location locationA = new Location("point A");
 
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
 
Location locationB = new Location("point B");
 
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
 
distance = locationA.distanceTo(locationB);

 

 

 

방법2.

float[] results = new float[3];
Location location = new Location("start");
location.distanceBetween(
startLatitude, 
startLongitude, 
endLatitude,
endLongitude,
results);
Sring mes = Float.toString(results[0]);
 
===============================================================================
The computed distance is stored in results[0]. 
If results has length 2 or greater, the initial bearing is stored in results[1].
If results has length 3 or greater, the final bearing is stored in results[2].
 
 
국토지리원에서 공개한 거리계산 함수 사용하기.
지구는 완전한 구라는 가정하에 지구를 GRS80타원체로 봤을경우
두지점간 거리와 방위각 구하는 소스
 
//거리 구하는 부분
 public double distance(double P1_latitude, double P1_longitude,
   double P2_latitude, double P2_longitude) {
  if ((P1_latitude == P2_latitude) && (P1_longitude == P2_longitude)) {
   return 0;
  }
  double e10 = P1_latitude * Math.PI / 180;
  double e11 = P1_longitude * Math.PI / 180;
  double e12 = P2_latitude * Math.PI / 180;
  double e13 = P2_longitude * Math.PI / 180;
  /* 타원체 GRS80 */
  double c16 = 6356752.314140910;
  double c15 = 6378137.000000000;
  double c17 = 0.0033528107;
  double f15 = c17 + c17 * c17;
  double f16 = f15 / 2;
  double f17 = c17 * c17 / 2;
  double f18 = c17 * c17 / 8;
  double f19 = c17 * c17 / 16;
  double c18 = e13 - e11;
  double c20 = (1 - c17) * Math.tan(e10);
  double c21 = Math.atan(c20);
  double c22 = Math.sin(c21);
  double c23 = Math.cos(c21);
  double c24 = (1 - c17) * Math.tan(e12);
  double c25 = Math.atan(c24);
  double c26 = Math.sin(c25);
  double c27 = Math.cos(c25);
  double c29 = c18;
  double c31 = (c27 * Math.sin(c29) * c27 * Math.sin(c29))
    + (c23 * c26 - c22 * c27 * Math.cos(c29))
    * (c23 * c26 - c22 * c27 * Math.cos(c29));
  double c33 = (c22 * c26) + (c23 * c27 * Math.cos(c29));
  double c35 = Math.sqrt(c31) / c33;
  double c36 = Math.atan(c35);
  double c38 = 0;
  if (c31 == 0) {
   c38 = 0;
  } else {
   c38 = c23 * c27 * Math.sin(c29) / Math.sqrt(c31);
  }
  double c40 = 0;
  if ((Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38))) == 0) {
   c40 = 0;
  } else {
   c40 = c33 - 2 * c22 * c26
     / (Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38)));
  }
  double c41 = Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38))
    * (c15 * c15 - c16 * c16) / (c16 * c16);
  double c43 = 1 + c41 / 16384
    * (4096 + c41 * (-768 + c41 * (320 - 175 * c41)));
  double c45 = c41 / 1024 * (256 + c41 * (-128 + c41 * (74 - 47 * c41)));
  double c47 = c45
    * Math.sqrt(c31)
    * (c40 + c45
      / 4
      * (c33 * (-1 + 2 * c40 * c40) - c45 / 6 * c40
        * (-3 + 4 * c31) * (-3 + 4 * c40 * c40)));
  double c50 = c17
    / 16
    * Math.cos(Math.asin(c38))
    * Math.cos(Math.asin(c38))
    * (4 + c17
      * (4 - 3 * Math.cos(Math.asin(c38))
        * Math.cos(Math.asin(c38))));
  double c52 = c18
    + (1 - c50)
    * c17
    * c38
    * (Math.acos(c33) + c50 * Math.sin(Math.acos(c33))
      * (c40 + c50 * c33 * (-1 + 2 * c40 * c40)));
  double c54 = c16 * c43 * (Math.atan(c35) - c47);
  // return distance in meter
  return c54;
 }
//방위각 구하는 부분
 public short bearingP1toP2(double P1_latitude, double P1_longitude,
   double P2_latitude, double P2_longitude) {
  // 현재 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에
  //라디안 각도로 변환한다.
  double Cur_Lat_radian = P1_latitude * (3.141592 / 180);
  double Cur_Lon_radian = P1_longitude * (3.141592 / 180);
  // 목표 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에
  // 라디안 각도로 변환한다.
  double Dest_Lat_radian = P2_latitude * (3.141592 / 180);
  double Dest_Lon_radian = P2_longitude * (3.141592 / 180);
  // radian distance
  double radian_distance = 0;
  radian_distance = Math.acos(Math.sin(Cur_Lat_radian)
    * Math.sin(Dest_Lat_radian) + Math.cos(Cur_Lat_radian)
    * Math.cos(Dest_Lat_radian)
    * Math.cos(Cur_Lon_radian - Dest_Lon_radian));
  // 목적지 이동 방향을 구한다.(현재 좌표에서 다음 좌표로 이동하기 위해서는 
  //방향을 설정해야 한다. 라디안값이다.
  double radian_bearing = Math.acos((Math.sin(Dest_Lat_radian) - Math
    .sin(Cur_Lat_radian)
    * Math.cos(radian_distance))
    / (Math.cos(Cur_Lat_radian) * Math.sin(radian_distance)));
  // acos의 인수로 주어지는 x는 360분법의 각도가 아닌 radian(호도)값이다.
  double true_bearing = 0;
  if (Math.sin(Dest_Lon_radian - Cur_Lon_radian) < 0) {
   true_bearing = radian_bearing * (180 / 3.141592);
   true_bearing = 360 - true_bearing;
  } else {
   true_bearing = radian_bearing * (180 / 3.141592);
  }
  return (short) true_bearing;
 }
 
 
이외 거리 구하는 참고자료는 첨부파일 참고해주세요~
번호 제목 글쓴이 날짜 조회 수
53 OKI B430dn 드럼 초기화 방법 [7] 류짜장 2015.09.15 437
52 [자동차] YF 2.4GDI 미션 충격(인히비터 스위치) [1] [12] file 류짜장 2015.09.10 832
51 [자동차] YF 소나타 공조기 잡소리 [10] file 류짜장 2015.08.30 1775
50 VB.NET 레지스트리 제어 [6] 류짜장 2015.03.25 370
49 몰딩 시공 자료 file 류짜장 2015.02.12 314
48 여수시 문수동 부영2차 아파트 셀프 리모델링(작업준비) [5] 류짜장 2014.07.03 1335
47 솔내시스템 CIE-H12를 활용한 에어컨 원격제어 [3] file 류짜장 2014.05.29 1148
46 VB.NET Serial port [107] 류짜장 2013.11.04 4550
» GPS 경위도 값을 이용한 거리 및 방위각 구하기 [15] file 류짜장 2013.04.08 2625
44 루바 자투리 활용(커피믹스 통) [6] 류짜장 2012.04.28 1026
43 OKI B430dn 프린터 드라이버 설치가 안되는 경우 [5] file 류짜장 2012.04.19 1690
42 VB Inet 관련 참고자료 [6] 류짜장 2012.03.25 1385
41 윈도우 업데이트 안되는 경우 해결방법 [4] 류짜장 2012.01.18 1784
40 부영아파트 분양 관련 소유권 이전 등기 직접 하기 [1] [2] 류짜장 2011.12.27 2417
39 무료백신 올레 닥터 2.0 소개 [2] file 류짜장 2011.12.21 2880
38 KT와이브로(모다정보통신 에그)를 통한 VPN접속 장애 [5] 류짜장 2011.12.10 5269
37 CISCO RV042 / RV082 VPN Router & Iphone [3] 류짜장 2011.10.29 2308
36 Suprema BioStation 지문인식기 [2] 류짜장 2011.10.23 2708
35 [VB] Visual Basic을 이용한 IE 신뢰할수 있는 사이트 추가 [2] 류짜장 2011.06.05 4016
34 MS 윈도우 업데이트 0xC80001FE 오류코드 해결방법 [2] 류짜장 2011.04.14 3804