13편 – 특정 시간대에 특정 도로의 교통정보를 계산해보자
내비게이션이 현재 차량의 위치정보를 확인하고 길안내를 서비스할 때, 내비 앱에는 GPS 정보들이 쌓이게 됩니다. 이런 GPS 정보로 운전자가 어떤 도로에서 얼마의 속도로 운행했는지를 알 수 있고, 이를 모아 해당 도로의 교통정보를 생성할 수 있는데요. 오늘은 ‘GPS 정보를 이용해 도로의 운행 속도 정보를 계산하는 방법’에 대해서 소개하고자 합니다. (물론, 여기서 사용하는 GPS 관련 정보에는 개인식별정보를 포함하고 있지 않습니다)
GPS(Global Positioning System) 정보(데이터)는 이미 많이 알려져 있는 것처럼 위성항법시스템을 말합니다. 4개 이상의 위성으로부터 신호를 받아 계산하여 위치를 알아낼 수 있는 시스템으로 위도, 경도, 고도와 시간 정보 이외에도 많은 정보를 포함하고 있지만 여기에서는 ‘좌표 정보(위도/경도)’와 ‘시간 정보’만을 이용합니다.
GPS 정보는 자체적으로 어느 정도 오차가 있는데, 추가로 3차원 상의 도로와 차량의 위치를 표현하는 GPS 정보를 다시 2차원의 점과 선으로 표현하여 속도를 계산하고 있기 때문에 어느 정도의 오차는 감안해야 합니다.
교통정보를 다루기 위해서는 ‘기반이 되는 도로’와 ‘도로 위를 주행하는 차량들’의 GPS 정보가 필요합니다. 현실의 도로 위에는 다양한 요소들이 복잡한 관계로 이루어져 있지만, 이를 교통정보 시스템으로 구성하기 위해 보다 간략화할 필요가 있습니다.
일반적으로 도로는 양방향으로 구성되고, 도로 내부는 여러 개의 차선으로 나뉘며, 차선 별로 차량들이 운행을 합니다. 아직은 오차로 인해 시스템에서는 차선을 구별하지는 못하고, 하나의 도로를 양방의 선으로 구성하고, 각 차량의 GPS 정보로 차량의 위치를 점으로 구성합니다. 각 차량은 서로 다른 차선에서 운행이 되는 점과, GPS의 정확도 오차범위 때문에 GPS는 도로를 대표하는 선과 정확히 일치하는 형태는 아니고 선 주변에 위치하게 됩니다.
다음은 실제 도로에서 차량 주행 상황을, 도로를 대표하는 선과 차량을 대표하는 포인트들로 간략화한 그림입니다.
실제 도로 전체의 교통정보를 한 번에 만들기는 불가능하기 때문에 도로를 구간별로 잘라서 구간별로 교통정보를 만들어 내고 있습니다. 이렇게 구간별로 잘라진 도로구간을 링크(Link)라 하고, 이를 선으로 표시합니다. 그리고, 이 선을 구성하는 점들을 버텍스(Vertex)라고 합니다. 실제로 도로 구간을 나누는 기준은 길이, 교차로, 도로의 특성 등에 따라 다양한 기준으로 나뉘게 되고, 맵을 전문으로 다루는 분들이 작업을 합니다만, 여기서는 교통정보를 구성하기 위한 수단으로만 이용하고 있는 점 참고하셨으면 합니다.
링크는 일직선으로만 구성되는 것은 아니고 위의 그림과 같이 실제 도로가 그러하듯 곡선이 존재할 수 있고, 이를 최대한 표현하기 위해서 많은 버텍스를 넣어서 최대한 곡선을 표시합니다.
결국 교통정보는 도로를 표시하는 링크와 버텍스, 차량의 위치를 표시하는 GPS 포인트 사이의 시간, 위치, 거리 정보를 이용하여 생성합니다.
기본적인 도로의 링크/버텍스 정보, GPS 정보로부터 본격적으로 차량의 속도정보를 계산해 보겠습니다. 다양한 방법들이 있겠지만, 여기서는 티맵모빌리티에서 고려되었던 방법들을 소개하려고 합니다.
도로의 특정 구간(링크)을 운행한 속도를 구하기 위해 필요한 기본 GPS 정보는 위도/경도 좌표와 측정한 시간입니다. 하지만, 위에서 설명한 것처럼 3~4차선의 도로를 하나의 선(링크)으로 표시하고 그 위에 실제 차량의 위치를 기반으로 측정한 GPS 포인트의 위도/경도 좌표를 그리게 되면 오차가 생길 수밖에 없습니다. 그런 오차를 감안하고, 가장 쉽게 속도를 측정하는 방법은 다음과 같습니다.
링크의 시작과 끝점 (N1, N2)과 GPS 포인트들 (Ga ~ Gz) 사이의 거리를 계산하면 N1, N2와 가장 가까운 GPS 포인트를 선택할 수 있습니다. 여기서는 N1과 가까운 GPS 포인트를 Gb, N2와 가까운 포인트를 Gz라고 가정하면,
링크의 길이 : L = N1과 N2 사이의 거리
링크를 통과하는데 걸리는 시간 : T = Gz측정시간 - Gb측정시간
링크를 통과한 해당 차량의 속도 : S = L / T
로 도로 위의 운행 속도를 쉽게 계산할 수 있습니다.
위의 계산법에서 조금 더 오차를 줄이기 위해 GPS 포인트를 수선의 발(foot of perpendicular)로 링크에 사상한 후에 거리를 계산하는 방법을 사용합니다. 위의 그림에서 각 GPS 포인트를 수선의 발로 링크 위로 사상하게 되면 다음 그림과 같이 그려볼 수 있습니다. 이렇게 링크 위로 모든 GPS 포인트를 사상한 후 비례식으로 실제 링크 시작점을 통과하는 시간을 측정해 오차를 조금 더 줄일 수 있습니다.
d1 : d2 = t1 : t2
t1 + t2 = Gb 측정시간 - Ga 측정시간
N1과 Ga, Gb 사이의 거리인 d1, d2 그리고 Ga, Gb의 측정시간은 모두 알 수 있는 값으로 N1의 통과 시점을 계산할 수 있습니다. 마찬가지 방법으로 N2의 통과 시점도 계산 가능합니다. 물론 이러한 방법도 Ga에서 Gb구간까지 등속으로 움직였다는 가정이 필요하지만 둘 사이의 시간이 대체로 몇 초 이내인 것을 감안하면 어느 정도 오차를 줄일 수 있다고 할 수 있습니다.
이렇게 링크의 양 끝점을 위주로 계산하는 경우에는 GPS가 링크를 통과하는 경우에만 사용할 수 있습니다. 즉, 링크 중간에 목적지가 있어 중간에 멈추는 경우나 모종의 이유로 더 이상 GPS가 측정이 안 되는 경우는 해당 차량이 링크의 어디까지 진행했는지 알아야 해당 링크의 진행 속도를 계산할 수 있습니다. 일반적인 직선 도로라면 간단하게 시작점에서 마지막 GPS 포인트까지의 거리를 계산하면 해결되지만, 이러한 직선 도로는 많지 않을 것입니다.
다음의 그림은 이러한 경우를 계산하는 방법에 대해 좀 더 자세히 보여 줍니다.
왼쪽의 그림은 첫 번째 방법과 마찬가지로 링크를 구성하는 Vertex들 (N1, N2, V1~V6)과 GPS 포인트들 (Ga~Ge)까지의 거리들을 구해서 마지막 GPS 포인트와 제일 가까운 V4까지 운행했다고 가정하고 거리를 계산합니다.
Ge와 가장 가까운 Vertex : V4
V4까지의 운행거리 : N1 ↔︎ V1 사이의 거리 + V1 ↔︎ V2 사이의 거리 + V2 ↔︎ V3 사이의 거리 + V3 ↔︎ V4 사이의 거리
V4까지의 운행시간 : Ge의 측정시간 - N1의 통과 예상 시간
N1에서 V4까지의 운행 거리 및 시간을 구해서 해당 구간에서의 속도를 구할 수 있습니다.
여기에서도 마찬가지로 수선의 발을 이용하면 마지막 V4와 Ge까지의 거리도 어느 정도 구할 수 있어 보다 오차를 줄인 속도를 구할 수 있습니다.
이렇게 개별 차량이 도로의 일정구간을 운행한 속도를 구할 수 있는데 이를 시간별 도로구간별로 묶어서 한 번 더 계산을 하면 특정 시간대에 특정 도로의 교통정보를 계산할 수 있고 최종적으로 교통정보가 생성되는 것입니다. 교통정보에는 속도 정보 이외에도 사고정보 같은 도로의 다양한 정보들을 포함하고 있고, 이외에도 많은 처리가 필요하지만 기본은 이러한 속도 정보입니다. 이 교통정보들이 생성되면 티맵에서 길찾기를 할 때 사용하게 됩니다.