ベクタータイルレイヤー
MapLibre 形式のベクタースタイル(style.json)をブラウザの中でラスタータイルに描き、どの地図プロバイダにも重ねられるようにするパッケージです。Google Maps・MapKit・HERE・ArcGIS・Cesium のように、ベクタースタイルを自分では読めない地図でも同じ見た目になります。
01 · 概要
描画は Rust で書いたレンダラーを wasm にしたもので、Web Worker の中で動きます。描いたタイルは SDK のローカルタイルサーバー(Service Worker)から配られ、地図には普通の RasterLayer として載ります。地図の側から見れば、ただのラスターレイヤーです。だからプロバイダを選びません。
レイヤーは2枚に分けて載せます。塗り・線・円の「地面」と、その上の透明な「ラベル」です。フォントが届いたときに描き直すのはラベルの側だけなので、文字が出る瞬間に地図が一度消える、ということが起きません。スタイルの出典(OpenStreetMap など)の帰属表示も自動で付きます。
02 · インストール
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 に入っているファイルを、アプリの公開ディレクトリへコピーしてください。
{
"scripts": {
"postinstall": "cp node_modules/@mapconductor/js-sdk-core/dist/tile-sw.js public/tile-sw.js"
}
}Vite の本番ビルドでは、worker を ES モジュールとして出力する設定が要ります(dev サーバーでは要りません)。
import { defineConfig } from 'vite';
export default defineConfig({
worker: { format: 'es' },
});localhost なら HTTP のままで構いませんが、LAN 内の別の端末から開くときは HTTPS が要ります。03 · 基本の使い方
どの *MapView の中にも置けます。style には style.json の URL・その文字列・パース済みのオブジェクトのどれでも渡せます。下の例は Google Maps 自身の地図を消して(GoogleMapDesign.None)、その上にベクタースタイルを描いています。
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 に 地図のスタイルを変える で書くルールを渡すと、色を変える・レイヤーを隠すといった調整をかけた状態で描きます。隠した役割(建物・ラベルなど)はそもそも描かれません。
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 は効きません。
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 · 主なプロパティ
鍵の要るタイルを使う
<VectorTileLayer
style="https://tiles.example.com/styles/basic/style.json"
headers={{ Authorization: `Bearer ${token}` }}
/>07 · 現在の制限
imports と一部のレイヤー型は描きません。onDiagnostics に出ます。*MapView の中に置く必要があります。地図の外では動きません。