d3-geo, TopoJSON, canvas를 이용한 맵 차트 그리기

Jung Han
14 min readApr 8, 2021

TOAST UI Map Chart 4를 새롭게 준비하면서 조사했던 지도 그리는 방법에 대해 간단하게 공유하려고 합니다.

왜 이조합인가?

기존 Chart3에서는 svg를 사용해 path 자체를 가져와 직접 입력해주는 형태로 차트를 그려주고 있었습니다. 지도데이터를 그릴 때 제일 먼저 생각나는 것은 캔버스가 아닌 svg를 사용하는 것입니다. 여러 부분에서 캔버스보다 다루기 쉬운 것은 사실이지만 TOAST UI Chart4의 반응형 로직을 그대로 활용하고 싶다는 생각에서 캔버스를 사용해 테스트를 진행했습니다. 또한, amChart에서 제공하는 데이터를 직접 사용하다 보니 행정 구역상의 변경이 있거나 amchart에 존재하지 않는 지도일 경우 사용이 어려운 문제가 있었습니다.

아무래도 path 자체를 갖고 있는 경우 지도 데이터를 갖고 있는게 아닌 그리는 방법을 갖고 있다보니위도, 경도를 입력해 마커를 표시하기에 무리가 있으며 이후에 새로운 기능을 확장하기에 무리가 있었습니다.

그럼 표준화된 지도 데이터 방식이 뭐가 있을까요?

GeoJSON과 TopoJSON

저도 이 분야는 익숙지 않아 관련 라이브러리를 먼저 조사했습니다. 기존에 사용하고 있던 amChart 부터 많이 사용하는 D3, leaflet, Mapbox, Google map 같은 서비스들을 살펴보면 지도를 그리는 데 사용되는 데이터로 GeoJSON 그리고 TopoJSON을 공통으로 확인할 수 있습니다.

GeoJSON

GeoJSON은 위치 정보를 갖는 점을 기반으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식입니다. 이름에서도 알 수 있듯이 JSON 형태의 파일 형태입니다. 다른 지리 정보 시스템(GIS) 처럼 공식 표준 조직에서 운영되지 않고 국제 인터넷 표준화 기구 산하 워킹그룹에서 유지되지만, XML을 기반으로 한 GPX사실상 표준처럼 사용됩니다.

GeoJSON은 FeatureCollection을 갖는 객체에 Feature 집합을 갖는 JSON 형태로 나타납니다. 아래 예시는 자바해의 말레이제도의 가상 GeoJSON 표기를 나타낸 내용입니다.

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0]
]
]
},
"properties": {
"prop0": "value0",
"prop1": { "this": "that" }
}
}
]
}

Feature 집합은 여러 geometry 타입과 좌표, 속성값을 갖습니다. 사용할 수 있는 간단한 geometry를 위키에서 참조해보면 다음과 같습니다. GeoJSON 좌표는 [경도, 위도]를 지원합니다.

--

--