diff --git a/examples/point/app.tsx b/examples/point/app.tsx index cf66a52..1ff5a0a 100644 --- a/examples/point/app.tsx +++ b/examples/point/app.tsx @@ -4,6 +4,7 @@ import { StaticMap, MapContext, NavigationControl } from "react-map-gl"; import DeckGL, { Layer, PickingInfo } from "deck.gl/typed"; import { GeoArrowScatterplotLayer } from "@geoarrow/deck.gl-layers"; import * as arrow from "apache-arrow"; +import type { Loader, LoaderWithParser } from "@loaders.gl/loader-utils"; const GEOARROW_POINT_DATA = "http://localhost:8080/2019-01-01_performance_mobile_tiles.feather"; @@ -24,6 +25,21 @@ const NAV_CONTROL_STYLE = { left: 10, }; +const GeoArrowIPCLoader: LoaderWithParser = { + name: "geoarrow-ipc", + id: "geoarrow-ipc", + module: "arrow", + version: "latest", + worker: false, + options: {}, + extensions: ["feather", "arrow"], + mimeTypes: [], + binary: true, + parse: async (arrayBuffer) => { + return arrow.tableFromIPC(arrayBuffer); + }, +}; + function Root() { const onClick = (info: PickingInfo) => { if (info.object) { @@ -31,36 +47,20 @@ function Root() { } }; - const [table, setTable] = useState(null); - - useEffect(() => { - // declare the data fetching function - const fetchData = async () => { - const data = await fetch(GEOARROW_POINT_DATA); - const buffer = await data.arrayBuffer(); - const table = arrow.tableFromIPC(buffer); - setTable(table); - }; - - if (!table) { - fetchData().catch(console.error); - } - }); - const layers: Layer[] = []; - table && - layers.push( - new GeoArrowScatterplotLayer({ - id: "geoarrow-points", - data: table, - getFillColor: table.getChild("colors")!, - radiusMinPixels: 1.5, - getPointRadius: 10, - pointRadiusMinPixels: 0.8, - pickable: true, - }) - ); + layers.push( + new GeoArrowScatterplotLayer({ + id: "geoarrow-points", + data: GEOARROW_POINT_DATA, + getFillColor: ((table: arrow.Table) => table.getChild("colors")!), + radiusMinPixels: 1.5, + getPointRadius: 10, + pointRadiusMinPixels: 0.8, + pickable: true, + loaders: [GeoArrowIPCLoader], + }) + ); return ( arrow.Vector>) | arrow.Vector> | Accessor; /** @@ -170,6 +173,40 @@ export class GeoArrowScatterplotLayer< static defaultProps = defaultProps; static layerName = "GeoArrowScatterplotLayer"; + declare state: CompositeLayer["state"] & { + table: arrow.Table | null; + } + + initializeState(_context: LayerContext): void { + this.state = { + table: null, + }; + } + + async updateData() { + const { data, fetch, loadOptions, loaders } = this.props; + + if (this.props.data instanceof arrow.Table) { + console.log("set state data"); + this.setState({ table: this.props.data }); + } else if (typeof data === "string") { + const newData = await fetch(data, { + propName: "data", + layer: this, + loaders, + loadOptions, + }); + this.setState({table: newData}); + } + } + + updateState({ props, changeFlags }: UpdateParameters): void { + console.log("updateState"); + if (changeFlags.dataChanged) { + this.updateData(); + } + } + getPickingInfo({ info, sourceLayer, @@ -207,7 +244,7 @@ export class GeoArrowScatterplotLayer< } renderLayers(): Layer<{}> | LayersList | null { - const { data: table } = this.props; + const { table } = this.state; const pointVector = getGeometryVector(table, EXTENSION_NAME.POINT); if (pointVector !== null) { @@ -237,7 +274,7 @@ export class GeoArrowScatterplotLayer< _renderLayersPoint( geometryColumn: PointVector ): Layer<{}> | LayersList | null { - const { data: table } = this.props; + const { table } = this.state; if (this.props._validate) { const vectorAccessors: arrow.Vector[] = [geometryColumn]; @@ -335,7 +372,7 @@ export class GeoArrowScatterplotLayer< _renderLayersMultiPoint( geometryColumn: MultiPointVector ): Layer<{}> | LayersList | null { - const { data: table } = this.props; + const { table } = this.state; // TODO: validate that if nested, accessor props have the same nesting // structure as the main geometry column.