@@ -15,10 +15,82 @@ import { getGeometryVector } from "./utils.js";
1515import { GeoArrowExtraPickingProps , getPickingInfo } from "./picking.js" ;
1616import { ColorAccessor , FloatAccessor , GeoArrowPickingInfo } from "./types.js" ;
1717import { EXTENSION_NAME } from "./constants.js" ;
18- import { validateAccessors } from "./validate.js" ;
1918import { GeoArrowSolidPolygonLayer } from "./solid-polygon-layer.js" ;
2019import { GeoArrowPathLayer } from "./path-layer.js" ;
2120
21+ /**
22+ * Get the exterior of a PolygonVector or PolygonData as a MultiLineString
23+ *
24+ * Note that casting to a MultiLineString is a no-op of the underlying data
25+ * structure. For the purposes of the PolygonLayer we don't want to cast to a
26+ * LineString because that would change the number of rows in the table.
27+ */
28+ export function getPolygonExterior (
29+ input : ga . vector . PolygonVector ,
30+ ) : ga . vector . MultiLineStringVector ;
31+ export function getPolygonExterior (
32+ input : ga . data . PolygonData ,
33+ ) : ga . data . MultiLineStringData ;
34+
35+ export function getPolygonExterior (
36+ input : ga . vector . PolygonVector | ga . data . PolygonData ,
37+ ) : ga . vector . MultiLineStringVector | ga . data . MultiLineStringData {
38+ if ( "data" in input ) {
39+ return new arrow . Vector ( input . data . map ( ( data ) => getPolygonExterior ( data ) ) ) ;
40+ }
41+
42+ return input ;
43+ }
44+
45+ /**
46+ * Get the exterior of a MultiPolygonVector or MultiPolygonData
47+ *
48+ * Note that for the purposes of the PolygonLayer, we don't want to change the
49+ * number of rows in the table. Instead, we convert each MultiPolygon to a
50+ * single MultiLineString, combining all exteriors of each contained Polygon
51+ * into a single united MultiLineString.
52+ *
53+ * This means that we need to condense both two offset buffers from the
54+ * MultiPolygonVector/Data (geomOffsets and polygonOffsets) into a single
55+ * `geomOffsets` for the new MultiLineStringVector/Data.
56+ */
57+ export function getMultiPolygonExterior (
58+ input : ga . vector . MultiPolygonVector ,
59+ ) : ga . vector . MultiLineStringVector ;
60+ export function getMultiPolygonExterior (
61+ input : ga . data . MultiPolygonData ,
62+ ) : ga . data . MultiLineStringData ;
63+
64+ export function getMultiPolygonExterior (
65+ input : ga . vector . MultiPolygonVector | ga . data . MultiPolygonData ,
66+ ) : ga . vector . MultiLineStringVector | ga . data . MultiLineStringData {
67+ if ( "data" in input ) {
68+ return new arrow . Vector (
69+ input . data . map ( ( data ) => getMultiPolygonExterior ( data ) ) ,
70+ ) ;
71+ }
72+
73+ const geomOffsets : Int32Array = input . valueOffsets ;
74+ const polygonData = ga . child . getMultiPolygonChild ( input ) ;
75+ const polygonOffsets : Int32Array = polygonData . valueOffsets ;
76+ const lineStringData = ga . child . getPolygonChild ( polygonData ) ;
77+
78+ const resolvedOffsets = new Int32Array ( geomOffsets . length ) ;
79+ for ( let i = 0 ; i < resolvedOffsets . length ; ++ i ) {
80+ // Perform the lookup
81+ resolvedOffsets [ i ] = polygonOffsets [ geomOffsets [ i ] ] ;
82+ }
83+
84+ return arrow . makeData ( {
85+ type : new arrow . List ( polygonData . type . children [ 0 ] ) ,
86+ length : input . length ,
87+ nullCount : input . nullCount ,
88+ nullBitmap : input . nullBitmap ,
89+ child : lineStringData ,
90+ valueOffsets : resolvedOffsets ,
91+ } ) ;
92+ }
93+
2294/** All properties supported by GeoArrowPolygonLayer */
2395export type GeoArrowPolygonLayerProps = Omit <
2496 PolygonLayerProps ,
@@ -97,6 +169,11 @@ const defaultProps: DefaultProps<GeoArrowPolygonLayerProps> = {
97169const defaultLineColor : [ number , number , number , number ] = [ 0 , 0 , 0 , 255 ] ;
98170const defaultFillColor : [ number , number , number , number ] = [ 0 , 0 , 0 , 255 ] ;
99171
172+ /** The `GeoArrowPolygonLayer` renders filled, stroked and/or extruded polygons.
173+ *
174+ * GeoArrowPolygonLayer is a CompositeLayer that wraps the
175+ * GeoArrowSolidPolygonLayer and the GeoArrowPathLayer.
176+ */
100177export class GeoArrowPolygonLayer <
101178 ExtraProps extends { } = { } ,
102179> extends CompositeLayer < Required < GeoArrowPolygonLayerProps > & ExtraProps > {
@@ -119,12 +196,12 @@ export class GeoArrowPolygonLayer<
119196 return this . _renderLayers ( polygonVector ) ;
120197 }
121198
122- const MultiPolygonVector = getGeometryVector (
199+ const multiPolygonVector = getGeometryVector (
123200 table ,
124201 EXTENSION_NAME . MULTIPOLYGON ,
125202 ) ;
126- if ( MultiPolygonVector !== null ) {
127- return this . _renderLayers ( MultiPolygonVector ) ;
203+ if ( multiPolygonVector !== null ) {
204+ return this . _renderLayers ( multiPolygonVector ) ;
128205 }
129206
130207 const geometryColumn = this . props . getPolygon ;
@@ -147,16 +224,11 @@ export class GeoArrowPolygonLayer<
147224 ) : Layer < { } > | LayersList | null {
148225 const { data : table } = this . props ;
149226
150- if ( this . props . _validate ) {
151- assert ( ga . vector . isPolygonVector ( geometryColumn ) ) ;
152- validateAccessors ( this . props , table ) ;
153- }
154-
155- let getPath : ga . vector . LineStringVector | ga . vector . MultiLineStringVector ;
227+ let getPath : ga . vector . MultiLineStringVector ;
156228 if ( ga . vector . isPolygonVector ( geometryColumn ) ) {
157- getPath = ga . algorithm . getPolygonExterior ( geometryColumn ) ;
229+ getPath = getPolygonExterior ( geometryColumn ) ;
158230 } else if ( ga . vector . isMultiPolygonVector ( geometryColumn ) ) {
159- getPath = ga . algorithm . getMultiPolygonExterior ( geometryColumn ) ;
231+ getPath = getMultiPolygonExterior ( geometryColumn ) ;
160232 } else {
161233 assert ( false ) ;
162234 }
0 commit comments