[소소한 개발 일지] css – letter-spacing 이 적용되지 않을 때
D3.js 를 사용하여 데이터 시각화하기 #7 우리나라 지도 그리기(svg)
2022-11-07
Explanation
오늘은 D3를 사용해서 우리나라 지도를 그리는 걸 해보려고 합니다.
사실 이미 굉장히 좋은 글들이 많이 있었는데요, 뭔가 막상 직접 해보니 헷갈리는 부분들이 있어서 정리도 할 겸 제가 해본 내용을 살짝 적어보려 합니다.
저는 많은 블로그의 글들에서 봤던 것처럼 아래의 링크에서 지도 데이터 파일을 다운로드했습니다!
(저는 ‘시도’를 받았습니다.)
http://www.gisdeveloper.co.kr/?p=2332
우선! 역시 마찬가지로.. 다른 분들의 글을 참고해서 QGIS을 다운로드했습니다.
https://qgis.org/en/site/forusers/download.html
이쯤에서 QGIS 프로그램에 대해서 이야기를 해야 하는데, 사실.. 아직 잘 몰…
대략 프로그램을 실행하면 위와 같은데요.
‘레이어’ > ‘레이어 추가’ > ‘벡터 레이어 추가…’ 버튼을 선택합니다.
‘원본’란에 아까 다운로드 받은 shp 파일을 넣어주시고, 위에 인코딩은 ‘EUC-KR’로 선택하신 후에 추가 버튼을 선택합니다.
그러면 위와 같이 지도가 짜잔하고 뜨는 걸 확인하실 수 있는데요, 여기에서 왼쪽 아래에 레이어란에서 마우스 우클릭 후 ‘속성 테이블 열기’ 버튼을 눌러보시면 데이터가 잘 나와야 하는데,
혹시라도 저와 같이 한글이 깨져서 나온다면?!
레이어에서 우클릭 하셔서 ‘속성’을 선택하신 후 ‘원본’에서 ‘데이터 원본 인코딩’을 ‘EUC-KR’로 변경하고 ‘OK’버튼을 선택해주세요.
그리고 다시 ‘속성 테이블 열기’를 확인해 보시면 한글이 정상적으로 나오는 것을 알 수 있습니다. 짜잔!
하… 간단한 내용인데… 캡처가 일입니다…
거의 다 왔습니다…
다시 레이어에서 우클릭 후 ‘Export’ > ‘객체를 다른 이름으로 저장’ 버튼을 선택합니다.
포맷을 ‘geoJSON’으로 하고 ‘파일 이름’은 … 을 선택하셔서 저장할 위치와 파일 이름을 설정하시고요 ‘좌표계’는 ‘- WGS 84’로 설정하고 ‘OK’ 버튼을 누르면, 드디어 geoJSON 파일을 만드는 거 끝!!
다음으로 geoJSON 파일의 지도를 조금 단순화 하고 topoJSON 파일로 변경합니다!
https://mapshaper.org/ 여기 사이트로 가셔서 아까 만든 geoJSON 파일을 넣어줍니다.
다음으로 지도를 조금 단순화 해볼게요, 상단에 ‘Simplify’ 메뉴를 선택한 후 ‘Apply’ 버튼을 선택하고 원하시는 퍼센테이지를 입력합니다.
상단에 ‘Export’ 메뉴를 선택한 후 ‘TopoJSON’ 을 선택한 후 Export 버튼을 눌러 topoJSON 파일을 만들어 주면 topoJSON 만들기 끝!
전체적인 코드는 아래의 링크를 통해 깃허브에서 확인하실 수 있습니다!
기본 스택은 저에게 가장 간단하고 익숙한 js, webpack, react를 사용하였습니다.
https://github.com/falsy/blog-post-example/tree/master/korea-map-charts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
//KoreaMap.js import * as React from 'react' import { useEffect, useRef } from 'react' import * as d3 from 'd3' import { feature } from 'topojson-client' import korea from '../mapData/korea-topo.json' const featureData = feature(korea, korea.objects['korea-topo']) // topojson-client는 topoJSON 파일을 D3에서 사용할 수 있게 바꿔주는 라이브러리라고 하네요?? // 그리고 저는 위에 'korea-topo' 라는 이름으로 접근했는데 // 만드신 topoJSON 파일을 열어서 'objects'라고 검색하셔서 객체로 안에 프로퍼티 이름을 적어주시면 된답니다. const KoreaMap = () => { // svg를 그릴 엘리먼트 설정을 위한 ref const chart = useRef(null) const printD3 = () => { // 지도 svg의 너비와 높이 const width = 500 const height = 500 // 메르카토르 투영법 설정 // 우리가 가장 많이 쓰는 도법으로 구형인 지구를 평면으로 표현하는 하나의 방법이라고 하네요?? const projection = d3.geoMercator().scale(1).translate([0, 0]) const path = d3.geoPath().projection(projection) const bounds = path.bounds(featureData) // svg의 크기에 따른 지도의 크기와 위치값을 설정합니다. const dx = bounds[1][0] - bounds[0][0] const dy = bounds[1][1] - bounds[0][1] const x = (bounds[0][0] + bounds[1][0]) / 2 const y = (bounds[0][1] + bounds[1][1]) / 2 const scale = 0.9 / Math.max(dx / width, dy / height) const translate = [width / 2 - scale * x, height / 2 - scale * y] projection.scale(scale).translate(translate) // svg를 만들고 const svg = d3 .select(chart.current) .append('svg') .attr('width', width) .attr('height', height) const mapLayer = svg.append('g') // topoJSON의 데이터를 그려줍니다. mapLayer .selectAll('path') .data(featureData.features) .enter().append('path') .attr('d', path) .style('fill', '#666') } useEffect(() => { printD3() }, []) return ( <div ref={chart}></div> ) } export default KoreaMap |
뭔가 캡처만 많았지 제대로 된 설명이 부족한 거 같네요. 절대로 아직 잘 몰라서 대충 적고 넘긴 거, 맞습니다…
(다음에 조금 더 공부해서.. 정리하도록 하겠습니다.)
참고.
https://junghan92.medium.com/d3-geo-topojson-canvas%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A7%B5-%EC%B0%A8%ED%8A%B8-%EA%B7%B8%EB%A6%AC%EA%B8%B0-ffab54ec23bf
https://parandol.tistory.com/38
https://gist.github.com/e9t/55699e9fa8c3eb7fe40c#file-thumbnail-png
https://threadbuilder.wordpress.com/2019/03/15/echart-%ED%95%9C%EA%B5%ADkorea%EC%A7%80%EB%8F%84-%EB%9D%84%EC%9A%B0%EA%B8%B0/
https://medium.com/@masoolsa7/%ED%96%89%EC%A0%95%EA%B5%AC%EC%97%AD-%EA%B2%BD%EA%B3%84-topojson-%ED%8C%8C%EC%9D%BC-%EB%A7%8C%EB%93%A4%EA%B8%B0-392800d0bc0b
https://stackoverflow.com/questions/25310390/how-does-path-bounds-work