UNPKG

@wayz/react-gl

Version:

React Component for DeckGL, Base on AMap, Mapbox GL

133 lines (132 loc) 5.46 kB
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;