🌍

deck.glのカスタムレイヤでオートハイライトしたい

2024/06/28に公開

はじめに

deck.glでカスタムレイヤを作成した際、オートハイライトが機能せず苦戦したので解決策を残します。同じく苦戦している方の助けになれば幸いです。

前提

主要なライブラリのバージョン

  • Vue3: ^3.4.29
  • deck.gl: ^8.9.35

今回はGoogleMapをベース地図として、CompositeLayerを継承したカスタムレイヤを表示させています。

やりたいこと

カスタムレイヤ上のオブジェクトのホバー時に色を変えたい。
ホバーイベントを検知してレイヤを更新(再描画)する方法では描画コストが高くパフォーマンスの面で懸念があるため、deck.glで提供されているオートハイライトを利用したい。

解決策

コード例
import { GeoJsonLayer } from '@deck.gl/layers/typed';
import { CompositeLayer, PickingInfo } from '@deck.gl/core/typed';
import { GeoJSON } from 'geojson';

export class MyLayer extends CompositeLayer<{ data: GeoJSON }> {

  // MyLayerのオブジェクトをホバーすると自動で呼ばれる
  getPickingInfo({ info, sourceLayer }) {
    if (info.picked) {
      console.log('pickされました');
    }
    return info;
  }

  // ハイライト色を定義
  getAutoHighlightColor() {
    return [255, 212, 248, 100];
  }

  // MyLayerのオブジェクトをホバーすると自動で呼ばれる
  updateAutoHighlight(info: PickingInfo): void {
    for (const layer of this.getSubLayers()) {
      layer.updateAutoHighlight(info);
    }
  }

  renderLayers() {
    return [
      new GeoJsonLayer({
        id: `my-layer-1`,
        data: this.props.data,
        pickable: true,
        stroked: true,
        pointType: 'circle',
        getPointRadius: 100,
        getFillColor: [51, 0, 102, 125],
        getLineColor: [0, 0, 255, 125],
        getLineWidth: 100,
        autoHighlight: true,
        highlightColor: () => this.getAutoHighlightColor(),
      }),
    ];
  }
}

LineTestLayer.layerName = `MyLayer`;

重要なポイントはカスタムレイヤのクラスにupdateAutoHighlight()を実装し、サブレイヤでそれぞれupdateAutoHighlight()を実行することです。

export class LineTestLayer extends CompositeLayer<{ data: GeoJSON }> {
  // 省略...

  updateAutoHighlight(info: PickingInfo): void {
    for (const layer of this.getSubLayers()) {
      layer.updateAutoHighlight(info);
    }
  }

new GeoJsonLayer()するときにautoHighlight: trueを指定しただけは不十分でした。

  renderLayers() {
    return [
      new GeoJsonLayer({
        id: `my-layer-1`,
        data: this.props.data,
        pickable: true,  <- ホバーイベントを検知するために必須
        stroked: true,
        pointType: 'circle',
        getPointRadius: 100,
        getFillColor: [51, 0, 102, 125],
        getLineColor: [0, 0, 255, 125],
        getLineWidth: 100,
        autoHighlight: true,  <- これだけだと機能しない
        highlightColor: () => this.getAutoHighlightColor(),
      }),
    ];
  }

カスタムレイヤのクラスで実装したupdateAutoHighlight()はホバーイベントハンドラの処理の中で明示的に呼び出す必要はなく、カスタムレイヤ上のオブジェクトをホバーすると自動的に実行されます。

今回はCompositeLayerを継承してカスタムレイヤを作成しましたが、他のレイヤを継承した場合も同様の方法で解決できるかと思います。

deck.glのカスタムレイヤ難しい...

参考

https://github.com/visgl/deck.gl/discussions/7591

レスキューナウテックブログ

Discussion