@wayz/react-gl
Version:
React Component for DeckGL, Base on AMap, Mapbox GL
74 lines (73 loc) • 2.87 kB
JavaScript
import { CompositeLayer } from '@deck.gl/core';
import { IconLayer } from '@deck.gl/layers';
import Supercluster from 'supercluster';
class IconClusterLayer extends CompositeLayer {
shouldUpdateState({ changeFlags }) {
return changeFlags.somethingChanged;
}
updateState({ props, oldProps, changeFlags }) {
var _a;
const rebuildIndex = changeFlags.dataChanged || props.sizeScale !== oldProps.sizeScale;
if (rebuildIndex) {
const index = new Supercluster({
maxZoom: 20,
radius: ((_a = props.sizeScale) !== null && _a !== void 0 ? _a : 1) * Math.sqrt(2),
});
index.load(props.data.map((d) => {
var _a;
return ({
geometry: { coordinates: (_a = props.getPosition) === null || _a === void 0 ? void 0 : _a.call(props, d) },
properties: d,
});
}));
this.setState({ index });
}
const z = Math.floor(this.context.viewport.zoom);
if (rebuildIndex || z !== this.state.z) {
this.setState({
data: this.state.index.getClusters([-180, -85, 180, 85], z).map((object) => {
if (object.properties.cluster) {
object.objects = this.state.index
.getLeaves(object.properties.cluster_id, 25)
.map((f) => f.properties);
}
return object;
}),
z,
});
}
}
getPickingInfo({ info, mode }) {
const pickedObject = info.object && info.object.properties;
if (pickedObject) {
if (pickedObject.cluster && mode !== 'hover') {
info.objects = this.state.index
.getLeaves(pickedObject.cluster_id, 25)
.map((f) => f.properties);
}
info.object = pickedObject;
}
return info;
}
renderLayers() {
const { data } = this.state;
const { updateTriggers } = this.props;
const IconClusterLayer = this.getSubLayerClass('cluster', IconLayer);
return new IconClusterLayer(this.props, this.getSubLayerProps({
id: 'cluster',
updateTriggers: {
getIcon: updateTriggers.getIcon,
getPosition: updateTriggers.getPosition,
getColor: updateTriggers.getColor,
getAngle: updateTriggers.getAngle,
getPixelOffset: updateTriggers.getPixelOffset,
getSize: updateTriggers.getSize,
},
}), {
data,
getPosition: (d) => d.geometry.coordinates,
});
}
}
IconClusterLayer.layerName = 'IconClusterLayer';
export default IconClusterLayer;