본문 바로가기
FRONTEND/React

React, Deck.gl, Mapbox(react-map-gl) 와 함께 한국어(ko) 처리하기

by 또야또야 2024. 2. 6.
반응형

회사에서 지도를 활용하는 프로젝트를 진행중인데, 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 사용하려니 적응안되는중 ...

반응형

댓글