Skip to content

Commit 9720ef6

Browse files
authored
Add column layer and h3 hexagon layer (#68)
* ColumnLayer * remove unused imports * Add geo-layers * wip * simplify column layer props * wip * wip * Add h3 hexagon layer * export hex layer with underscore
1 parent e1d3a6e commit 9720ef6

File tree

7 files changed

+393
-2
lines changed

7 files changed

+393
-2
lines changed

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@
3939
"peerDependencies": {
4040
"@deck.gl/aggregation-layers": "^8.9.23",
4141
"@deck.gl/core": "^8.9.23",
42+
"@deck.gl/geo-layers": "^8.9.23",
4243
"@deck.gl/layers": "^8.9.23",
4344
"@math.gl/polygon": "^3.6.2",
4445
"apache-arrow": "^13.0.0"
4546
},
4647
"devDependencies": {
4748
"@deck.gl/aggregation-layers": "^8.9.23",
4849
"@deck.gl/core": "^8.9.23",
50+
"@deck.gl/geo-layers": "^8.9.23",
4951
"@deck.gl/layers": "^8.9.23",
5052
"@math.gl/polygon": "^3.6.2",
5153
"@rollup/plugin-terser": "^0.4.3",

src/arc-layer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export type GeoArrowArcLayerProps = Omit<
4242

4343
/** Properties added by GeoArrowArcLayer */
4444
type _GeoArrowArcLayerProps = {
45-
data?: arrow.Table;
45+
data: arrow.Table;
4646

4747
/**
4848
* Method called to retrieve the source position of each object.
@@ -139,6 +139,8 @@ export class GeoArrowArcLayer<
139139
}
140140
}
141141

142+
// Note: below we iterate over table batches anyways, so this layer won't
143+
// work as-is if data/table is null
142144
validatePointType(sourcePosition.type);
143145
validatePointType(targetPosition.type);
144146
if (table) {

src/column-layer.ts

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import {
2+
CompositeLayer,
3+
CompositeLayerProps,
4+
DefaultProps,
5+
GetPickingInfoParams,
6+
Layer,
7+
LayersList,
8+
} from "@deck.gl/core/typed";
9+
import { ColumnLayer } from "@deck.gl/layers/typed";
10+
import type { ColumnLayerProps } from "@deck.gl/layers/typed";
11+
import * as arrow from "apache-arrow";
12+
import {
13+
assignAccessor,
14+
getGeometryVector,
15+
getPointChild,
16+
isPointVector,
17+
validateColorVector,
18+
validatePointType,
19+
validateVectorAccessors,
20+
} from "./utils.js";
21+
import {
22+
ColorAccessor,
23+
FloatAccessor,
24+
GeoArrowPickingInfo,
25+
PointVector,
26+
} from "./types.js";
27+
import { EXTENSION_NAME } from "./constants.js";
28+
import { getPickingInfo } from "./picking.js";
29+
30+
/** All properties supported by GeoArrowColumnLayer */
31+
export type GeoArrowColumnLayerProps = Omit<
32+
ColumnLayerProps<arrow.Table>,
33+
| "data"
34+
| "getPosition"
35+
| "getFillColor"
36+
| "getLineColor"
37+
| "getElevation"
38+
| "getLineWidth"
39+
> &
40+
_GeoArrowColumnLayerProps &
41+
CompositeLayerProps;
42+
43+
/** Properties added by GeoArrowColumnLayer */
44+
type _GeoArrowColumnLayerProps = {
45+
data: arrow.Table;
46+
47+
/**
48+
* Method called to retrieve the position of each column.
49+
* @default object => object.position
50+
*/
51+
getPosition?: PointVector;
52+
53+
/**
54+
* Fill color value or accessor.
55+
* @default [0, 0, 0, 255]
56+
*/
57+
getFillColor?: ColorAccessor;
58+
59+
/**
60+
* Line color value or accessor.
61+
*
62+
* @default [0, 0, 0, 255]
63+
*/
64+
getLineColor?: ColorAccessor;
65+
66+
/**
67+
* The elevation of each cell in meters.
68+
* @default 1000
69+
*/
70+
getElevation?: FloatAccessor;
71+
72+
/**
73+
* The width of the outline of the column, in units specified by `lineWidthUnits`.
74+
*
75+
* @default 1
76+
*/
77+
getLineWidth?: FloatAccessor;
78+
79+
/**
80+
* If `true`, validate the arrays provided (e.g. chunk lengths)
81+
* @default true
82+
*/
83+
_validate?: boolean;
84+
};
85+
86+
// Remove data and getPosition from the upstream default props
87+
const {
88+
data: _data,
89+
getPosition: _getPosition,
90+
..._defaultProps
91+
} = ColumnLayer.defaultProps;
92+
93+
const defaultProps: DefaultProps<GeoArrowColumnLayerProps> = {
94+
..._defaultProps,
95+
_validate: true,
96+
};
97+
98+
/**
99+
* Render extruded cylinders (tessellated regular polygons) at given
100+
* coordinates.
101+
*/
102+
export class GeoArrowColumnLayer<
103+
ExtraProps extends {} = {}
104+
> extends CompositeLayer<Required<GeoArrowColumnLayerProps> & ExtraProps> {
105+
static defaultProps = defaultProps;
106+
static layerName = "GeoArrowColumnLayer";
107+
108+
getPickingInfo(params: GetPickingInfoParams): GeoArrowPickingInfo {
109+
return getPickingInfo(params, this.props.data);
110+
}
111+
112+
renderLayers(): Layer<{}> | LayersList | null {
113+
const { data: table } = this.props;
114+
115+
const pointVector = getGeometryVector(table, EXTENSION_NAME.POINT);
116+
if (pointVector !== null) {
117+
return this._renderLayersPoint(pointVector);
118+
}
119+
120+
const geometryColumn = this.props.getPosition;
121+
if (isPointVector(geometryColumn)) {
122+
return this._renderLayersPoint(geometryColumn);
123+
}
124+
125+
throw new Error("geometryColumn not point");
126+
}
127+
128+
_renderLayersPoint(
129+
geometryColumn: PointVector
130+
): Layer<{}> | LayersList | null {
131+
const { data: table } = this.props;
132+
133+
if (this.props._validate) {
134+
const vectorAccessors: arrow.Vector[] = [geometryColumn];
135+
for (const accessor of [
136+
this.props.getFillColor,
137+
this.props.getLineColor,
138+
this.props.getLineWidth,
139+
this.props.getElevation,
140+
]) {
141+
if (accessor instanceof arrow.Vector) {
142+
vectorAccessors.push(accessor);
143+
}
144+
}
145+
146+
validatePointType(geometryColumn.type);
147+
validateVectorAccessors(table, vectorAccessors);
148+
149+
if (this.props.getFillColor instanceof arrow.Vector) {
150+
validateColorVector(this.props.getFillColor);
151+
}
152+
if (this.props.getLineColor instanceof arrow.Vector) {
153+
validateColorVector(this.props.getLineColor);
154+
}
155+
}
156+
157+
const layers: ColumnLayer[] = [];
158+
for (
159+
let recordBatchIdx = 0;
160+
recordBatchIdx < table.batches.length;
161+
recordBatchIdx++
162+
) {
163+
const geometryData = geometryColumn.data[recordBatchIdx];
164+
const flatCoordsData = getPointChild(geometryData);
165+
const flatCoordinateArray = flatCoordsData.values;
166+
167+
const props: ColumnLayerProps = {
168+
// @ts-expect-error used for picking purposes
169+
recordBatchIdx,
170+
171+
id: `${this.props.id}-geoarrow-column-${recordBatchIdx}`,
172+
173+
diskResolution: this.props.diskResolution,
174+
radius: this.props.radius,
175+
angle: this.props.angle,
176+
vertices: this.props.vertices,
177+
offset: this.props.offset,
178+
coverage: this.props.coverage,
179+
elevationScale: this.props.elevationScale,
180+
filled: this.props.filled,
181+
stroked: this.props.stroked,
182+
extruded: this.props.extruded,
183+
wireframe: this.props.wireframe,
184+
flatShading: this.props.flatShading,
185+
radiusUnits: this.props.radiusUnits,
186+
lineWidthUnits: this.props.lineWidthUnits,
187+
lineWidthScale: this.props.lineWidthScale,
188+
lineWidthMinPixels: this.props.lineWidthMinPixels,
189+
lineWidthMaxPixels: this.props.lineWidthMaxPixels,
190+
material: this.props.material,
191+
192+
data: {
193+
length: geometryData.length,
194+
attributes: {
195+
getPosition: {
196+
value: flatCoordinateArray,
197+
size: geometryData.type.listSize,
198+
},
199+
},
200+
},
201+
};
202+
203+
assignAccessor({
204+
props,
205+
propName: "getFillColor",
206+
propInput: this.props.getFillColor,
207+
chunkIdx: recordBatchIdx,
208+
});
209+
assignAccessor({
210+
props,
211+
propName: "getLineColor",
212+
propInput: this.props.getLineColor,
213+
chunkIdx: recordBatchIdx,
214+
});
215+
assignAccessor({
216+
props,
217+
propName: "getElevation",
218+
propInput: this.props.getElevation,
219+
chunkIdx: recordBatchIdx,
220+
});
221+
assignAccessor({
222+
props,
223+
propName: "getLineWidth",
224+
propInput: this.props.getLineWidth,
225+
chunkIdx: recordBatchIdx,
226+
});
227+
228+
const layer = new ColumnLayer(this.getSubLayerProps(props));
229+
layers.push(layer);
230+
}
231+
232+
return layers;
233+
}
234+
}

0 commit comments

Comments
 (0)