ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 정도만 써도 충분하겠네요.

    gps 제품 메뉴얼.




    참고로 현재 저의 위치입니다.  구글 지도에서 클릭하면 바로 위경도가 뜨니까 확인이 쉬워요.


    이제 계산해 볼까요? 계산 공식은 매우 간단하고, 시간이 없는 관계로 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)
    반응형

    댓글

Designed by Tistory.