파이썬(Python)

[Python]GPS파일(nmea)에서 위도, 경도, 속도, 시간 정보 읽어서 csv에 저장하기(Latitude, Longitude, Speed, Time)

끄적끄적아무거나 2022. 11. 10. 08:32
반응형

 

목차

     

     

     

    GPS파일(nmea) Parsing 하기

     

    예제 nmea파일>>

    $GPRMC,054900,A,3708.8127,N,12724.8667,E,000.0,252.0,311022,007.9,W*69
    $PVRCT,56035757821,054900,311022*5F
    $GPGGA,054900,3708.8127,N,12724.8667,E,1,08,1.2,144.0,M,22.9,M,,*44
    $GPGSA,A,3,10,12,15,22,23,24,25,,32,,,,2.0,1.2,1.6*33
    $GPGSV,3,1,10,10,70,262,39,12,51,098,46,15,12,108,36,22,20,295,43*74
    $GPGSV,3,2,10,23,56,181,40,24,36,052,41,25,48,156,43,31,00,000,37*7E
    $GPGSV,3,3,10,32,45,311,42,21,04,318,00*70
    $PGRMT,GPS 16x-HVS software ver. 4.20,,,,,,,,*73
    $GPRMC,054901,A,3708.8127,N,12724.8667,E,000.0,252.0,311022,007.9,W*68
    $PVRCT,56135759167,054901,311022*5A
    $GPGGA,054901,3708.8127,N,12724.8667,E,1,09,1.0,144.0,M,22.9,M,,*46
    $GPGSA,A,3,10,12,15,22,23,24,25,31,32,,,,1.6,1.0,1.3*33
    $GPGSV,3,1,10,10,70,262,39,12,51,098,46,15,12,108,36,22,20,295,43*74
    $GPGSV,3,2,10,23,56,181,40,24,36,052,41,25,48,156,43,31,13,243,37*79
    $GPGSV,3,3,10,32,45,311,42,21,04,318,00*70
    $GPRMC,054902,A,3708.8127,N,12724.8667,E,000.0,252.0,311022,007.9,W*6B

     

    위 파일은 Garmin GPS 센서를 사용해서 1초 주기로 샘플링한 결과 값 중 일부 입니다. 여기서 저는 위도, 경도, 속도, 시간에 대한 정보 값을 읽어(read)오려고 합니다.

     

    nmea 파일은 $(달러) 기호로 정보의 시작을 알려줍니다. 그리고 우리가 찾는 정보는 GPRMC 구문에 있습니다.

     

    GPRMS를 Parse 해서 분석하면 아래와 같습니다.

     

     

     

    $GPRMC,054902,A,3708.8127,N,12724.8667,E,000.0,252.0,311022,007.9,W*6B

     

    - 054902 : UTC 시간 정보

    - A: Active로 현재 신뢰할 수 있는 데이터라는 의미

    - 3708.8127 : 위도(Latitude) 정보, ddmm.mmmm 으로 표기됨

    - N : North, South 를 의미

    - 12724.8667 : 경도(Longitude) 정보, dddmm.mmmm 으로 표기됨

    - E : East, West를 위미

    - 000.0 : 속도를 의미 Knot 단위, km/h로 변환을 위해 1.852 곱함

     

     

     

     

     

    파이썬 GPS파일(nmea)에서 위도, 경도, 속도, 시간 정보 읽어서 csv에 저장

     

    이번에는 nmea 파일을 파이썬(Python)으로 읽어서 위도, 경도, 속도, 시간 값만을 검색해서 해당 값만을 csv에 저장하는 코드를 작성해 보겠습니다.

     

    코드 설명에 앞서 전체 코드는 아래와 같습니다.

     

    파이썬 전체 코드>>

    import csv
    
    file_name = input("nmea 확장자를 제외한 파일명을 입력하시오(ex:abc.nmea -> abc): ")
    
    def readNMEA():
        while True:
            try:
                infile = open(file_name+".nmea", "r")
                with open(file_name+"_gps.csv", 'w', encoding='UTF8', newline='') as f:
                    writer = csv.writer(f)
                    writer.writerow(["time","lat","long","speed"])
                    writer.writerow(["sec","degree","degree","km/h"])
    
                    for x in infile:
                        dataGPS = x.split(",")
                        if dataGPS[0]=="$GPRMC":
                            if dataGPS[2]=="A":
                                utc = float(dataGPS[1])
                                latgps = float(dataGPS[3])
                                longps = float(dataGPS[5])
                                speed = float(dataGPS[7])
                                # if dataGPS[4]=="S":
                                #     latgps =  -latgps
                                # if dataGPS[6]=="W":
                                #     longps =  -longps  
    
                                #convert lat, lon ddmm.mmmm to decimal degree
                                latdeg = int(latgps/100)
                                latmin = latgps - latdeg*100
                                lat = latdeg + latmin/60
    
                                londeg = int(longps/100)
                                lonmin = longps - londeg*100
                                lon = londeg + lonmin/60
    
                                speed = int(speed)*1.852
    
                                coord =[utc, lat, lon, speed]
                                
                                writer.writerow(coord)
                                print(coord)
                break
            except:
                file_name = input("잘못된 입력 값입니다. 다시 입력해주십시오\nnmea 확장자를 제외한 파일명을 입력하시오(ex:abc.nmea -> abc): ")
    
    
    readNMEA()

     

     

    결과>>

    nmea 확장자를 제외한 파일명을 입력하시오(ex:abc.nmea -> abc): test

    test.nmea 파일을 통해 test_gps.cvs 파일을 생성하였습니다. 해당 값이 맞는지는 구글 맵(Google map)에서 위도 값, 경도 값 을 입력하면 지도에 표기 됩니다.

     

     

     

     

    주석>>

    file_name = input("nmea 확장자를 제외한 파일명을 입력하시오(ex:abc.nmea -> abc): ")

    주석: nmea의 파일명을 입력 받아서 분석하고 csv 파일을 만들 때 해당 파일 명을 사용 합니다.

     

     

     

    def readNMEA():
        while True:
            try:
                infile = open(file_name+".nmea", "r")
                with open(file_name+"_gps.csv", 'w', encoding='UTF8', newline='') as f:
                    writer = csv.writer(f)
                    writer.writerow(["time","lat","long","speed"])
                    writer.writerow(["sec","degree","degree","km/h"])

    주석: 함수를 while으로 동작하고 file_name이 없는 경우 except이 실행되어 다시 input 값을 받습니다. 정상적으로 파일이 열리면 csv 파일을 만들고 첫 두열을 7, 8번째 라인과 같이 채워 줍니다.

     

     

                    for x in infile:
                        dataGPS = x.split(",")
                        if dataGPS[0]=="$GPRMC":
                            if dataGPS[2]=="A":
                                utc = float(dataGPS[1])
                                latgps = float(dataGPS[3])
                                longps = float(dataGPS[5])
                                speed = float(dataGPS[7])

    GPRMC에서 UTC 시간 정보와 위도 정보, 경도 정보, 속도 정보를 가져 옵니다.

     

     

                                latdeg = int(latgps/100)
                                latmin = latgps - latdeg*100
                                lat = latdeg + latmin/60
    
                                londeg = int(longps/100)
                                lonmin = longps - londeg*100
                                lon = londeg + lonmin/60
    
                                speed = int(speed)*1.852

    앞서 위도 경도 값을 decimal 형태로 변경 해줍니다. 속도는 km/h로 변경합니다. 

     

     

    반응형