문서 / 확장 레이어 / 벡터 타일 레이어

벡터 타일 레이어

MapLibre 형식의 벡터 스타일(style.json)을 브라우저 안에서 래스터 타일로 그려, 어떤 지도 프로바이더에도 겹쳐 쓸 수 있게 하는 패키지입니다. Google Maps·MapKit·HERE·ArcGIS·Cesium처럼 벡터 스타일을 스스로 읽지 못하는 지도에서도 같은 모양으로 표시됩니다.

REACT
@mapconductor/react-vectortile
렌더링 방식
래스터 타일(wasm)
ESM / CJS
ESM 전용

01 · 개요

렌더링은 Rust로 작성한 렌더러를 wasm으로 만든 것으로, Web Worker 안에서 동작합니다. 그린 타일은 SDK의 로컬 타일 서버(Service Worker)에서 제공되며, 지도에는 일반적인 RasterLayer로 올라갑니다. 지도 입장에서 보면 그저 래스터 레이어일 뿐입니다. 그래서 프로바이더를 가리지 않습니다.

레이어는 2장으로 나누어 올립니다. 채우기·선·원의 '지면'과, 그 위의 투명한 '라벨'입니다. 폰트가 도착했을 때 다시 그리는 것은 라벨 쪽뿐이므로, 글자가 나타나는 순간 지도가 한 번 사라지는 일이 발생하지 않습니다. 스타일의 출처(OpenStreetMap 등)의 저작권 표시도 자동으로 붙습니다.

02 · 설치

terminalnpm
npm install @mapconductor/js-sdk-core @mapconductor/js-sdk-react \
            @mapconductor/react-vectortile

@mapconductor/js-vectorstyle도 의존성으로 함께 설치됩니다. 패키지는 ESM 전용입니다.

타일용 Service Worker 배치하기

타일은 /tile-sw.js에서 제공됩니다. 히트맵과 같은 요건입니다. @mapconductor/js-sdk-core에 들어 있는 파일을 앱의 공개 디렉터리로 복사하세요.

package.jsonJSON
{
  "scripts": {
    "postinstall": "cp node_modules/@mapconductor/js-sdk-core/dist/tile-sw.js public/tile-sw.js"
  }
}

Vite의 프로덕션 빌드에서는 worker를 ES 모듈로 출력하는 설정이 필요합니다(dev 서버에서는 필요하지 않습니다).

vite.config.tsTypeScript
import { defineConfig } from 'vite';

export default defineConfig({
  worker: { format: 'es' },
});
주의
Service Worker는 보안 컨텍스트에서만 동작합니다. localhost라면 HTTP인 채로 괜찮지만, LAN 안의 다른 기기에서 열 때는 HTTPS가 필요합니다.

03 · 기본 사용법

어떤 *MapView 안에도 배치할 수 있습니다. style에는 style.json의 URL, 해당 문자열, 파싱된 객체 중 무엇이든 전달할 수 있습니다. 아래 예는 Google Maps 자체 지도를 지우고(GoogleMapDesign.None), 그 위에 벡터 스타일을 그립니다.

VectorTileMap.tsxTypeScript · React
import { createGeoPoint, createMapCameraPosition } from '@mapconductor/js-sdk-core';
import { GoogleMapDesign, GoogleMapView2D, useGoogleMapViewState } from '@mapconductor/react-for-googlemaps';
import { VectorTileLayer } from '@mapconductor/react-vectortile';

const TOKYO = createGeoPoint({ latitude: 35.6812, longitude: 139.7671 });
const STYLE_URL = 'https://tiles.versatiles.org/assets/styles/colorful/style.json';

export function VectorTileMap() {
  const state = useGoogleMapViewState({
    apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
    mapDesignType: GoogleMapDesign.None,
    cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
  });

  return (
    <GoogleMapView2D state={state} style={{ height: 480 }}>
      <VectorTileLayer style={STYLE_URL} onDiagnostics={(messages) => console.warn(messages)} />
    </GoogleMapView2D>
  );
}

