当数据数组更改时重新加载 DeckGL HexagonLayer/触发重新加载 DeckGL HexagonLayer

时间:2020-12-21 15:30:22

标签: javascript reactjs deck.gl

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

我看到很多人在 JavaScript 中创建了一个 DeckGL-Object,然后使用它来调用 deck.setProps(),但我不知道如何使用 react 来渲染这个 DeckGL-Object。

这是我的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 个答案:

答案 0 :(得分:2)

  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() 建议在非反应环境中使用

相关问题