Skip to content

Commit

Permalink
[feat] Layer property additions: H3 Layer: Add text labels (#2243)
Browse files Browse the repository at this point in the history
Signed-off-by: Ihor Dykhta <dikhta.igor@gmail.com>
Co-authored-by: Xun Li <lixun910@gmail.com>
  • Loading branch information
igorDykhta and lixun910 committed Jun 9, 2023
1 parent 9ba6bcd commit 94cb2a1
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 5 deletions.
Expand Up @@ -555,6 +555,13 @@ export default function LayerConfiguratorFactory(
/>
</ConfigGroupCollapsibleContent>
</LayerConfigGroup>

{/* text label */}
<TextLabelPanel
fields={visConfiguratorProps.fields}
updateLayerTextLabel={this.props.updateLayerTextLabel}
textLabel={layer.config.textLabel}
/>
</StyledLayerVisualConfigurator>
);
}
Expand Down
49 changes: 46 additions & 3 deletions src/layers/src/h3-hexagon-layer/h3-hexagon-layer.ts
Expand Up @@ -26,6 +26,7 @@ import Layer, {
LayerCoverageConfig,
LayerSizeConfig
} from '../base-layer';
import {BrushingExtension} from '@deck.gl/extensions';
import {GeoJsonLayer} from '@deck.gl/layers';
import {H3HexagonLayer} from '@deck.gl/geo-layers';
import {EnhancedColumnLayer} from '@kepler.gl/deckgl-layers';
Expand All @@ -51,6 +52,8 @@ import {
} from '@kepler.gl/types';
import {KeplerTable} from '@kepler.gl/table';

import {getTextOffsetByRadius, formatTextLabelData} from '../layer-text-label';

export type HexagonIdLayerColumnsConfig = {
hex_id: LayerColumn;
};
Expand Down Expand Up @@ -118,6 +121,7 @@ export const HexagonIdVisConfigs: {
enableElevationZoomFactor: 'enableElevationZoomFactor'
};

const brushingExtension = new BrushingExtension();
export default class HexagonIdLayer extends Layer {
dataToFeature: {centroids: Centroid[]};

Expand Down Expand Up @@ -253,13 +257,25 @@ export default class HexagonIdLayer extends Layer {
}
const {gpuFilter, dataContainer} = datasets[this.config.dataId];
const getHexId = this.getPositionAccessor(dataContainer);
const {data} = this.updateData(datasets, oldLayerData);
const {data, triggerChanged} = this.updateData(datasets, oldLayerData);
const accessors = this.getAttributeAccessors({dataContainer});
const {textLabel} = this.config;

// get all distinct characters in the text labels
const textLabels = formatTextLabelData({
textLabel,
triggerChanged,
oldLayerData,
data,
dataContainer
});

return {
data,
getHexId,
getFilterValue: gpuFilter.filterValueAccessor(dataContainer)(),
textLabels,
getPosition: d => d.centroid,
...accessors
};
}
Expand Down Expand Up @@ -289,7 +305,7 @@ export default class HexagonIdLayer extends Layer {
}

renderLayer(opts) {
const {data, gpuFilter, objectHovered, mapState} = opts;
const {data, gpuFilter, objectHovered, mapState, interactionConfig} = opts;

const zoomFactor = this.getZoomFactor(mapState);
const eleZoomFactor = this.getElevationZoomFactor(mapState);
Expand All @@ -311,10 +327,27 @@ export default class HexagonIdLayer extends Layer {
const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
const hoveredObject = this.hasHoveredObject(objectHovered);

// getPixelOffset with no radius
const radiusScale = 1.0;
const getRaidus = null;
const getPixelOffset = getTextOffsetByRadius(radiusScale, getRaidus, mapState);

const brushingProps = this.getBrushingExtensionProps(interactionConfig);
const extensions = [...defaultLayerProps.extensions, brushingExtension];
const sharedProps = {
getFilterValue: data.getFilterValue,
extensions,
filterRange: defaultLayerProps.filterRange,
visible: defaultLayerProps.visible,
...brushingProps
};

return [
new H3HexagonLayer({
...defaultLayerProps,
...data,
...brushingProps,
extensions,
wrapLongitude: false,

getHexagon: (x: any) => x.id,
Expand Down Expand Up @@ -352,7 +385,17 @@ export default class HexagonIdLayer extends Layer {
wrapLongitude: false
})
]
: [])
: []),
// text label layer
...this.renderTextLabelLayer(
{
getPosition: data.getPosition,
sharedProps,
getPixelOffset,
updateTriggers
},
opts
)
];
}
}
78 changes: 76 additions & 2 deletions test/browser/layer-tests/h3-hexagon-layer-specs.js
Expand Up @@ -104,7 +104,9 @@ test('#H3Layer -> formatLayerData', t => {
getFilterValue: () => {},
getFillColor: () => {},
getHexId: () => {},
getCoverage: () => {}
getCoverage: () => {},
getPosition: () => {},
textLabels: () => {}
};
t.deepEqual(
Object.keys(layerData).sort(),
Expand Down Expand Up @@ -226,7 +228,7 @@ test('#H3Layer -> renderLayer', t => {
label: 'h3 hex',
columns,
color: [1, 2, 3],
visCondig: {
visConfig: {
worldUnitSize: 0.5,
elevationScale: 5
}
Expand Down Expand Up @@ -262,6 +264,78 @@ test('#H3Layer -> renderLayer', t => {
t.deepEqual(props[key], expectedProps[key], `should have correct props.${key}`);
});
}
},
{
name: 'Test render h3.2 with text label',
layer: {
id: 'test_layer_2',
type: 'hexagonId',
config: {
dataId,
label: 'h3 hex',
columns,
color: [1, 2, 3],
visConfig: {
worldUnitSize: 0.5,
elevationScale: 5
},
textLabel: [
{
field: {
name: 'types',
format: ''
},
format: ''
}
]
}
},
datasets: {
[dataId]: preparedDataset
},
assert: (deckLayers, layer) => {
t.equal(layer.type, 'hexagonId', 'should create 1 hexagonId layer');

const expectedTextLabels = [
{
field: {
name: 'types',
id: 'types',
displayName: 'types',
format: '',
fieldIdx: 5,
type: 'string',
analyzerType: 'STRING',
valueAccessor: preparedDataset.fields[5].valueAccessor
},
color: [255, 255, 255],
size: 18,
offset: [0, 0],
anchor: 'start',
alignment: 'center'
}
];

t.deepEqual(
layer.config.textLabel,
expectedTextLabels,
'should create textLabel using field "types"'
);

t.equal(deckLayers.length, 4, 'Should create 4 deck.gl layers');
const expectedLayerIds = [
'test_layer_2',
'test_layer_2-hexagon-cell',
'test_layer_2-label-types',
'test_layer_2-label-types-characters'
];

t.deepEqual(
deckLayers.map(l => l.id),
expectedLayerIds,
'should create 1 composite, 1 hexagon-cell layer, 1 text layer, 1 multi-icon layer'
);
}
}
];

Expand Down

0 comments on commit 94cb2a1

Please sign in to comment.