style은 내용으로 비교합니다. 같은 내용이면 매번 새 객체를 만들어 전달해도 다시 그리지 않습니다.

04 · 모양 바꾸기

rules에 지도 스타일 바꾸기에서 작성하는 규칙을 전달하면, 색을 바꾸거나 레이어를 숨기는 등의 조정을 적용한 상태로 그립니다. 숨긴 역할(건물·라벨 등)은 애초에 그려지지 않습니다.

TypeScriptTypeScript · React
import { useMemo } from 'react';
import { buildStyleRules, LayerRole } from '@mapconductor/js-vectorstyle';
import { VectorTileLayer } from '@mapconductor/react-vectortile';

const rules = useMemo(
  () => buildStyleRules((r) => {
    r.role(LayerRole.building, { visible: false });
    r.role(LayerRole.water, { colorFilter: { mix: { color: '#3a7ca5', amount: 0.6 } } });
    r.role(LayerRole.label, { opacity: 0.6 });
  }),
  [],
);

<VectorTileLayer style={STYLE_URL} rules={rules} />

규칙이나 스타일을 바꾸면 메모리에 있는 벡터 타일을 다시 그리기만 하고, 네트워크로 가져가지 않습니다. 형태는 변하지 않고 칠하는 방법만 바뀌었기 때문입니다. 슬라이더로 색을 움직이는 식의 사용이라도 통신은 늘지 않습니다. rules를 생략하면 규칙 컴파일러(wasm)는 로드되지 않습니다.

05 · 베이스맵으로 사용하기

asBasemap을 붙이면 MapLibre·Mapbox·MapTiler에서는 래스터로 만들지 않고, 스타일을 그대로 지도에 전달하여 지도 디자인과 교체합니다. 이 3개는 직접 벡터 스타일을 그릴 수 있으므로 그쪽이 더 빠르고 깔끔합니다. 이때 opacity는 적용되지 않습니다.

TypeScriptTypeScript · React
import { MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
import { VectorTileLayer } from '@mapconductor/react-vectortile';

<MapLibreMapView2D state={state}>
  <VectorTileLayer style={STYLE_URL} rules={rules} asBasemap />
</MapLibreMapView2D>

그 외 프로바이더에서는 asBasemap은 아무것도 바꾸지 않습니다. 프로바이더 자체 지도는 앱 쪽에서 None 디자인으로 하여 지우십시오.

06 · 주요 프로퍼티

프로퍼티
기본값
설명
style
—
style.json의 URL·문자열·객체. 필수.
rules
—
js-vectorstyle의 규칙. 생략하면 스타일을 그대로 그린다.
opacity
1
레이어 전체의 불투명도.
visible
true
표시할지 여부.
tileSize
512
출력할 타일의 크기(px). 프로바이더의 희망이 있으면 그쪽 우선(ArcGIS 3D는 256).
maxZoom
22
그리는 최대 줌.
headers
—
소스의 타일을 가져올 때 붙이는 헤더입니다. 토큰이나 API 키에 사용합니다.
asBasemap
false
벡터 대응 지도에서는 스타일을 지도에 직접 전달한다.
onDiagnostics
—
그릴 수 없는 레이어 타입, 가져올 수 없는 소스 등, 의도한 대로 그릴 수 없는 이유.

키가 필요한 타일 사용하기

TypeScriptTypeScript · React
<VectorTileLayer
  style="https://tiles.example.com/styles/basic/style.json"
  headers={{ Authorization: `Bearer ${token}` }}
/>

07 · 현재의 제한

라벨도 래스터이므로, 지도를 회전하면 글자도 함께 회전합니다.
Mapbox의 imports와 일부 레이어 타입은 그리지 않습니다. onDiagnostics에 표시됩니다.
MapKit과 Mappls는 '지도 없음' 디자인이 없기 때문에, 불투명한 타일 아래에서 프로바이더 자체의 지도도 함께 로드됩니다.
*MapView 안에 넣어야 합니다. 지도 밖에서는 동작하지 않습니다.

관련 페이지