GeoArrowPointCloudLayer does not accept geoarrow encoded 3d points from geoparquet
GeoArrowPointCloudLayer does not accept the geoarrow geometry column of 3d points while GeoArrowScatterPlotLayer handles same column well.
I am getting the error:
deck: initialization of GeoArrowPointCloudLayer({id: 'pointcloud-xyz'}): Points of a PointCloudLayer in the geometry column must be three-dimensional. Error: Points of a PointCloudLayer in the geometry column must be three-dimensional.
this is coming from an assert that checks:
assert( geometryColumn.type.listSize === 3, "Points of a PointCloudLayer in the geometry column must be three-dimensional.", ); (from point-cloud-layer.ts line 142)
Here is how I got this
I have created a GeoParquet file with the following:
import geopandas as gpd
geometry = gpd.points_from_xy(x=df['X'], y=df['Y'], z=df['Z'])
gdf = gpd.GeoDataFrame(df[['point_id']], geometry=geometry, crs="EPSG:4326")
gdf.to_parquet('my_parquet', geometry_encoding='geoarrow')
I then read it into my frontend such:
const response = await fetch(url_to_my_parquet);
const buffer = await response.arrayBuffer();
const pointCloudData = await readParquet(new Uint8Array(buffer), { batchSize: Math.pow(2, 31) });
const table = arrow.tableFromIPC(pointCloudData.intoIPCStream());
const geometryColumn = table.getChild("geometry");
let gps_ref = [40, 40, 0];
...
layer = new GeoArrowPointCloudLayer({
id: "pointcloud-xyz",
data: table,
getPosition: geometryColumn,
getColor: fillColorAccessor,
pointSize: 2,
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
coordinateOrigin: gps_ref,
});
I have verified that when reading the geometryColumn I get 3 columns named 'x','y','z'
(using the code: console.log('Geometry column fields:', geometryColumn.type.children.map(f => f.name)))
and when I try to use a GeoArrowScatterPlotLayer with the same data it works:
layer = new GeoArrowScatterplotLayer({
id: "scatterplot",
data: table,
getPosition: geometryColumn,
getFillColor: [255,0,0,180],
radiusMinPixels: 1,
getRadius: 0.05,
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
coordinateOrigin: gps_ref,
});
What version of deck.gl-layers are you using? This should be fixed in https://github.com/geoarrow/deck.gl-layers/pull/139.
You might want to put a console.log before and after here https://github.com/geoarrow/deck.gl-layers/blob/343eacfffb66ff631d93d7fac99fc8a7d1f868c8/src/layers/point-cloud-layer.ts#L162-L164 to see if this function is getting called https://github.com/geoarrow/deck.gl-layers/blob/343eacfffb66ff631d93d7fac99fc8a7d1f868c8/src/utils/utils.ts#L111
....
oh actually looks like the default validation still assumes the input is a fixed size list geometry
https://github.com/geoarrow/deck.gl-layers/blob/343eacfffb66ff631d93d7fac99fc8a7d1f868c8/src/layers/point-cloud-layer.ts#L137-L147
You can try with setting validate: false as a prop