회사에서 지도를 활용하는 프로젝트를 진행중인데, Deck.gl, Mapbox에 한국어를 적용하는 문서들이 많이 없길래 ... 누군가에게 도움이 될 수 있을지도 모르니, 백업 차원에서 오랜만에 블로그로 작성한다.
참고로 사용하는 라이브러리들이 client side rendering 이 많아 사용하는 프레임워크는 단순 React, Typescript 로 진행하고있다. Deck.gl 은 React friendly 하며, 처음엔 Next.js 사용할까 했는데 페이지가 약 4개정도 밖에 되지 않는데 차트랑 Deck.gl 때문에 use client
덕지덕지 붙어있어서 그냥 SPA 사용했다.
참고로 이번 포스팅은 내가 작성한 Deck.gl, react-map-gl 의 구조와 한국어 처리하는 방식을 다루고 있으므로 설치 과정은 포함하지 않는다.
Deck.gl 이란?
Heatmap, Arch, Polygon 등 다양한 차트를 지도에 표기할 수 있는 라이브러리
이미 이부분을 알고있는 사람들은 그냥 넘어가도 좋을듯 하다. 사실 나도 그렇게 자세히 조사한건 아니댜. ㅎ
미국의 대형 택시회사 (...) Uber 에서 만든 라이브러리이기 때문에 성능 면에서는 나쁘지 않은 것 같다. 현재 회사에서 사용하고있는 컴퓨터가 낡아서 그렇지, 좌표계 데이터 거의 8만건 이상을 넣어도 성능 좋은 컴퓨터에서는 굉장히 잘 돌아가는 편
데이터가 많은, 참고할만한 Deck.gl 예시들
- Superset (Scatter Plot) : 데이터를 최대 5만건 까지 가져와서 Scatter Layer 를 활용해볼 수 있다.
- US Gun Violence (Heatmap, Scatter Plot) : 데이터가 14만건 이므로 Heatmap 과 Scatter Layer 를 둘다 사용하는 예시인데, 내 컴퓨터에서는 너무 느려서 아무것도 볼 수 없었다.
내가 표기해야할 데이터들이 얼마나 데이터가 많이 들어가는지, 얼마나 많은 그림을 그려야할지를 가늠해서 라이브러리의 사용 여부를 결정하면 좋겠다.
Deck.gl 의 동작 방식은 지도 레이어 위에 deck.gl의 다양한 차트 레이어(Layers)들을 덮는 방식이다.
사실 deck.gl 의 대부분의 docs Layers 는 React 코드로 보여주고 있기 때문에 문서를 자세히 읽으면 금방 사용방법을 익힐 수 있다. Typescript 를 이용하는 경우, 모듈에서 type을 제공해주고 있으므로 다양하게 사용할 수 있다.
Deck.gl 사용하기
자세한 설치 방법은 Docs 를 참고하면 될테니 생략하고, 코드를 제공하고 구조를 설명하도록 하겠다.
Deck.gl 은 위에서 언급했던 것 처럼 레이어 형식으로 이루어져있기 때문에, deck.gl 컴포넌트 가 mapbox layer 를 감싸는 형식으로 구조를 작성해야한다.
해당 문서를 작성하는 시점에서는 (24.02.06) Base Map 은 Mapbox (react-map-gl
) 과 함께 사용하도록 작성되어있어서, 나도 Mapbox 로 이용했다. (관련 Docs)
참고로 구글 맵으로도 이용할 수 있으나, 예시나 기타 다양한 문서를 찾을 시간 없었다. 하하하
Google Maps 와 Mapbox 는 다른 회사이므로 구글 맵을 이용하는 경우, 해당 문서는 참고할 필요가 없다.
Deck.gl + Google Map 연동 참고 문서
Deck.gl 코드
import React, { type FC, type ReactNode } from 'react'
import DeckGL from '@deck.gl/react/typed'
import { Map } from 'react-map-gl'
import context from './context'
interface MapProps {
layers?: object[]
}
const MapComponent: FC<MapProps> = ({ layers }) => {
return (
<DeckGL
initialViewState={context.INITIAL_VIEW_STATE}
controller={true}
style={{ width: '100%', height: '100%' }}
useDevicePixels={false}
layers={layers as any}
>
<Map
mapboxAccessToken={context.MAPBOX_TOKEN}
mapStyle={context.mapStyle.streets}
/>
</DeckGL>
)
}
export default MapComponent
Deck.gl 을 활용한 기본 구조를 잡았다. 나는 타입스크립트를 이용하였기 때문에 /typed
를 이용하여 컴포넌트를 호출했다.
./context
: 나는 기본 설정 파일을 context 파일에 정의했다. 초기 상태, mapbox-token, mapbox 에 필요한 style 등을 입력해두었다.layers
: 해당 props 의 경우는, Deck.gl 에 추가할 Layer 객체의 집합 Array 를 생성해서 넣어주면 된다. (Layers 관련 Docs 참고)
MapboxLanguage 사용하기
MapboxLanguage 는 Mapbox 에서만 동작하는 언어 플러그인이다. (MapboxLanguage github) 참고로 한국어도 지원한다.
다만 /example
의 예시가 생성자함수 위주로만 작성되어있고 React 컴포넌트에서 활용하는 방법이 작성되어 있지 않아서 어떤 메서드를 이용해야할지 헤맸다는것 ㅎ...
사용법은 매우매우 간단한데, Github 의 문서를 따라 설치 후 <Map>
컴포넌트에 랜더링시 등록 해주면 된다.
MapboxLanguage 한국어 설정 코드
import React, { type FC, type ReactNode } from 'react'
import DeckGL from '@deck.gl/react/typed'
import { Map } from 'react-map-gl'
import context from './context'
interface MapProps {
layers?: object[]
}
const MapComponent: FC<MapProps> = ({ layers }) => {
// Rendering 과정에서 Language 설정
const onRender = useCallback((e: any) => {
// https://github.com/mapbox/mapbox-gl-language/?tab=readme-ov-file#setlanguage
e.target.addControl(new MapboxLanguage({ defaultLanguage: 'ko' }))
}, [])
return (
<DeckGL
initialViewState={context.INITIAL_VIEW_STATE}
controller={true}
style={{ width: '100%', height: '100%' }}
useDevicePixels={false}
layers={layers as any}
>
<Map
onRender={onRender}
mapboxAccessToken={context.MAPBOX_TOKEN}
mapStyle={context.mapStyle.streets}
/>
</DeckGL>
)
}
export default MapComponent
기본 언어를 'ko' 로 설정해주었으나, 다양한 언어를 지원하므로 다른 언어를 넣어도 이용 가능하다. 아래는 작업 완료된 결과물이다.
지도를 호출하고 렌더링하는 과정이 발생될 때마다 언어를 설정해주기 때문에, 콘솔을 확인해보면 onRender
함수는 매번 지도를 움직일 대 마다 동작한다.
Vue 만 사용하다가 React 사용하려니 적응안되는중 ...
'FRONTEND > React' 카테고리의 다른 글
React Typescript (CRA) 환경에서 Path Alias 설정하기 (0) | 2024.02.13 |
---|---|
220902 React Textarea 컨텐츠 높이 자동 설정 (0) | 2022.09.02 |
210623 React Context (0) | 2021.07.04 |
210622 React Hooks (0) | 2021.07.04 |
React - React lifecycle methods 정리 (0) | 2020.05.16 |
댓글