티스토리 뷰
728x90
GPS 거리 계산하기
GPS 좌표를 두개를 입력하면 해당 좌표를 거리를 계산해주는 코드 입니다.
지구는 표면이 곡선으로 이루어져 있기에 직선으로만 계산하면 땅을 뚫고 지나가야 되는 문제점이 있습니다.
정확하지는 않지만 해당 부분을 보정하는 값을 넣었습니다.
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | /****************************************************************************** * _ _ _ _ __ _____ _ _ *| | | | | | | |/ / | __ \ | | | | *| |__| | __ _ ___ | |_ _| ' / | | | | _____ __ | | __ _| |__ *| __ |/ _` |/ _ \_ | | | | | < | | | |/ _ \ \ / / | | / _` | '_ \ *| | | | (_| | __/ |__| | |_| | . \ | |__| | __/\ V / | |___| (_| | |_) | *|_| |_|\__,_|\___|\____/ \__,_|_|\_\ |_____/ \___| \_(_) |______\__,_|_.__/ * * Copyright (c) HaeJuK Dev Lab All Rights Reserved. * *******************************************************************************/ using System; using System.Collections.Generic; using System.Text; namespace GPSLogger { class GpsCalc { public double distance( double P1_latitude/*C10*/, double P1_longitude/*C11*/, double P2_latitude/*C12*/, double P2_longitude/*C13*/) { 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; } // */ } } | cs |
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- C#
- 블루버블
- ip
- 윈도우
- Thread
- 현포다이브
- C++
- Windows
- PowerShell
- C#.NET
- 암호화
- Linux
- 제주도
- C# 고급 기술
- OpenSource
- 블루버블다이브팀
- DLL
- 성산블루버블
- 외돌개
- 블루버블다이빙팀
- 서귀포
- 스쿠버다이빙
- 리눅스
- CMake
- Build
- 패턴
- 서귀포블루버블
- 스쿠버 다이빙
- C
- 울릉도
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함
250x250