@wayz/react-gl
Version:
React Component for DeckGL, Base on AMap, Mapbox GL
107 lines (106 loc) • 4.14 kB
JavaScript
// @ts-nocheck
import TagMap from './CustomTagMap';
import RBush from 'rbush';
import { lngLatToWorld, worldToLngLat } from '@math.gl/web-mercator';
function getDrawingContext() {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.font = '10px "Lucida Console", Monaco, monospace';
ctx.fillStyle = '#000';
ctx.textBaseline = 'hanging';
ctx.textAlign = 'left';
return ctx;
}
var TextMapWrapper = /** @class */ (function () {
function TextMapWrapper() {
this.tagMap = null;
this.ctx = getDrawingContext();
this.measureText = this.measureText.bind(this);
this.textSizes = {};
this.weightThreshold = 1;
// cache of layout results
this.clusterCache = {};
}
TextMapWrapper.prototype.setData = function (data, _a) {
var _this = this;
var getLabel = _a.getLabel, getPosition = _a.getPosition, getWeight = _a.getWeight;
this.textSizes = {};
data.forEach(function (d) {
var label = getLabel(d);
_this.textSizes[label] = _this.ctx.measureText(label).width;
});
this.tagMap = new TagMap();
this.tagMap.buildHierarchy(data, { getLabel: getLabel, getPosition: getPosition, getWeight: getWeight });
this.clusterCache = {};
};
TextMapWrapper.prototype.extractCluster = function (_a) {
var scale = _a.scale, weightThreshold = _a.weightThreshold;
var project = function (lngLat) {
var p = lngLatToWorld(lngLat);
p[0] *= scale;
p[1] *= scale;
return p;
};
var tagList = this.tagMap.extractCluster({ project: project, weightThreshold: weightThreshold });
tagList.forEach(function (tag) {
tag.minX = tag.center[0];
tag.minY = tag.center[1];
tag.maxX = tag.center[0];
tag.maxY = tag.center[1];
});
var cluster = new RBush();
cluster.load(tagList);
return cluster;
};
TextMapWrapper.prototype.layout = function (_a) {
var tagList = _a.tagList, scale = _a.scale, minFontSize = _a.minFontSize, maxFontSize = _a.maxFontSize;
var tags = this.tagMap.layout({
tagList: tagList,
minFontSize: minFontSize,
maxFontSize: maxFontSize,
maxNumOfTags: 150,
sizeMeasurer: this.measureText,
});
// transform tags to the format that are used to be visualized as icons in the deckgl layer
tags.forEach(function (tag) {
tag.position = worldToLngLat([tag.center[0] / scale, tag.center[1] / scale]);
});
return tags;
};
TextMapWrapper.prototype.getTags = function (_a) {
var zoom = _a.zoom, bbox = _a.bbox, minFontSize = _a.minFontSize, maxFontSize = _a.maxFontSize, weightThreshold = _a.weightThreshold;
if (weightThreshold !== this.weightThreshold) {
this.weightThreshold = weightThreshold;
this.clusterCache = {};
}
var scale = Math.pow(2, zoom);
var cluster = this.clusterCache[zoom] || this.extractCluster({ scale: scale, weightThreshold: weightThreshold });
this.clusterCache[zoom] = cluster;
var tagList;
if (bbox) {
var sw = lngLatToWorld([bbox.minX, bbox.minY]);
var ne = lngLatToWorld([bbox.maxX, bbox.maxY]);
tagList = cluster.search({
minX: sw[0] * scale,
minY: sw[1] * scale,
maxX: ne[0] * scale,
maxY: ne[1] * scale,
});
}
else {
tagList = cluster.all();
}
return this.layout({
tagList: tagList,
scale: scale,
minFontSize: minFontSize,
maxFontSize: maxFontSize,
});
};
TextMapWrapper.prototype.measureText = function (label, fontSize) {
var width = this.textSizes[label];
return { width: (width / 10) * fontSize, height: fontSize };
};
return TextMapWrapper;
}());
export default TextMapWrapper;