@wayz/react-gl
Version:
React Component for DeckGL, Base on AMap, Mapbox GL
133 lines (132 loc) • 5.46 kB
JavaScript
import { PolygonLayer } from '@deck.gl/layers';
import { CompositeLayer } from '@deck.gl/core';
import { polygon } from '@turf/helpers';
import centerOfMass from '@turf/center-of-mass';
import TextmapLayer from '../textmap-layer/textmap-layer';
const defaultProps = {
// Inherit all of PolygonLayer's props
...PolygonLayer.defaultProps,
// Label for each feature
getLabel: { type: 'accessor', value: (x) => x.text },
// Label size for each feature
getLabelSize: { type: 'accessor', value: 32 },
// Label color for each feature
getLabelColor: { type: 'accessor', value: [0, 0, 0, 255] },
// Whether to render background for the text blocks
background: false,
// Label background color
getLabelBackground: { type: 'accessor', value: [255, 255, 255, 255] },
// Label not facing the camera
billboard: true,
// Label size units
labelSizeUnits: 'pixels',
// Label font
fontFamily: 'Monaco, monospace',
};
class LabeledPolygonLayer extends CompositeLayer {
updateState({ changeFlags }) {
const { data } = this.props;
if (changeFlags.dataChanged && data) {
const characterSet = new Set();
const labelData = data.flatMap((f, index) => {
this.setCharacterSet(f, characterSet);
const labelAnchors = this.getLabelAnchors(f);
return labelAnchors.map((p) => this.getSubLayerRow({ position: p }, f, index));
});
this.setState({ labelData, characterSet });
}
}
// get center mass
getLabelAnchors(f) {
let { getPolygon } = this.props;
getPolygon = getPolygon ? getPolygon : (f) => f.polygon;
const pl = getPolygon(f);
return [centerOfMass(polygon(pl)).geometry.coordinates];
}
// set characterSet
setCharacterSet(f, characterSet) {
let { getLabel } = this.props;
getLabel = getLabel ? getLabel : (f) => f.text;
getLabel(f)
.split('')
.forEach((s) => characterSet.add(s));
}
renderLayers() {
// Layer prop
const { data } = this.props;
// Rendering props underlying layer
const { elevationScale, extruded, wireframe, filled, stroked, lineWidthUnits, lineWidthScale, lineWidthMinPixels, lineWidthMaxPixels, lineJointRounded, lineMiterLimit, getPolygon, getPolygonOffset, getElevation, getFillColor, getLineColor, getLineWidth,
//@ts-ignore
lineDashJustified,
//@ts-ignore
getLineDashArray, } = this.props;
const { fontFamily, billboard, labelSizeUnits, background, characterSet, getLabel, getLabelColor, getLabelSize, getLabelBackground, } = this.props;
// Accessor props for underlying layers
const { updateTriggers, material } = this.props;
// Filled Polygon Layer
const CellLayer = this.getSubLayerClass('labeled-cell', PolygonLayer);
return [
new CellLayer({
filled,
wireframe,
extruded,
elevationScale,
stroked,
lineWidthUnits,
lineWidthScale,
lineWidthMinPixels,
lineWidthMaxPixels,
lineJointRounded,
lineMiterLimit,
lineDashJustified,
material,
getPolygon,
getPolygonOffset,
getElevation,
getFillColor,
getLineColor,
getLineWidth,
getLineDashArray,
}, this.getSubLayerProps({
id: 'labeled-cell',
updateTriggers: {
getPolygon: updateTriggers.getPolygon,
getPolygonOffset: updateTriggers.getPolygonOffset,
getElevation: updateTriggers.getElevation,
getFillColor: updateTriggers.getFillColor,
getLineColor: updateTriggers.getLineColor,
getLineWidth: updateTriggers.getLineWidth,
getLineDashArray: updateTriggers.getLineDashArray,
},
}), {
data,
}),
new TextmapLayer({
data: this.state.labelData,
characterSet: characterSet ? characterSet : this.state.characterSet,
sizeUnits: labelSizeUnits,
background,
fontFamily,
billboard,
}, this.getSubLayerProps({
id: 'textamap',
updateTriggers: {
getPosition: updateTriggers.getPosition,
getText: updateTriggers.getLabel,
getSize: updateTriggers.getLabelSize,
getColor: updateTriggers.getLabelColor,
getBackgroundColor: updateTriggers.getLabelBackground,
},
}), {
getPosition: (d) => d.position,
getText: this.getSubLayerAccessor(getLabel),
getSize: this.getSubLayerAccessor(getLabelSize),
getColor: this.getSubLayerAccessor(getLabelColor),
getBackgroundColor: this.getSubLayerAccessor(getLabelBackground),
}),
];
}
}
LabeledPolygonLayer.layerName = 'LabeledPolygonLayer';
LabeledPolygonLayer.defaultProps = defaultProps;
export default LabeledPolygonLayer;