자율주행

자율주행을 위한 GPS 데이터를 사용한 경로 맵 작성

coding art 2022. 9. 9. 17:09
728x90

참조1: GPS 데이터 가시화 및 OpenStreet Maps 사용법

https://towardsdatascience.com/simple-gps-data-visualization-using-python-and-open-street-maps-50f992e9b676

 

GPS 경로를 작도해 보기 위한 관심 지역의 맵을 https://openstreetmap.org/export

사이트를 방문하여 열자.

그림 파일 형태의 지도가 나타나면 아래 그림에서처럼 위도(latitude)와 경도(longitude)를 입력하여 관심지역 맵을 띄우자.

2. 내보내기 할 맵만 한정하여 화면 오른쪽 공유 버튼을 눌러 공유 메뉴에서 사용자지정 치수 설정을 클릭하여 맵과 가변 커서를 일치시킨 후 다운로드 버튼을 클릭한다.

3. 이러한 방법으로 이미 맵이 준비된 Github 데이터를 다운받아 압축 해제 후 폴더를 열어보자.

참조: GPS-visualization-Python

https://github.com/tisljaricleo/GPS-visualization-Python

 

아래 그림의 폴더에서 map.png 파일이 준비되었다.

resultMap 은 gps_class 클라스를 사용 짧은 main.py를 실행하여 출력된 GPS 경로가 작도된 결과물 지도이다.

GPS 경로 데이터는 엑셀이나 한셀 데이터 파일 즉 csv 파일로 주어지며 pandas 라이브러리를 사용하여 컬럼형 좌표 데이터를 읽어 들일 수 있다.

데이터를 읽을 수 있도록 pandas 라이브러리를 사용하자.

GPS 경로 라인의 작도는 matplolib.pyplt를 사용한다.

PIL로부터 이미지를 읽고 쓰고 작도할 수 있는 라이브러리를 불러오자.

1 import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw

 

함수 scale_to_img를 사용하여 GPS 데이터를 맵 데이터의 스케일로 변환하자. 함수의 인수는 gps 데이터, 맵의 폭과 높이 h_w, 짤라맨 맵의 좌상 및 우하의 위경도 데이터로 구성된다.

2 def scale_to_img(lat_lon, h_w, points):
old = (points[2], points[0])
new = (0, h_w[1])
y = ((lat_lon[0] - old[0]) * (new[1] - new[0]) / (old[1] - old[0])) + new[0]
old = (points[1], points[3])
new = (0, h_w[0])
x = ((lat_lon[1] - old[0]) * (new[1] - new[0]) / (old[1] - old[0])) + new[0]
return int(x), h_w[1] - int(y)

GPS 데이터가 기록되어 있는 data.csv 를 pandas 로 읽어 들이자. 엑셀로 열어보면 2개의 컬럼 데이터를 확인할 수 있다. 첫 번째를 Latitude(위도), 두 번째를 Logitude(경도) 로 두고 ‘,’ 로 분리된 상태의 데이터이다. csv 데이터를 수정 없이 재 저장해 보자. 이때 엑셀의 반응을 주의깊게 살펴보고 csv 확장자로 저장하자.

3 data_path = 'data.csv'
data = pd.read_csv(data_path, names=['LATITUDE', 'LONGITUDE'], sep=',')
print(data)

읽은 데이터를 다음과 같이 출력해 보자.

LATITUDE LONGITUDE

0 45.825866 16.043631

1 45.825998 16.043700

... ... ...

35374 45.830008 16.039910

35375 45.830008 16.039908

 

.values 는 pandas 데이터로부터 일반 수치값으로 변환시키는 작업이다. tuple은 2차원 좌표처럼 2개의 짝으로 구성된 데이터를 형성하는 명령이다.

map.png 즉 맵 그림 파일을 읽어들이자.

4 gps_data = tuple(zip(data['LATITUDE'].values, data['LONGITUDE'].values))
image = Image.open('map.png', 'r') # Load map image.

맵상에 gps 경로를 찍을 이미지 점 데이터를 리스트 데이터 형태로 생성하자. for loop 알고리듬을 사용해서 gps 리스트 데이터를 하나씩 looping 시켜 gps 데이터를 맵 좌표 데이터로 변환한다. 하나씩 데이터가 변환될 때마다 image.points 리스트 데이터에 첨부(append) 시키자.

5 img_points = []
points=(45.8357, 15.9645, 45.6806, 16.1557)
for d in gps_data:
x1, y1 = scale_to_img(d, (image.size[0], image.size[1]), points) # Convert GPS coordinates to image coordinates.
img_points.append((x1, y1))

최종적으로 얻어진 맵상의 점 데이터들을 연결 선으로 작도하자. fill=(255,0,0) 은 연결선 색상으로 푸른색을 지정하고 선폭은 굵은 선에 해당하는 2 로 둔다.

6 draw = ImageDraw.Draw(image)
# Draw converted records to the map image.
draw.line(img_points, fill=(255, 0, 0), width=2)
image.save('resultMap.png')

다음과 같이 gps 경로가 작도된 지도를 볼 수 있다.

 

블로그에 첨부된 gpsmapplot.py 코드를 다운받아 실행해보자.

gpsmapplot.py
0.00MB

실측한 GPS 데이터 세트를 맵 상에 가시화 하는 파이선 작성해 보았다. 하지만 자율주행 차량의 시스템 소프트웨어 작성은 센서 데이터 통합부터 인공지능 분석에 이르기까지 대단히 많은 세부 코드들이 통합되어야 하므로 이 작업 중에서 핵심이 되는 코드들은 가급적 클라스 명령으로 만들어 분리하고 짧은 메인 코드에서 불러 쓰는 형태가 되어야 할 것이다.

 

다음의 메인 코드에서처럼 GPSVis 클라스를 준비하여 불러내자. 앞서 설명된 1 ~5번까지의 작업에 해당할 것이다. 특히 2번의 함수 scale_to_image 는 GPSVis 클라스에 속하는 메서드로 등록되어 있음에 유의하자.

아울러 메서드 create_image를 사용하여 작도 이미지를 생성하고 메서드 plot_map 으로 inline 출력 후 저장한다.

헤더 영역 제외하면 3줄에 해당하는 코딩 분량이다.

 

1 from gps_class import GPSVis
vis = GPSVis(data_path='data.csv', map_path='map.png',
points=(45.8357, 15.9645, 45.6806, 16.1557))
vis.create_image(color=(0, 0, 255), width=3)
vis.plot_map(output='save')
print()

이 코드를 아나콘다에서 실행시켜보며면 앞서 다운받아 압축해제했던 GPS-visulaization-Python 폴더의 main.py를 실해하면 된다.

참조: GPS-visualization-Python

https://github.com/tisljaricleo/GPS-visualization-Python