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 } }