【deck.gl×React】ポイントデータを表示

## はじめに
deck.glのいろんなレイヤを使ってポイントデータを表示してみます。
今回は、ScatterplotLayer、IconLayer、TextLayerを試してみました。

## 前提
create-react-appでReactアプリをセットアップして、必要なライブラリをもろもろインストールした状態からスタートです。（手順は [こちら](https://qiita.com/asahina820/items/6ead76abf4fc7f187dfc)。TypeScriptだと型エラーでこけやすいので、JavaScriptがよいです。。）

背景地図はreact-map-glとMapLibre GL JSを使います。（詳しくは [こちら](https://qiita.com/asahina820/items/775f77fb646dc1ef6b51) ）

deck.glで使うレイヤを別の関数から呼び出します。
表示するポイントデータは適当な連想配列にしました。

```react:App.js
// deck.gl
import DeckGL from '@deck.gl/react';
// react-map-gl
import Map from 'react-map-gl';
// MapLibre GL JS
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import './style.css';
import { RenderLayers } from './RenderLayers';

const App = () => {
    // 初期ビューポートの設定
    const INITIAL_VIEW_STATE = {
        latitude: 35.688584,
        longitude: 139.7454316,
        bearing: 0,
        pitch: 0,
        zoom: 12,
    };
    const data = [
        { name: '東京タワー', lng: 139.7454316, lat: 35.658584 },
        { name: '東京スカイツリー', lng: 139.8108103, lat: 35.7100069 },
    ];

    return (
        <div className="App">
            <DeckGL initialViewState={INITIAL_VIEW_STATE} controller={true} layers={RenderLayers({ data: data })}>
                <Map mapLib={maplibregl} mapStyle="https://tile.openstreetmap.jp/styles/osm-bright-ja/style.json" />
            </DeckGL>
        </div>
    );
};

export default App;
```



## ScatterplotLayer
与えられた座標に円を描画するレイヤです。

```RenderLayers.js
import { ScatterplotLayer } from '@deck.gl/layers';

export function RenderLayers(props) {
    const point = new ScatterplotLayer({
        id: 'scatterplot-layer',
        data: props.data,
        pickable: false,
        opacity: 0.8,
        stroked: true,
        filled: true,
        radiusScale: 6,
        radiusMinPixels: 1,
        radiusMaxPixels: 100,
        lineWidthMinPixels: 1,
        getPosition: (d) => {
            return [d.lng, d.lat];
        },
        getRadius: 10,
        getFillColor: (d) => [255, 140, 0],
        getLineColor: (d) => [0, 0, 0],
    });

    //レイヤーの重なり順を配列で指定(先頭のレイヤーが一番下になる)
    return [point];
}
```

画面表示はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/e31d6c9e-66ef-1e0d-6030-d81f3301cf2c.png)

## IconLayer
与えられた座標にラスターアイコンを描画するレイヤです。

```RenderLayers.js
import { IconLayer } from '@deck.gl/layers';

export function RenderLayers(props) {
    const ICON_MAPPING = {
        marker: { x: 0, y: 0, width: 128, height: 128, mask: true },
    };

    const point = new IconLayer({
        id: 'icon-layer',
        data: props.data,
        pickable: false,
        iconAtlas: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.png',
        iconMapping: ICON_MAPPING,
        getIcon: (d) => 'marker',
        sizeScale: 10,
        getPosition: (d) => {
            return [d.lng, d.lat];
        },
        getSize: (d) => 5,
        getColor: (d) => [255, 140, 0],
    });

    //レイヤーの重なり順を配列で指定(先頭のレイヤーが一番下になる)
    return [point];
}
```

画面表示はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/4e86f34e-e1ae-e972-56c4-1924741d802a.png)


https://deck.gl/docs/api-reference/layers/icon-layer

## TextLayer
与えられた座標にテキストラベルをレンダリングするレイヤです。

```RenderLayers.js
import { TextLayer } from '@deck.gl/layers';

export function RenderLayers(props) {
    const point = new TextLayer({
        id: 'text-layer',
        data: props.data,
        pickable: false,
        characterSet: 'auto',
        getPosition: (d) => {
            return [d.lng, d.lat];
        },
        getText: (d) => d.name,
        getSize: 20,
        getAngle: 0,
        getTextAnchor: 'middle',
        getAlignmentBaseline: 'center',
    });

    //レイヤーの重なり順を配列で指定(先頭のレイヤーが一番下になる)
    return [point];
}
```

`characterSet`を指定しないと日本語は表示できません。（デフォルトが ASCII characters 32-128のため）
`auto` を指定するとデータで使用されている文字を自動的に検出してくれます。

画面表示はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/eec62f8f-ae53-621b-bad1-95d9f55f61ea.png)

https://deck.gl/docs/api-reference/layers/text-layer

## 参考文献
https://deck.gl/docs/get-started/using-with-react