@vuemap/district-cluster
Version:
98 lines (95 loc) • 3.15 kB
text/typescript
import utils from './utils'
import DistMgr from './DistMgr'
function getPosition(p) {
return [p.x, p.y]
}
export default class DistCounter {
_opts: any
_data: any[] = []
_pointsMap: any = {}
constructor(opts) {
this._opts = utils.extend(
{
topAdcode: 1e5
},
opts
)
this.clearData()
}
clearData() {
this._data = []
this._pointsMap = {}
}
setData(data) {
this.clearData()
this._data = data
this._updatePointsMap(this._opts.topAdcode, 'all', data)
}
_updatePointsMap(adcode, tag, points) {
let item = this._pointsMap[adcode]
item || (item = this._pointsMap[adcode] = {})
item[tag] = points
item[`${tag}_pack`] = this._buildPackItemsByAdcode(adcode, points)
}
getPointsByAdcode(adcode, tag?: any) {
return this._pointsMap[adcode] ? this._pointsMap[adcode][tag || 'all'] : []
}
getPackItemsByAdcode(adcode, tag?: any) {
return this._pointsMap[adcode] ? this._pointsMap[adcode][`${tag || 'all'}_pack`] : []
}
_buildPackItemsByAdcode(adcode, points) {
const packer = this._opts.pointPacker,
items: any[] = []
for (let i = 0, len = points.length; i < len; i++) items[i] = packer.call(this._opts.pointPackerThisArg, points[i])
return items
}
calcDistGroup(adcode, subInclude, callback, thisArg) {
const nodeInfo = this._opts.distMgr.getNodeByAdcode(adcode)
let routes = nodeInfo.acroutes || [1e5]
if (subInclude && nodeInfo.acroutes) {
routes = [].concat(routes)
routes.push(adcode)
}
this._calcGroupWithRoutes(routes, 0, callback, thisArg)
}
_calcGroupWithRoutes(routes, idx, callback, thisArg) {
const next = () => {
idx < routes.length - 1
? this._calcGroupWithRoutes(routes, idx + 1, callback, thisArg)
: callback && callback.call(thisArg)
}
const adcode = routes[idx]
if (this.getPointsByAdcode(adcode, '__done')) next.call(this)
else {
const points = this.getPointsByAdcode(adcode)
if (!points) throw new Error(`Not points found: ${adcode}`)
this._opts.distMgr.getExplorer().loadAreaNode(
adcode,
(error, areaNode) => {
this._groupByAreaNode(areaNode, points)
next.call(this)
},
this,
!0
)
}
}
_groupByAreaNode(areaNode, points) {
const groups = areaNode.groupByPosition(points, getPosition),
isTopNode = areaNode.getAdcode() === this._opts.topAdcode,
topPoints: any[] = []
for (let i = 0, len = groups.length; i < len; i++) {
const item = groups[i]
if (item.subFeature) {
this._updatePointsMap(item.subFeature.properties.adcode, 'all', item.points)
isTopNode && utils.mergeArray(topPoints, item.points)
} else this._updatePointsMap(areaNode.getAdcode(), 'hanging', item.points)
}
isTopNode && this._updatePointsMap(areaNode.getAdcode(), 'all', topPoints)
this._updatePointsMap(areaNode.getAdcode(), '__done', !0)
}
destroy() {
this.clearData()
this._opts = null
}
}