'이동평균'에 해당되는 글 1건

  1. 2009.06.19 OSM 작업노트 #10: 해안선과 도로
OSM의 coastline은 PGS에서 자동 변환한 것으로, polygon이 아닌 polyline이라서 OSM 파일을 Garmin GPS용 .img로 변환하면 바다와 육지 경계만 표시될 뿐, 바다는 파랗고 육지는 육지색으로 표시되지 않는 문제가 있다. 여기에다가 transparent 옵션을 주고 .img 파일을 만들면 해안선은 엉성한 basemap에 묻혀 사실상 GPS에서 보이지 않는다. basemap에 묻히면 해안선 뿐만 아니라 시퍼런 바다에 등고선이 돋아있는 희안한 현상도 볼 수 있다.


남해안. 아래쪽은 새파란 바다여야 한다.

OSM의 랜더러들은 해안선을 판단해 바다와 육지 경계를 표시하므로 문제가 없지만, mkgmap, cgpsmapper 등에서 coastline을 적절히 처리할 방법을 찾아야 한다. mkgmap 제작자가 해안선을 처리할 방법을 나름대로 강구중인 것 같으나, 언제될 지 알 수 없다. 주욱 OSM 지도 작업을 하면서 느낀 거지만, 일단은 자력갱생 해야 한다.

현재로선 OSM 지도의 주 활용처가 Garmin GPS 디바이스인 관계로 이 문제를 해결하기 위해 임시변통 격으로(mkgmap에서 해안선을 다루게 될 때까지) polygon으로 구성된 해안선 데이터를 얻어와 바다를 구성하는 수 밖에 없다.

세계자전거오지여행의 운영자가 국가교통정보센터에서 공개한 한반도 도로 지도를 가공한 mp 파일에는 해안선 polygon 데이터가 있다(최근 데이터에는 없음). 이것을 뜯어와 img를 만들어 봤더니 드디어 바다와 육지가 구분되었다. 그런데 문제가 좀 있다.

해안선을 확대하면 디지타이즈된 라인이 아마도 한반도 저해상도 파일을 가지고 작업한 것처럼 라인이 단속적으로 끊어졌다.

성격은 좀 다르지만 국가교통정보센터의 도로에도 비슷한 문제가 있다.

사용자 삽입 이미지
오버줌 상태에서 보면 라인이 매끄럽게 연속적으로 이어진 것이 아니라 단락적으로 지글거린다. 이 때문에 도로만 데이터 크기가 350MB나 되어 OSM 서버에 도로 데이터를 올리는 것을 계속 망설이고 있었다. 해안선 문제 뿐만 아니라, 불필요한 노이즈를 억제하여 도로 데이터의 크기를 줄이는 방법도 역시 필요하다.

이들 문제를 해결하기 위해 벡터를 보간하는 방법을 궁리했다. 첫번째 방법은 벡터의 연속된 인접 3점으로 구성된 삼각형의 무게 중심을 구하는 공식을 이용해 다음 지점을 구하는 것이다. 그림으로 그리면,

사용자 삽입 이미지
좌상단이 첫 포인트, 우상단이 마지막 포인트. 두꺼운 실선은 원래의 좌표 벡터. 푸른선은 3점 포인트를 이용해 구성된 삼각형, 붉은선은 ABC 세 점으로 이루어진 연속적인 삼각형의 중심을 따라 이어진 선.

이렇게 하면 anti alias를 한 것 같은 효과가 나타난다. 원래의 검정 실선보다 붉은 선이 좀 더 부드러워지는 것. 포인트 수는 원래 7개에서 5개로 줄었는데, polyline이 상당히 길 경우 이 알고리즘을 적용하면 포인트의 수가 대략 1/2로 감소한다. 즉 파일 크기가 50% 줄어든다. 식: 각 점 A,B,C가 (x1,y1), (x2,y2),  (x3,y3)로 구성되어 있을 때 삼각형의 중심은 xc = (x1 + x2 + x3) / 3, yc = (y1 + y2 + y3) / 3.

두번째 삼각형과 세번째 삼각형에서 지나친 평균화 때문에 라인이 뭉툭해진다. 이것을 개선하기 위해 알고리즘을 바꿔 마름모의 중심을 이용하되 마지막 3점은 삼각형으로 계산하는 형태로 바꿨다.
 
사용자 삽입 이미지
삼각형보다는 원래 형태가 잘 반영되었다. 사각형(마름모) ABCD의 중심점은 xc = (x1 + x2 + x3 + x4) / 4, yc = (y1 + y2 + y3 + y4) / 4. 이것을 일반화하면 xc = (x1 + x2 + ... + xn ) / n, yc = (y1 + y2 + ... + yn) / n. 어? 정리해 놓고 보니 좌표의 이동 평균을 취한 것이다. 기껏 머리 좀 굴렸더니만 하하. 이때 n이 증가하면 포인트 수는 줄어드는 대신 궤적의 변화는 둔해진다.

과문한 탓에 더 빠르고 훌륭한 알고리즘을 만들진 못했다. 어디 뒤져보면 꽤 괜찮은 알고리즘이 있을 것 같다. 이쯤 해두고 알고리즘을 구현했다. 간단한 프로그램을 작성해 원래의 해안선 Polished file을 변환해 보았다.

사용자 삽입 이미지
원본.

사용자 삽입 이미지
알고리즘 적용.

만들긴 했지만 해안선은 애당초 DEM처럼 정밀한 데이터가 필요하다. 운 좋게 그걸 구하게 되면 이건 폐기할 것이다. 일단은 이동평균법을 이용해 Garmin GPS용 해안선을 예쁘게 만들었고(OSM 서버에는 안 올린다), 주 활용은 도로 데이터의 크기를 줄이는 것이다.

일단 OSM 서버에 도로 업로드하는 것은 당분간 안 하기로 했다. 도로 작업은 앞으로 몇 단계로 나뉘어 진행하게 될 것 같은데... 1. interpolation. 2. merge lanes. 3. connect. 4. add route information.

어쩐지 삽질하는 느낌을 지울 수 없다. 이런 데이터는 어딘가 이미 있다. 단지 그 데이터를 구하지 못해서...
 
,