UNPKG

@wayz/react-gl

Version:

React Component for DeckGL, Base on AMap, Mapbox GL

189 lines (188 loc) 7.04 kB
import { CompositeLayer } from '@deck.gl/core'; import { TextLayer } from '@deck.gl/layers'; import TextMapWrapper from './textmap-wrapper'; const MAX_CACHED_ZOOM_LEVEL = 5; const defaultProps = { getWeight: { type: 'accessor', value: (x) => x.weight || 1 }, minFontSize: 14, maxFontSize: 32, weightThreshold: 1, }; class TextmapLayer extends CompositeLayer { initializeState() { this.state = { // Cached tags per zoom level tagsCache: {}, tags: [], }; } shouldUpdateState({ changeFlags }) { return changeFlags.somethingChanged; } updateState({ props, oldProps, changeFlags }) { super.updateState({ props, oldProps, changeFlags }); let needsUpdate = changeFlags.viewportChanged; if (changeFlags.dataChanged) { this.updateTagMapData(); needsUpdate = true; } else if (props.minFontSize !== oldProps.minFontSize || props.maxFontSize !== oldProps.maxFontSize || props.weightThreshold !== oldProps.weightThreshold) { this.setState({ tagsCache: {} }); needsUpdate = true; } if (needsUpdate) { this.updateTagMapVis(); } } updateTagMapData() { const { data, getText, getPosition, getWeight } = this.props; const tagMap = new TextMapWrapper(); tagMap.setData(data, { getLabel: getText, getPosition, getWeight }); this.setState({ tagMap, tagsCache: {} }); } updateTagMapVis() { const { tagMap, tagsCache } = this.state; if (!tagMap) { return; } const { viewport } = this.context; const discreteZoomLevel = Math.floor(viewport.zoom); let tags = tagsCache[discreteZoomLevel]; if (tags) { this.setState(tags); return; } const { minFontSize, maxFontSize, weightThreshold } = this.props; let bbox = null; if (discreteZoomLevel > MAX_CACHED_ZOOM_LEVEL) { const { unproject, width, height } = viewport; const corners = [ unproject([0, 0]), unproject([width, 0]), unproject([0, height]), unproject([width, height]), ]; bbox = { minX: Math.min.apply(null, corners.map((p) => p[0])), minY: Math.min.apply(null, corners.map((p) => p[1])), maxX: Math.max.apply(null, corners.map((p) => p[0])), maxY: Math.max.apply(null, corners.map((p) => p[1])), }; } tags = tagMap.getTags({ bbox, minFontSize, maxFontSize, weightThreshold, zoom: discreteZoomLevel, }); const characterSet = new Set(); // 转化tags为输入的初始数据 const data = tags.map((tag) => { this.setCharacterSet(tag.originValue, characterSet); return Object.assign({}, tag.originValue, { position: tag.position }); }); if (discreteZoomLevel <= MAX_CACHED_ZOOM_LEVEL) { tagsCache[discreteZoomLevel] = { tags, data, characterSet }; } this.setState({ tags, data, characterSet }); } // 设置characterSet setCharacterSet(f, characterSet) { let { getText } = this.props; getText = getText ? getText : (f) => f.text; getText(f) .split('') .forEach((s) => characterSet.add(s)); } renderLayers() { const { updateTriggers, characterSet } = this.props; // const { // sizeScale, // sizeUnits, // sizeMinPixels, // sizeMaxPixels, // billboard, // // @ts-expect-error // background, // // @ts-expect-error // backgroundPadding, // fontFamily, // characterSet, // fontWeight, // lineHeight, // fontSettings, // wordBreak, // maxWidth, // // @ts-expect-error // outlineWidth, // // @ts-expect-error // outlineColor, // } = this.props const { //Data Accessors getText, getSize, getColor, // getAngle, //Text Alignment Options // getTextAnchor, // getAlignmentBaseline, // getPixelOffset, getBackgroundColor, getBorderColor, getBorderWidth, } = this.props; const TextMapLayer = this.getSubLayerClass('textmap', TextLayer); return [ new TextMapLayer( // { // sizeScale, // sizeUnits, // sizeMinPixels, // sizeMaxPixels, // billboard, // background, // backgroundPadding, // fontFamily, // fontWeight, // lineHeight, // fontSettings, // wordBreak, // maxWidth, // outlineWidth, // outlineColor, // }, this.props, this.getSubLayerProps({ id: 'textmap', updateTriggers: { getText: updateTriggers.getText, getPosition: updateTriggers.getPosition, getSize: updateTriggers.getSize, getColor: updateTriggers.getColor, getAngle: updateTriggers.getAngle, getTextAnchor: updateTriggers.getTextAnchor, getAlignmentBaseline: updateTriggers.getAlignmentBaseline, getPixelOffset: updateTriggers.getPixelOffset, getBackgroundColor: updateTriggers.getBackgroundColor, getBorderColor: updateTriggers.getBorderColor, getBorderWidth: updateTriggers.getBorderWidth, }, }), { data: this.state.data, characterSet: characterSet ? characterSet : this.state.characterSet, getPosition: (x) => x.position, getText: this.getSubLayerAccessor(getText), getSize: this.getSubLayerAccessor(getSize), getColor: this.getSubLayerAccessor(getColor), // getAngle: this.getSubLayerAccessor(getAngle), // getTextAnchor: this.getSubLayerAccessor(getTextAnchor), // getAlignmentBaseline: this.getSubLayerAccessor(getAlignmentBaseline), // getPixelOffset: this.getSubLayerAccessor(getPixelOffset), getBackgroundColor: this.getSubLayerAccessor(getBackgroundColor), getBorderColor: this.getSubLayerAccessor(getBorderColor), getBorderWidth: this.getSubLayerAccessor(getBorderWidth), }), ]; } } TextmapLayer.layerName = 'TextmapLayer'; TextmapLayer.defaultProps = defaultProps; export default TextmapLayer;