-
gps 위경도 구하기.하드웨어 2021. 10. 15. 16:08반응형
사용한 gps 제품은 TOP130L 이라는 모델입니다.
하지만 대부분의 GPS 는 포멧이 거의 동일하기 때문에 큰 차이점은 없습니다.
저 같은 경우는 3가지의 GPS 의 포멧을 분석해봤지만 위경도의 경우는 첫 태그만 종종 다를뿐 위경도 계산공식은 동일하게 사용하고 있습니다.
GPS 데이터를 일부만 잘라 보겠습니다.
여기서는 위경도만 구합니다. (저는 헤딩값까지 사용하긴 합니다.)
==========================================================$GNGSA,A,3,72,76,,,,,,,,,,,2.21,1.47,1.66,2*04
$GNGSA,A,3,27,,,,,,,,,,,,2.21,1.47,1.66,3*04
$GPGSV,3,1,10,05,25,124,26,10,22,311,22,12,05,157,36,13,25,060,30,0*65
$GPGSV,3,2,10,14,06,041,,15,54,052,31,18,50,238,29,24,76,170,29,0*67
$GPGSV,3,3,10,32,01,263,,50,46,179,31,0*69
$GLGSV,3,1,10,65,55,034,09,66,29,309,20,72,23,082,32,74,24,035,,0*78
$GLGSV,3,2,10,75,54,100,36,76,25,167,20,81,28,293,22,82,08,338,13,0*79
$GLGSV,3,3,10,87,01,201,21,88,23,235,28,0*79
$GAGSV,1,1,04,01,05,174,26,04,21,277,,27,29,071,33,33,25,200,22,0*7A
$GNGLL,3738.46131,N,12641.08594,E,053143.00,A,D*7C
$GNRMC,053144.00,A,3738.46118,N,12641.08587,E,0.121,,151021,,,D,V*15
$GNVTG,,T,,M,0.121,N,0.225,K,D*3F
$GNGGA,053144.00,3738.46118,N,12641.08587,E,2,09,1.47,26.5,M,17.8,M,,0000*75
$GNGSA,A,3,05,24,13,15,12,18,,,,,,,2.21,1.47,1.66,1*0C
$GNGSA,A,3,72,76,,,,,,,,,,,2.21,1.47,1.66,2*04
$GNGSA,A,3,27,,,,,,,,,,,,2.21,1.47,1.66,3*04==========================================================
뭔가 많아서 어려워 보이지만... 메뉴얼 볼것도 없이
대한민국에 거주중이시라면 37.xxx , 126.xxxx 일 테니까 GNGLL, GNRMC,GNGGA 3가지 태그로 값이 들어오는군요.
저는 GNRMC 값을 이용해서 파싱하도록 할게요.
아래 메뉴얼을 읽어보니 2번 status 가 A 이면 쓸만한 값인가보네요? 이것도 참조를 할게요.
3번 과 5번 값이 위경도네요. 0,2,3,5 정도만 써도 충분하겠네요.
이제 계산해 볼까요? 계산 공식은 매우 간단하고, 시간이 없는 관계로 php 로 빨리 짜볼게요.(실 업무에서는 c로 해야겠지만요..)
1. 위도 구하기.
$lat = "3738.46118";
$log_lat_dd = substr($lat,0,2); //앞 2자리
$sub_lat_mm = substr($lat,2); // 앞 2자리를 제외한 나머지
$log_lat_mm = $sub_lat_mm/60; // 60 으로 나누고
$log_lat = $log_lat_dd+$log_lat_mm; // 두개의 값을 더해줍니다.
echo "위도: ".$log_lat."<br/>"; //끝!
2. 경도 구하기.
$lng = "12641.08587";
$log_lng_dd = substr($lng,0,3); //앞 3자리
$sub_lng_mm = substr($lng,3); //앞 3자리를 제외한 나머지
$log_lng_mm = $sub_lng_mm/60; // 60으로 나누고
$log_lng = $log_lng_dd+$log_lng_mm; // 두개의 값을 더해줍니다.
echo "경도: ".$log_lng."<br/>"; //끝!
3. 결과자~ 구글 지도와 비교했을 때 , 비슷하게 나왔죠?
고가의 gps 라면 더 정확할 테고 저가라면 좀 더 정확도가 떨어질거에요.
추가로 저가 일수록 데이터가 튀는 현상이 발생하기도 합니다.
그럴 땐 전의 데이터와 비교하여 쓰래기 값은 걸러주는 로직도 필요하겠네요.
4. 추가
php 샘플$gpsTxt = '$GNRMC,053144.00,A,3738.46118,N,12641.08587,E,0.121,,151021,,,D,V*15'; //37.641389, 126.684270 $exgps = explode(",",$gpsTxt); //echo count($exgps); for($i=0;$i<count($exgps); $i++){ //echo $i."==".$exgps[$i]."<br/>"; } $tag = $exgps[0]; $status = $exgps[2]; $lat = $exgps[3]; $lng = $exgps[5]; $speed = $exgps[7]; echo $speed; if($tag == '$GNRMC' and $status == 'A' ){ //위경도 계산 //1. 위도 if(strlen($lat) >= 8 && strlen($lng) >= 8){ //$lat = "3738.46118"; $log_lat_dd = substr($lat,0,2); //앞 2자리 $sub_lat_mm = substr($lat,2); // 앞 2자리를 제외한 나머지 $log_lat_mm = $sub_lat_mm/60; $log_lat = $log_lat_dd+$log_lat_mm; echo "위도: ".$log_lat."<br/>"; //$lng = "12641.08587"; $log_lng_dd = substr($lng,0,3); //앞 3자리 $sub_lng_mm = substr($lng,3); //앞 3자리를 제외한 나머지 $log_lng_mm = $sub_lng_mm/60; $log_lng = $log_lng_dd+$log_lng_mm; echo "경도: ".$log_lng."<br/>"; } }
c 샘플log_latS = 3738.46118 log_lngS = 12641.08587 string log_lat_dd = log_latS.substr(0,2); string sub_lat_mm = log_latS.substr(2); float log_lat_mm = atof(sub_lat_mm.c_str())/60; float log_lat = atof(log_lat_dd.c_str())+log_lat_mm; log_latS = std::to_string(log_lat); string log_lng_dd = log_lngS.substr(0,3); string sub_lng_mm = log_lngS.substr(3); float log_lng_mm = atof(sub_lng_mm.c_str())/60; float log_lng = atof(log_lng_dd.c_str())+log_lng_mm; log_lngS = std::to_string(log_lng);
python 샘플def GPSParsing(lat , lng): print("lat : " + lat) print("lng : " + lng) log_lat_dd = lat[0:2] sub_lat_mm = lat[2:] print("log_lat_dd : " + log_lat_dd) print("sub_lat_mm : " + sub_lat_mm) log_lat_mm = float(sub_lat_mm)/60 print("log_lat_mm: "+str(log_lat_mm)) log_lat = str(int(log_lat_dd)+float(log_lat_mm)); print("log_lat : " +log_lat) log_lng_dd = lng[0:3] sub_lng_mm = lng[3:] print("log_lng_dd : " + log_lng_dd) print("sub_lng_mm : " + sub_lng_mm) log_lng_mm = float(sub_lng_mm)/60 log_lng = str(int(log_lng_dd)+float(log_lng_mm)); print("log_lng : " log_lng)
반응형'하드웨어' 카테고리의 다른 글
[아두이노 컴파일] esp8266 ch340G (0) 2023.01.31 리눅스 USB os 만들기. (0) 2022.01.11 [ESP8266] Serial 서버로 업로드하기 (0) 2017.08.28 Orange Pi Android Setup - Orange Pi PC Plus (0) 2017.08.19 Orange Pi Android Setup - Orange Pi One (0) 2017.08.19