@wayz/react-gl
Version:
React Component for DeckGL, Base on AMap, Mapbox GL
63 lines (62 loc) • 2.52 kB
JavaScript
// @ts-nocheck
import Tag from './tag';
import TagMap from './tagmap';
import ClusterTree from 'hdbscanjs';
const DEFAULT_MAX_DIST = 20;
class CustomTagMap extends TagMap {
constructor() {
super();
}
buildHierarchy(data, { getLabel = (val) => val.label, getPosition = (val) => val.position, getWeight = (val) => val.weight, }) {
// clear tree
this.tagTree = {};
const { tagTree, distFunc } = this;
// group tags based on the content
for (let [, val] of Object.entries(data)) {
let label = getLabel(val);
// 相同label只添加一次
if (!tagTree.hasOwnProperty(label)) {
tagTree[label] = [];
tagTree[label].push({ data: getPosition(val), opt: getWeight(val) });
tagTree[label].originValue = val;
}
}
for (const [key, tag] of Object.entries(tagTree)) {
const cluster = new ClusterTree(tag, distFunc);
tagTree[key] = cluster.getTree();
tagTree[key].originValue = tag.originValue;
}
}
extractCluster({ project = (val) => val, bbox = null, weightThreshold = 0, maxDist = DEFAULT_MAX_DIST, }) {
// clear tagList
this.tagList = [];
const { tagTree, tagList } = this;
const maxDistSq = maxDist * maxDist;
for (const [key, tree] of Object.entries(tagTree)) {
const flagCluster = tree.filter((val) => {
// a cluster of a single point
if (val.isLeaf) {
return true;
}
// test the cluster does not split under the current zoom level
const cp0 = project(val.edge[0]);
const cp1 = project(val.edge[1]);
const dx = cp0[0] - cp1[0];
const dy = cp0[1] - cp1[1];
return dx * dx + dy * dy < maxDistSq;
}, bbox);
// generate tags which passed the test and weightThreshold
for (let [, val] of Object.entries(flagCluster)) {
const tag = new Tag(key);
val.data.forEach((p, i) => tag.add(p, val.opt[i]));
if (tag.weight >= weightThreshold) {
tag.setCenter(project(tag.center));
Object.assign(tag, { originValue: val.originValue });
tagList.push(tag);
}
}
}
return tagList;
}
}
export default CustomTagMap;