为 DeckGL HexagonLayer 重新加载数据数组 changes/Triggering 时重新加载 DeckGL HexagonLayer

Reloading DeckGL HexagonLayer when data array changes/Triggering reload for DeckGL HexagonLayer

我正在使用 DeckGL 和 React 在 OpenStreetMap 上显示一些数据。 我计划实施一些过滤器,以便能够显示我拥有的数据的不同视图。 我的主要问题是,我不知道如何在过滤数据数组后刷新数据表示层。

我看到一群人在 JavaScript 中创建了一个 DeckGL 对象,然后使用它来调用 deck.setProps() 但我不知道如何渲染这个 DeckGL 对象使用反应。

这是我的 app.js:

export default function App({showBorder = false, onTilesLoad = null}) {
  layers = [
    /**
     * TileLayer ist ein Layer aus Open-Streetmap-Tiles (Anzeigen der Karte)
     */
    new TileLayer({
      data: [/*OSM TileServer*/],
      maxRequests: 20,
      pickable: true,
      onViewportLoad: onTilesLoad,
      autoHighlight: showBorder,
      highlightColor: [60, 60, 60, 40],
      minZoom: 0,
      maxZoom: 19,
      tileSize: 512 / devicePixelRatio,
      renderSubLayers: (props) => {
        const {
          bbox: {west, south, east, north}
        } = props.tile;
        return [
          new BitmapLayer(props, {
            data: null,
            image: props.data,
            bounds: [west, south, east, north]
          }),
          showBorder &&
            new PathLayer({
              id: `${props.id}-border`,
              visible: props.visible,
              data: [
                [
                  [west, north],
                  [west, south],
                  [east, south],
                  [east, north],
                  [west, north]
                ]
              ],
              getPath: (d) => d,
              getColor: [255, 0, 0],
              widthMinPixels: 4
            })
        ];
      }
    }),
    new HexagonLayer({
      id: 'hexagon-layer',
      data: /*JsonDataArray*/,
      pickable: true,
      extruded: true,
      radius: 2000,
      elevationRange: [25, 500],
      elevationScale: 200,
      autoHighlight: true,
      opacity: 0.2,
      colorRange: [
        [255, 255, 204],
        [199, 233, 180],
        [127, 205, 187],
        [65, 182, 196],
        [44, 127, 184],
        [37, 52, 148]
      ],
      getElevationHeight: () => 500,
      getPosition: (d) => d.coordinates,
    })
  ];

  return (
    <DeckGL
      layers={layers}
      views={new MapView({repeat: true})}
      initialViewState={INITIAL_VIEW_STATE}
      controller={true}
    />
  );
}

显然我的app.js还有更多内容,但我认为缺少的部分并不重要,因为我只想知道如何刷新图层。

我也有一个 index.html,但我认为它的内容也不是真正相关的,因为它的唯一用途是调用 App 函数来渲染图层。

我只是不知道该怎么做才能重新加载 HexagonLayer。

提前感谢您的帮助。

  1. 一个好的方法是使用 DataFilterExtension。基于 GPU 的数据 过滤,如果您关心性能,请按此方式进行。为了 扩展的时刻 there is a limitation HexagonLayer,但也许使用 GPUGridLayer 可以帮助您 可视化也。

    即:假设您要过滤定性数据。 filterRange 需要数字边界(定义对象是否 应该被渲染),所以你可以将你的边界设置为 [1, 1] 和 检查某个对象是否与您当前的过滤条件匹配,如果 匹配,getFilterValue 得到 1,所以该对象将被渲染, 否则,不呈现:

     const [filterCondition, setFilter] = useState('');
    
     useEffect(() => {
         // dispatch some action to set the filter
         setFilter('cities');
     }, []);
    
     new ScatterplotLayer({
         ...otherProps,
         getFilterValue: object => object.properties.target === filterCondition ? 1 : 0,
         filterRange: [1, 1],
         extensions: [new DataFilterExtension({ filterSize: 1 })],
         updateTriggers: {
             // It's important to tell deck.gl when to update
             getFilterValue: filterCondition
         }
     });
    
  2. 否则更新您的 data 数组就足够了。这意味着一个 CPU基于数据过滤,如果你的数据不是很大,没关系。 多亏了这样的反应性应该足够了:

    const [yourData, setData] = useState([]);
    
    useEffect(() => {
        // dispatch some action to set data
        setData([newData]);
    }, []);
    
    const layers = [
        new HexagonLayer({
            ...otherProps,
            data: yourData
        });
    ];
    
    return (
        <DeckGL
            ...otherProps,
            layers={layers}
        />
    );
    

P.D:deck.setProps()建议在非反应环境下使用