1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-14 21:23:50 +00:00
seahub/media/js/map/cluster.js
Aries 076d147d4e
Optimize/map marker cluster (#7421)
* click overlay to preview

* updatea cluster plugin

---------

Co-authored-by: zhouwenxuan <aries@Mac.local>
2025-01-23 14:35:46 +08:00

1 line
33 KiB
JavaScript

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Cluster=e()}(this,(function(){"use strict";class t{constructor(e){this._hashCode=null!=e?e:t.guid()}getHandlers(t){let e=this._events||(this._events=new Map);return e.has(t)||e.set(t,new Map),e.get(t)}on(e,s){if("function"!=typeof s)return;this.getHandlers(e).set(s,t.guid())}addEventListener(t,e){this.on(t,e)}off(t,e){var s;let i=this.getHandlers(t);e?i.has(e)&&i.delete(e):null===(s=this._events)||void 0===s||s.clear()}removeEventListener(t,e){this.off(t,e)}fire(t,e){let s=Array.from(this.getHandlers(t).entries());for(const[t]of s)t.call(this,e)}dispatchEvent(t,e){this.fire(t,e)}destroy(){var t;null===(t=this._events)||void 0===t||t.clear(),this._events=null}get hashCode(){return this._hashCode}static guid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){let e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}}var e,s,i,r;!function(t){t.CLICK="click",t.MOUSE_OVER="mouseover",t.MOUSE_OUT="mouseout",t.CHANGE="change",t.DESTROY="destroy"}(e||(e={})),function(t){t.DIS_PIXEL="dis-pixel",t.ATTR_REF="attribute",t.GEO_FENCE="geo-fence"}(s||(s={})),function(t){t.DOM="dom",t.WEBGL="webgl"}(i||(i={})),function(t){t.MULTI="multi",t.SINGLE="single"}(r||(r={}));const n=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class o{static from(t){if(!(t instanceof ArrayBuffer))throw new Error("Data must be an instance of ArrayBuffer.");const[e,s]=new Uint8Array(t,0,2);if(219!==e)throw new Error("Data does not appear to be in a KDBush format.");const i=s>>4;if(1!==i)throw new Error(`Got v${i} data when expected v1.`);const r=n[15&s];if(!r)throw new Error("Unrecognized array type.");const[l]=new Uint16Array(t,2,1),[h]=new Uint32Array(t,4,1);return new o(h,l,r,t)}constructor(t,e=64,s=Float64Array,i){if(isNaN(t)||t<0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.ArrayType=s,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const r=n.indexOf(this.ArrayType),o=2*t*this.ArrayType.BYTES_PER_ELEMENT,l=t*this.IndexArrayType.BYTES_PER_ELEMENT,h=(8-l%8)%8;if(r<0)throw new Error(`Unexpected typed array class: ${s}.`);i&&i instanceof ArrayBuffer?(this.data=i,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+l+h,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+o+l+h),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+l+h,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+r]),new Uint16Array(this.data,2,1)[0]=e,new Uint32Array(this.data,4,1)[0]=t)}add(t,e){const s=this._pos>>1;return this.ids[s]=s,this.coords[this._pos++]=t,this.coords[this._pos++]=e,s}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return l(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(t,e,s,i){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:r,coords:n,nodeSize:o}=this,l=[0,r.length-1,0],h=[];for(;l.length;){const a=l.pop()||0,u=l.pop()||0,p=l.pop()||0;if(u-p<=o){for(let o=p;o<=u;o++){const l=n[2*o],a=n[2*o+1];l>=t&&l<=s&&a>=e&&a<=i&&h.push(r[o])}continue}const c=p+u>>1,g=n[2*c],d=n[2*c+1];g>=t&&g<=s&&d>=e&&d<=i&&h.push(r[c]),(0===a?t<=g:e<=d)&&(l.push(p),l.push(c-1),l.push(1-a)),(0===a?s>=g:i>=d)&&(l.push(c+1),l.push(u),l.push(1-a))}return h}within(t,e,s){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:i,coords:r,nodeSize:n}=this,o=[0,i.length-1,0],l=[],h=s*s;for(;o.length;){const a=o.pop()||0,u=o.pop()||0,c=o.pop()||0;if(u-c<=n){for(let s=c;s<=u;s++)p(r[2*s],r[2*s+1],t,e)<=h&&l.push(i[s]);continue}const g=c+u>>1,d=r[2*g],y=r[2*g+1];p(d,y,t,e)<=h&&l.push(i[g]),(0===a?t-s<=d:e-s<=y)&&(o.push(c),o.push(g-1),o.push(1-a)),(0===a?t+s>=d:e+s>=y)&&(o.push(g+1),o.push(u),o.push(1-a))}return l}}function l(t,e,s,i,r,n){if(r-i<=s)return;const o=i+r>>1;h(t,e,o,i,r,n),l(t,e,s,i,o-1,1-n),l(t,e,s,o+1,r,1-n)}function h(t,e,s,i,r,n){for(;r>i;){if(r-i>600){const o=r-i+1,l=s-i+1,a=Math.log(o),u=.5*Math.exp(2*a/3),p=.5*Math.sqrt(a*u*(o-u)/o)*(l-o/2<0?-1:1);h(t,e,s,Math.max(i,Math.floor(s-l*u/o+p)),Math.min(r,Math.floor(s+(o-l)*u/o+p)),n)}const o=e[2*s+n];let l=i,u=r;for(a(t,e,i,s),e[2*r+n]>o&&a(t,e,i,r);l<u;){for(a(t,e,l,u),l++,u--;e[2*l+n]<o;)l++;for(;e[2*u+n]>o;)u--}e[2*i+n]===o?a(t,e,i,u):(u++,a(t,e,u,r)),u<=s&&(i=u+1),s<=u&&(r=u-1)}}function a(t,e,s,i){u(t,s,i),u(e,2*s,2*i),u(e,2*s+1,2*i+1)}function u(t,e,s){const i=t[e];t[e]=t[s],t[s]=i}function p(t,e,s,i){const r=t-s,n=e-i;return r*r+n*n}function c(t){return!isNaN(t)&&null!==t&&!Array.isArray(t)}function g(t,e,s){if(null!==t)for(var i,r,n,o,l,h,a,u,p=0,c=0,d=t.type,y="FeatureCollection"===d,m="Feature"===d,f=y?t.features.length:1,_=0;_<f;_++){l=(u=!!(a=y?t.features[_].geometry:m?t.geometry:t)&&"GeometryCollection"===a.type)?a.geometries.length:1;for(var w=0;w<l;w++){var E=0,O=0;if(null!==(o=u?a.geometries[w]:a)){h=o.coordinates;var T=o.type;switch(p=!s||"Polygon"!==T&&"MultiPolygon"!==T?0:1,T){case null:break;case"Point":if(!1===e(h,c,_,E,O))return!1;c++,E++;break;case"LineString":case"MultiPoint":for(i=0;i<h.length;i++){if(!1===e(h[i],c,_,E,O))return!1;c++,"MultiPoint"===T&&E++}"LineString"===T&&E++;break;case"Polygon":case"MultiLineString":for(i=0;i<h.length;i++){for(r=0;r<h[i].length-p;r++){if(!1===e(h[i][r],c,_,E,O))return!1;c++}"MultiLineString"===T&&E++,"Polygon"===T&&O++}"Polygon"===T&&E++;break;case"MultiPolygon":for(i=0;i<h.length;i++){for(O=0,r=0;r<h[i].length;r++){for(n=0;n<h[i][r].length-p;n++){if(!1===e(h[i][r][n],c,_,E,O))return!1;c++}O++}E++}break;case"GeometryCollection":for(i=0;i<o.geometries.length;i++)if(!1===g(o.geometries[i],e,s))return!1;break;default:throw new Error("Unknown Geometry Type")}}}}}function d(t){var e=[1/0,1/0,-1/0,-1/0];return g(t,(function(t){e[0]>t[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]<t[0]&&(e[2]=t[0]),e[3]<t[1]&&(e[3]=t[1])})),e}function y(t,e,s){if(void 0===s&&(s={}),!t)throw new Error("point is required");if(!e)throw new Error("polygon is required");var i,r=function(t){if(!t)throw new Error("coord is required");if(!Array.isArray(t)){if("Feature"===t.type&&null!==t.geometry&&"Point"===t.geometry.type)return t.geometry.coordinates;if("Point"===t.type)return t.coordinates}if(Array.isArray(t)&&t.length>=2&&!Array.isArray(t[0])&&!Array.isArray(t[1]))return t;throw new Error("coord must be GeoJSON Point or an Array of numbers")}(t),n="Feature"===(i=e).type?i.geometry:i,o=n.type,l=e.bbox,h=n.coordinates;if(l&&!1===function(t,e){return e[0]<=t[0]&&e[1]<=t[1]&&e[2]>=t[0]&&e[3]>=t[1]}(r,l))return!1;"Polygon"===o&&(h=[h]);for(var a=!1,u=0;u<h.length&&!a;u++)if(m(r,h[u][0],s.ignoreBoundary)){for(var p=!1,c=1;c<h[u].length&&!p;)m(r,h[u][c],!s.ignoreBoundary)&&(p=!0),c++;p||(a=!0)}return a}function m(t,e,s){var i=!1;e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]&&(e=e.slice(0,e.length-1));for(var r=0,n=e.length-1;r<e.length;n=r++){var o=e[r][0],l=e[r][1],h=e[n][0],a=e[n][1];if(t[1]*(o-h)+l*(h-t[0])+a*(t[0]-o)==0&&(o-t[0])*(h-t[0])<=0&&(l-t[1])*(a-t[1])<=0)return!s;l>t[1]!=a>t[1]&&t[0]<(h-o)*(t[1]-l)/(a-l)+o&&(i=!i)}return i}function f(t,e){void 0===e&&(e={});var s=0,i=0,r=0;return g(t,(function(t){s+=t[0],i+=t[1],r++}),!0),function(t,e,s){if(void 0===s&&(s={}),!t)throw new Error("coordinates is required");if(!Array.isArray(t))throw new Error("coordinates must be an Array");if(t.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!c(t[0])||!c(t[1]))throw new Error("coordinates must contain numbers");return function(t,e,s){void 0===s&&(s={});var i={type:"Feature"};return(0===s.id||s.id)&&(i.id=s.id),s.bbox&&(i.bbox=s.bbox),i.properties=e||{},i.geometry=t,i}({type:"Point",coordinates:t},e,s)}([s/r,i/r],e.properties)}d.default=d;const _=(t,e,s)=>{let i,r,n,o=null,l=0;s||(s={});let h=function(){l=!1===s.leading?0:Date.now(),o=null,n=t.apply(r,i),o||(r=i=null)};return function(){let a=Date.now();l||!1!==s.leading||(l=a);let u=e-(a-l);return r=this,i=arguments,u<=0||u>e?(o&&(clearTimeout(o),o=null),l=a,n=t.apply(r,i),o||(r=i=null)):o||!1===s.trailing||(o=setTimeout(h,u)),n}},w=Math.fround||(E=new Float32Array(1),t=>(E[0]=+t,E[0]));var E;const O=(t,e,s)=>t.reduce(((t,i,r)=>{let n=e(i);return n=null==n||""===n?"undefined":n,t[n]||(t[n]=[]),s.type&&s.zoom&&(i["_inner_"+s.type+"_"+s.zoom]=n),i.id=r,t[n].push(i),t}),{}),T=t=>({fence:!0,bbox:d(t),center:v(t)}),M=(t,e)=>{if(e){return d({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[t]}}]})}return d({type:"FeatureCollection",features:t})},v=t=>f(t).geometry.coordinates,L=t=>{if(!t||!Array.isArray(t)||t.length<2)return[];let e=[t[0],t[1]];for(let s=2;s<t.length-1;s+=2)t[s]!==e[s-2]&&t[s+1]!==e[s-1]&&e.push(t[s],t[s+1]);return e},F=t=>t/360+.5,C=t=>{const e=Math.sin(t*Math.PI/180),s=.5-.25*Math.log((1+e)/(1-e))/Math.PI;return s<0?0:s>1?1:s};class x{constructor(){}}var S;!function(t){t[t.NONE=0]="NONE",t[t.INNER=1]="INNER",t[t.OUT=2]="OUT",t[t.ALL=3]="ALL"}(S||(S={}));class b{constructor(t,s=!1){this.trees={},this.nodeSize=64,this.isSort=!0,this.splitChar="*.*",this.isWeight=!1,this.OFFSET_ZOOM=2,this.OFFSET_ID=3,this.OFFSET_PARENT=4,this.OFFSET_NUM=5,this.OFFSET_PROP=6,this.ZOOM_BITS=5,this.mapping=new Map,this.geo_refs=new Map,this.key_refs=new Map,this.cluster_geo_refs=new Map,this.own=t,this.showLog=s,this.reduceType=this.isClusterReduce(),this.stride=this.reduceType!==S.NONE?7:6,this.reduceType&S.INNER&&(this.innerReduce=(t,e)=>{var s,i;this.weightKey&&(t.weight+=null!==(s=null==e?void 0:e.weight)&&void 0!==s?s:1),this.typeKey&&(t.divide_type=null!==(i=null==e?void 0:e.divide_type)&&void 0!==i?i:"unknown")},this.innerMap=t=>{var e,s,i,r;let n={};return this.weightKey&&("function"==typeof this.weightKey?n.weight=null!==(e=this.weightKey(t))&&void 0!==e?e:1:n.weight=t?null!==(s=t[this.weightKey])&&void 0!==s?s:1:null),this.typeKey&&("function"==typeof this.typeKey?n.divide_type=null!==(i=this.typeKey(t))&&void 0!==i?i:"unknown":n.divide_type=t?null!==(r=t[this.typeKey])&&void 0!==r?r:"unknown":null),n}),this.createZoomMapping(),this.own.on(e.DESTROY,(()=>{this.reset(),this.mapping.clear()}))}isClusterReduce(){let t=this.own.getOptions().clusterPointWeight,e=this.own.getOptions().clusterPointType;return t||e?(t&&(this.weightKey=t,this.isWeight=!0),e&&(this.typeKey=e),this.own.getOptions().clusterReduce?S.ALL:S.INNER):this.own.getOptions().clusterReduce?S.OUT:S.NONE}createZoomMapping(){let t=this.own.getOptions().clusterType;t&&0!==t.length&&(t.forEach((t=>{let[e,i,r,n,o]=t;if(i=null!=i?i:this.own.getOptions().clusterMaxZoom,r===s.GEO_FENCE||r===s.ATTR_REF)this.mapping.set(e,[null!=o?o:i,r,n]);else if(o)this.mapping.set(e,[o,s.DIS_PIXEL,n]);else for(var l=e;l<=i;l++)this.mapping.set(l,[l,s.DIS_PIXEL,n])})),this.showLog&&console.log("this.mapping",this.mapping))}getClusterType(t){let e,i=s.DIS_PIXEL;for(let[r,n]of[...this.mapping.entries()].reverse())if(r<=t){i=n[1],e=i===s.ATTR_REF&&n[2]instanceof Array?n[2][n[2].length-1]:n[2];break}return{type:i,name:e}}getClusterZoom(t){let e=this._limitZoom(t);for(let[s]of[...this.mapping.entries()].reverse())if(s<=t){e=s;break}return e}getClusterTree(t){let e=this.getClusterZoom(t);const{clusterMaxZoom:s=21}=this.own.getOptions();e<t&&s+1===t&&(e=s+1);return this.trees[e]}createClusters(t){this.reset(),this.points=t.filter((t=>{if(t.geometry){const[e,s]=t.geometry.coordinates;if(!isNaN(e)&&!isNaN(s)&&e>=-180&&e<=180&&s>=-90&&s<=90)return!0}return!1}));const{clusterMinZoom:e=3,clusterMaxZoom:i=21}=this.own.getOptions(),r=`prepare ${t.length} points`;this.showLog&&console.time(r);const n=[];for(let t=0;t<this.points.length;t++){const e=this.points[t];if(!e.geometry)continue;const[s,i]=e.geometry.coordinates,r=w(s),o=w(i);n.push(r,o,1/0,t,-1,1),this.reduceType!==S.NONE&&n.push(-1)}let o=this.trees[i+1]=this._createTree(new Float32Array(n));for(let t=i;t>=e;t--){const e=+Date.now(),i=this.getClusterZoom(t);if(this.mapping.has(i)){if(this.trees[i])continue;let t,[e,r,n]=this.mapping.get(i);switch(r){case s.GEO_FENCE:t=this._fence_cluster(e,n);break;case s.ATTR_REF:t=this._attribute_cluster(e,n);break;default:t=this._distance_cluster(o,e,n)}o=this.trees[i]=this._createTree(t)}else o=this.trees[i]=this._createTree(this._distance_cluster(o,i));this.showLog&&console.log("z%d: %d clusters in %dms",t,o.numItems,+Date.now()-e)}this.showLog&&console.timeEnd(r)}_createTree(t){const e=new o(t.length/this.stride|0,this.nodeSize,Float32Array);for(let s=0;s<t.length;s+=this.stride)e.add(F(t[s]),C(t[s+1]));return e.finish(),e.data=t,e}_attribute_cluster(t,e){let i=O(this.points,(t=>{if(!t.properties)return null;let i=null;if(e instanceof Array?e.forEach((e=>{var s;(null===(s=t.properties)||void 0===s?void 0:s.hasOwnProperty(e))&&(null===i?i=t.properties[e]:i+=this.splitChar+t.properties[e])})):i=t.properties[e],this.own.getOptions().clusterDictionary&&i&&!this.geo_refs.has(i)){let t=this.own.getOptions().clusterDictionary(s.ATTR_REF,i);t&&t.point&&this.geo_refs.set(i,t)}return i}),{zoom:t,type:s.ATTR_REF});this.showLog&&console.log("attribute_cluster",t,i);return this._match_cluster(s.ATTR_REF,i,t)}_fence_cluster(t,e){let i=new Map;if(this.own.getOptions().clusterDictionary){let t=e;t instanceof Array||(t=[t]),t.forEach((t=>{if(this.geo_refs.has(t))i.set(t,this.geo_refs.get(t));else{this.showLog&&console.log("fence_cluster_key",t);let e=this.own.getOptions().clusterDictionary(s.GEO_FENCE,t);e&&e.region&&(e.point||(e.point=v(e.region)),this.geo_refs.set(t,e),i.set(t,e))}}))}let r=O(this.points,(t=>((t,e,s)=>{let i=null;for(let[r,n]of t)if(y(e,s(n))){i=r;break}return i})(i,t,(t=>({type:"Feature",geometry:{type:"Polygon",coordinates:[t.region]}})))),{zoom:t,type:s.GEO_FENCE});this.showLog&&console.log("fence_cluster",r);return this._match_cluster(s.GEO_FENCE,r,t)}_match_cluster(t,e,i){let r=[];const{clusterMinPoints:n=3,clusterReduce:o}=this.own.getOptions();for(const l in e)if(e.hasOwnProperty(l)){let h=e[l];if("undefined"===l||h.length<n)h.forEach((t=>{var e;const[s,i]=t.geometry.coordinates,n=s,o=i;r.push(n,o,1/0,+(null!==(e=t.id)&&void 0!==e?e:0),-1,1),this.reduceType!==S.NONE&&r.push(-1)}));else{let e,a=-1;h.forEach((t=>{if(this.reduceType!==S.NONE){let s={};if(this.reduceType&S.INNER&&(s=this.innerMap(t.properties)),o){let e=this.own.getOptions().clusterMap(t.properties);Object.assign(s,e)}e?(this.reduceType&S.INNER&&this.innerReduce(e,Object.assign({},s)),o&&o(e,Object.assign({},s))):(e=Object.assign({},s),a=this.clusterProps.length,this.clusterProps.push(e))}}));let u=(h[0].id<<this.ZOOM_BITS)+(i+1)+this.points.length,p=l.split(this.splitChar);if(this.key_refs.set(u,p[p.length-1]),this.geo_refs.has(l)){let e=this.geo_refs.get(l),i=e.point;r.push(i[0],i[1],1/0,u,-1,h.length),t===s.GEO_FENCE?this.cluster_geo_refs.set(u,{bbox:M(e.region,!0)}):this.cluster_geo_refs.set(u,{bbox:M(h,!1)})}else{let{fence:t,bbox:e,center:s}=T({type:"FeatureCollection",features:h});L(e).length<=2||e[0]===1/0||!t?(n>1&&(u=h[0].id),r.push(s[0],s[1],1/0,u,-1,1)):r.push(s[0],s[1],1/0,u,-1,h.length),this.cluster_geo_refs.set(u,{bbox:e})}this.reduceType!==S.NONE&&r.push(a)}}return r}_distance_cluster(t,e,s){var i,r,n,o,l,h,a,u;const{clusterRadius:p=60,tileSize:c=256,clusterMinPoints:g=3,clusterReduce:d}=this.own.getOptions();const y=(void 0===s?p:s)/(c*Math.pow(2,e-1)),m=t.data,f=[],_=this.stride;for(let s=0;s<m.length;s+=_){if(m[s+this.OFFSET_ZOOM]<=e)continue;m[s+this.OFFSET_ZOOM]=e;const p=m[s],c=m[s+1];let w=t.within(F(m[s]),C(m[s+1]),y);if(this.showLog&&console.log("delete neighborId start",w),this.typeKey){let t=null!==(r=null===(i=this._map(m,s))||void 0===i?void 0:i.divide_type)&&void 0!==r?r:"unknown";w=w.filter((e=>{var s,i;const r=e*_;let n=null!==(i=null===(s=this._map(m,r))||void 0===s?void 0:s.divide_type)&&void 0!==i?i:"unknown";return n!=t&&this.showLog&&console.log("delete neighborId",`${t}!==${n}`),n===t}))}this.showLog&&console.log("delete neighborId end",w);const E=m[s+this.OFFSET_NUM];let O=E;const T=this.isWeight&&null!==(o=null===(n=this.clusterProps[m[s+this.OFFSET_PROP]])||void 0===n?void 0:n.weight)&&void 0!==o?o:1;let v=T;for(const t of w){const s=t*_;m[s+this.OFFSET_ZOOM]>e&&(O+=m[s+this.OFFSET_NUM],v+=this.isWeight&&null!==(h=null===(l=this.clusterProps[m[s+this.OFFSET_PROP]])||void 0===l?void 0:l.weight)&&void 0!==h?h:1)}if(O>E&&O>=g){let t,i=p*(this.isWeight?T:E),r=c*(this.isWeight?T:E),n=-1,o=[[p,c]];const l=(s/_<<this.ZOOM_BITS)+(e+1)+this.points.length;for(const h of w){const p=h*_;if(m[p+this.OFFSET_ZOOM]<=e)continue;m[p+this.OFFSET_ZOOM]=e;const c=m[p+this.OFFSET_NUM],g=this.isWeight&&null!==(u=null===(a=this.clusterProps[m[p+this.OFFSET_PROP]])||void 0===a?void 0:a.weight)&&void 0!==u?u:1;if(i+=m[p]*(this.isWeight?g:c),r+=m[p+1]*(this.isWeight?g:c),o.push([m[p],m[p+1]]),m[p+this.OFFSET_PARENT]=l,this.reduceType!==S.NONE){t||(t=this._map(m,s,!0),n=this.clusterProps.length,this.clusterProps.push(t));let e=this._map(m,p);this.reduceType&S.INNER&&this.innerReduce(t,e),d&&d(t,e)}}m[s+this.OFFSET_PARENT]=l,this.cluster_geo_refs.set(l,{bbox:M(o,!0)}),this.isWeight?f.push(i/v,r/v,1/0,l,-1,O):f.push(i/O,r/O,1/0,l,-1,O),this.reduceType!==S.NONE&&f.push(n)}else{for(let t=0;t<_;t++)f.push(m[s+t]);if(O>1)for(const t of w){const s=t*_;if(!(m[s+this.OFFSET_ZOOM]<=e)){m[s+this.OFFSET_ZOOM]=e;for(let t=0;t<_;t++)f.push(m[s+t])}}}}return f}_getOriginId(t){return t-this.points.length>>this.ZOOM_BITS}_getOriginZoom(t){return(t-this.points.length)%32}_map(t,e,s){if(t[e+this.OFFSET_NUM]>1){const i=this.clusterProps[t[e+this.OFFSET_PROP]];return s?Object.assign({},i):i}const i=this.points[t[e+this.OFFSET_ID]].properties;let r={};if(this.reduceType&S.INNER&&(r=this.innerMap(i)),this.own.getOptions().clusterReduce){let t=this.own.getOptions().clusterMap(i);Object.assign(r,t)}return s&&r===i?Object.assign({},r):r}_limitZoom(t){var e,s;let i=this.own.getOptions();return Math.max(null!==(e=i.clusterMinZoom)&&void 0!==e?e:3,Math.min(Math.floor(+t),(null!==(s=i.clusterMaxZoom)&&void 0!==s?s:21)+1))}getClusters(t,e){var i;if(this.isIllegal(t))return[[],[]];let r=((e[0]+180)%360+360)%360-180;const n=Math.max(-90,Math.min(90,e[1]));let o=180===e[2]?180:((e[2]+180)%360+360)%360-180;const l=Math.max(-90,Math.min(90,e[3]));if(e[2]-e[0]>=360)r=-180,o=180;else if(r>o){const e=this.getClusters(t,[r,n,180,l]),s=this.getClusters(t,[-180,n,o,l]);return[[...e[0],...s[0]],[...e[1],...s[1]]]}let h=this.getClusterZoom(t);const a=this.getClusterTree(t);if(!a)return[[],[]];const{type:u,name:p}=this.getClusterType(t),c=a.range(F(r),C(l),F(o),C(n)),g=a.data,d=[],y=[];this.showLog&&console.log("getClusters",c);for(const t of c){const e=this.stride*t;if(this.showLog&&console.log("getClusters",t,g.slice(e,e+this.stride)),g[e+this.OFFSET_NUM]>=this.own.getOptions().clusterMinPoints){let r=this.getClusterJSON(g,e,this.clusterProps);r.properties||(r.properties={}),r.properties.listChildren=this.getLeaves(g[e+this.OFFSET_ID],[],null!==(i=this.own.getOptions().clusterListChildren)&&void 0!==i?i:-1),r.properties.clusterIndex=(t<<this.ZOOM_BITS)+h,r.properties.allCount=this.points.length,r.properties.type=u,u!==s.GEO_FENCE&&u!==s.ATTR_REF||this.key_refs.has(g[e+this.OFFSET_ID])&&(r.properties.belongKey=p,r.properties.belongValue=this.key_refs.get(g[e+this.OFFSET_ID])),d.push(r)}else{let t=g[e+this.OFFSET_ID],s=this.points[t];s.id=t,s.properties?s.properties.listChildren=[]:s.properties={listChildren:[]},s.properties?s.properties.clusterId=t:s.properties={clusterId:t},s.properties?s.properties.allCount=this.points.length:s.properties={allCount:this.points.length},s.properties?s.properties.parentId=g[e+this.OFFSET_PARENT]:s.properties={parentId:g[e+this.OFFSET_PARENT]},y.push(s)}}return this.isSort&&d.sort(((t,e)=>{var s,i;return(null===(s=t.properties)||void 0===s?void 0:s.pointCount)-(null===(i=e.properties)||void 0===i?void 0:i.pointCount)})),[y,d]}getElementById(t,e,i){let r=i?e>>this.ZOOM_BITS:e,n=new x;n.id=t,n.index=r;let o=i?e&(1<<this.ZOOM_BITS)-1:this._getOriginZoom(t)-1,{type:l,name:h}=this.getClusterType(o);if(n.type=l,t<=this.points.length)n.isCluster=!1,n.properties=this.points[t].properties,n.latLng=this.points[t].geometry.coordinates;else{n.isCluster=!0;let e=this.getClusterTree(o),i=e.data;if(e){let e=r*this.stride;this.showLog&&console.log("getElementById",i.slice(e,e+this.stride)),n.latLng=[i[e],i[e+1]],n.pointCount=i[e+this.OFFSET_NUM],n.parentId=i[e+this.OFFSET_PARENT],l!==s.GEO_FENCE&&l!==s.ATTR_REF||this.key_refs.has(t)&&(n.belongKey=h,n.belongValue=this.key_refs.get(t)),this.reduceType!==S.NONE&&(n.reduces=this.clusterProps[i[e+this.OFFSET_PROP]])}}return this.cluster_geo_refs.has(t)&&(n.bbox=this.cluster_geo_refs.get(t).bbox),this.showLog&&console.log("getElementById",n),n}getUnDistanceBrothers(t,e,s,i,r){let n=this._getOriginId(t),o=this.points[n],l=o?o["_inner_"+e+"_"+i]:void 0,h=[];return l&&(h=this.points.filter((t=>!!t&&t["_inner_"+e+"_"+i]===l))),h.slice(0,r).map((t=>{let s=new x;return s.id=t.id,s.index=t.id,s.type=e,s.isCluster=!1,s.properties=this.points[t.id].properties,s.latLng=this.points[t.id].geometry.coordinates,s}))}getLeaves(t,e=[],i){if(void 0===i&&(i=1/0),i<=0)return[];e||(e=[]);let r=this._getOriginZoom(t)-1,{type:n,name:o}=this.getClusterType(r);if(n===s.GEO_FENCE||n===s.ATTR_REF)return e=this.getUnDistanceBrothers(t,n,o,r,i);if(t>this.points.length){let s=this.getClusterTree(r+1),n=s.data;if(s)for(let s=0;s<n.length/this.stride;s++){let r=s*this.stride+this.OFFSET_ID;if(n[s*this.stride+this.OFFSET_PARENT]===t)if(n[r]<=this.points.length){if(!(e.length<i))break;e.push(this.getElementById(n[r],s))}else this.getLeaves(n[r],e,i)}}return e}getChildNodes(t){let e=[];if(t<=this.points.length)e=[];else{let s=this._getOriginZoom(t)-1,i=this.getClusterTree(s+1),r=i.data;if(i)for(let s=0;s<r.length/this.stride;s++)if(r[s*this.stride+this.OFFSET_PARENT]===t){let i=this.getElementById(r[s*this.stride+this.OFFSET_ID],s);i.parentId=t,e.push(i)}}return e}getClusterJSON(t,e,s){return{type:"Feature",id:t[e+this.OFFSET_ID],properties:this.getClusterProperties(t,e,s),geometry:{type:"Point",coordinates:[t[e],t[e+1]]}}}getClusterProperties(t,e,s){const i=t[e+this.OFFSET_NUM],r=i>=1e4?`${Math.round(i/1e3)}k`:i>=1e3?Math.round(i/100)/10+"k":i;let n={};if(this.reduceType!==S.NONE){const i=t[e+this.OFFSET_PROP];n=-1===i?{}:Object.assign({},{reduces:s[i]})}return Object.assign(n,{isCluster:!0,clusterId:t[e+this.OFFSET_ID],parentId:t[e+this.OFFSET_PARENT],point:[t[e],t[e+1]],pointCount:i,pointCountAbbrev:r})}isIllegal(t){var e,s;let i=null!==(e=this.own.getOptions().minZoom)&&void 0!==e?e:3,r=null!==(s=this.own.getOptions().maxZoom)&&void 0!==s?s:23;return t<i||t>r}reset(){this.points=[],this.clusterProps=[],this.trees={},this.geo_refs.clear(),this.key_refs.clear(),this.cluster_geo_refs.clear()}}class I{constructor(t,e,s,i){this._wait=600,this._fitViewMargin=[12,12,12,12],this.own=t,this.engine=e,this.map=s,this.showLog=i,this.register(),this.createLayers()}register(){this.own.getOptions().updateRealTime?(this._wait=this.own.getOptions().waitTime||300,this.map.addEventListener("update",this._onMapStatusChange=_(this.mapStatusChange.bind(this),this._wait,{leading:!0,trailing:!1}))):this.map.addEventListener("mapstatusidle_inner",this._onMapStatusChange=this.mapStatusChange.bind(this)),this.map.addEventListener("destroy",(()=>{this.own.destroy()})),this.own.on(e.DESTROY,(()=>{this.destroy()}))}unregister(){this.own.getOptions().updateRealTime?this.map.removeEventListener("update",this._onMapStatusChange):this.map.removeEventListener("mapstatusidle_inner",this._onMapStatusChange),this._onMapStatusChange=()=>{}}mapStatusChange(t){let s=this.map.getZoom(),i=this.map.getBounds(),r=i.getSouthWest(),n=i.getNorthEast();this.showLog&&console.log("地图状态变化",s,[r.lng,r.lat,n.lng,n.lat]);let o=this.engine.getClusters(s,[r.lng,r.lat,n.lng,n.lat]);this.own.fire(e.CHANGE,o),this.own.isRender&&this.update(o)}update(t){if(this.showLog&&console.log("更新数据",t),this.own.getOptions().isAnimation){if(!(this.multi_layer instanceof BMapGL.CustomHtmlLayer))throw new Error("isAnimation is true, but renderClusterStyle is not dom type");this.render([...t[0],...t[1]],r.MULTI)}else this.render(t[0],r.SINGLE),this.render(t[1],r.MULTI)}render(t,e){this.showLog&&console.log("渲染type",e),this.showLog&&console.log("渲染data",t);let s={type:"FeatureCollection",features:t},i=e===r.MULTI?this.multi_layer:this.single_layer;i&&(t.length>0&&(null==i||i.setData(s)),0===t.length&&(null==i||i.clearData()))}createLayers(){var t,e;(null===(t=this.own.getOptions().renderSingleStyle)||void 0===t?void 0:t.type)===i.DOM?this.single_layer=this.createLayer(r.SINGLE,i.DOM):this.single_layer=this.createLayer(r.SINGLE,i.WEBGL),(null===(e=this.own.getOptions().renderClusterStyle)||void 0===e?void 0:e.type)===i.DOM?this.multi_layer=this.createLayer(r.MULTI,i.DOM):this.multi_layer=this.createLayer(r.MULTI,i.WEBGL)}createLayer(t,s){this.showLog&&console.log("创建图层",s);let n,o=this.own.getOptions(),l=t===r.MULTI?o.renderClusterStyle:o.renderSingleStyle;if(!l)return;if(s===i.DOM){let e={sliceRepeat:!0,minZoom:this.own.getOptions().minZoom,maxZoom:this.own.getOptions().maxZoom,zIndex:t===r.MULTI?10:9,nextTick:!0,fixBottom:!0,useTranslate:!!this.own.getOptions().isAnimation,anchors:[.5,.5],displayType:"normal",enableDraggingMap:!0};this.own.getOptions().isAnimation&&(e.displayType="cluster"),Object.assign(e,l.style);const s=new BMapGL.CustomHtmlLayer(l.inject,e);this.map.addCustomHtmlLayer(s),n=s}else{let e=1.2*(o.clusterRadius||32),s={iconObj:(t,e)=>({canvas:(null==l?void 0:l.inject)(e),id:e.clusterId}),sizes:[e,e/2],scale:1,userSizes:!1,anchors:[0,0],width:e,height:e/2};Object.assign(s,l.style);let i={icon:"https://webmap0.bdimg.com/image/api/marker_red.png",sizes:[8,8],anchors:[0,-1],userSizes:!1,width:["match",["get","type"],0,16,8],height:["match",["get","type"],0,16,8]};Object.assign(i,l.style);const h=new BMapGL.PointIconLayer({minZoom:this.own.getOptions().minZoom,maxZoom:this.own.getOptions().maxZoom,zIndex:t===r.MULTI?10:9,isTop:!1,enablePicked:!0,autoSelect:!1,pickWidth:30,pickHeight:30,opacity:1,isFlat:!1,isFixed:!0,style:t===r.MULTI?s:i});this.map.addNormalLayer(h),n=h}n.addEventListener("click",(t=>{if(this.showLog&&console.log("鼠标点击事件",t),t.target instanceof BMapGL.PointIconLayer&&!t.value.dataItem)return;let s=this.getElementByEvent(t);s.bbox&&Array.isArray(s.bbox)&&s.bbox[0]!==1/0&&this.fitView(s.bbox),this.own.fire(e.CLICK,s)}));let h=s===i.DOM?"mouseover":"mousemove";return n.addEventListener(h,(t=>{if(this.showLog&&console.log("鼠标悬浮事件",t),t.target instanceof BMapGL.PointIconLayer&&!t.value.dataItem)return void(this._preMouseMove&&(this.own.fire(e.MOUSE_OUT,this._preMouseMove),this._preMouseMove=null));let s=this.getElementByEvent(t);if(t.target instanceof BMapGL.PointIconLayer)return this._preMouseMove&&this._preMouseMove.id===s.id||this.own.fire(e.MOUSE_OVER,s),void(this._preMouseMove=s);this.own.fire(e.MOUSE_OVER,s)})),n.addEventListener("mouseout",(t=>{if(this.showLog&&console.log("鼠标移开事件",t),t.target instanceof BMapGL.PointIconLayer)return;let s=this.getElementByEvent(t);this.own.fire(e.MOUSE_OUT,s)})),n}getElementByEvent(t){var e,s;let i,r,n=[];if(t.target instanceof BMapGL.CustomOverlay){let s=t.target.properties||{};i=s.clusterId,r=s.clusterIndex,n=null!==(e=s.listChildren)&&void 0!==e?e:[]}else{let e=t.value.dataItem.properties||{};i=e.clusterId,r=e.clusterIndex,n=null!==(s=e.listChildren)&&void 0!==s?s:[]}let o=this.engine.getElementById(i,r,!0);return o.listChildren=n,o.pixel=[t.pixel.x,t.pixel.y],o.target=t.target,o}clearRender(){this.showLog&&console.log("清除图层"),this.update([[],[]])}unrender(){this.showLog&&console.log("销毁图层"),this.multi_layer instanceof BMapGL.PointIconLayer?this.map.removeNormalLayer(this.multi_layer):this.map.removeCustomHtmlLayer(this.multi_layer),this.single_layer instanceof BMapGL.PointIconLayer?this.map.removeNormalLayer(this.single_layer):this.map.removeCustomHtmlLayer(this.single_layer),this.multi_layer=void 0,this.single_layer=void 0}fitView(t){if(this.showLog&&console.log("fitView",t),this.own.getOptions().fitViewOnClick){let e=this.map.getZoom(),s=[new BMapGL.Point(t[0],t[1]),new BMapGL.Point(t[2],t[3])],i={margins:this._fitViewMargin,enableAnimation:!0};this.map.setViewport(s,i),setTimeout((()=>{e===this.map.getZoom()&&this.map.setZoom(e+1),this.mapStatusChange()}),300)}}show(){this.single_layer&&(this.single_layer instanceof BMapGL.CustomHtmlLayer&&this.single_layer.show(),this.single_layer instanceof BMapGL.PointIconLayer&&this.single_layer.setVisible(!0)),this.multi_layer&&(this.multi_layer instanceof BMapGL.CustomHtmlLayer&&this.multi_layer.show(),this.multi_layer instanceof BMapGL.PointIconLayer&&this.multi_layer.setVisible(!0))}hide(){this.single_layer&&(this.single_layer instanceof BMapGL.CustomHtmlLayer&&this.single_layer.hide(),this.single_layer instanceof BMapGL.PointIconLayer&&this.single_layer.setVisible(!1)),this.multi_layer&&(this.multi_layer instanceof BMapGL.CustomHtmlLayer&&this.multi_layer.hide(),this.multi_layer instanceof BMapGL.PointIconLayer&&this.multi_layer.setVisible(!1))}getSingleLayer(){return this.single_layer}getClusterLayer(){return this.multi_layer}drawMarker(t){this.map.addOverlay(new BMapGL.Marker(new BMapGL.Point(t[0],t[1])))}destroy(){this.map&&(this.unregister(),this.unrender())}}var N=Object.freeze({__proto__:null,get ClusterData(){return r},ClusterElement:x,get ClusterEvent(){return e},get ClusterRender(){return i},get ClusterType(){return s},View:class extends t{constructor(t,e){if(super(),this._showLog=!1,!t)throw new Error("map is required");e&&this.verifyOptions(e);const s={tileSize:256,minZoom:3,maxZoom:21,clusterRadius:30,clusterMinZoom:3,clusterMaxZoom:16,clusterMinPoints:3,clusterListChildren:0,clusterPointWeight:void 0,clusterPointType:void 0,clusterMap:t=>({}),clusterReduce:void 0,clusterType:void 0,clusterDictionary:void 0,isRender:!0,isAnimation:!1,renderClusterStyle:{type:i.DOM,style:{},inject:t=>{var e=Math.pow(t.pointCount/t.allCount,.1),s=document.createElement("div"),i=180-180*e,r="hsla("+i+",100%,30%,0.7)",n="hsla("+i+",100%,90%,1)",o="hsla("+i+",100%,30%,1)",l="hsla("+i+",100%,90%,1)";s.style.backgroundColor=r;var h=Math.round(25+30*Math.pow(t.pointCount/t.allCount,1/6));return s.style.width=s.style.height=h+"px",s.style.border="solid 1px "+o,s.style.borderRadius=h/2+"px",s.style.boxShadow="0 0 5px "+l,s.innerHTML=t.pointCount,s.style.lineHeight=h+"px",s.style.color=n,s.style.fontSize="14px",s.style.textAlign="center",s.style.cursor="pointer",s}},renderSingleStyle:{type:i.WEBGL,style:{},inject:t=>document.createElement("canvas")},fitViewOnClick:!0,updateRealTime:!1,waitTime:300};this.options=Object.assign(s,e),this.engine=new b(this,this._showLog),this.render=new I(this,this.engine,t,this._showLog),this.isRender=this.options.isRender||!1}setData(t){this._showLog&&console.log("cluster options",this.options),this.engine.createClusters(t),this.redraw()}getSingleLayer(){return this.render.getSingleLayer()}getClusterLayer(){return this.render.getClusterLayer()}getLeaves(t,e){return this.engine.getLeaves(t,[],e)}getSonNodes(t){return this.engine.getChildNodes(t)}redraw(){this.render.mapStatusChange()}show(){this.render.show()}hide(){this.render.hide()}destroy(){this.fire(e.DESTROY)}get isRender(){return this._isRender}set isRender(t){this._isRender=t,!t&&this.render.clearRender()}getOptions(){return this.options}verifyOptions(t){var e,s;if(t.minZoom&&t.minZoom<3)throw new Error("minZoom must be greater than 3");if(t.maxZoom&&t.maxZoom>23)throw new Error("maxZoom must be less than 23");if(Math.max(null!==(e=t.minZoom)&&void 0!==e?e:3,3)>Math.min(null!==(s=t.maxZoom)&&void 0!==s?s:23,23))throw new Error("minZoom must be less than maxZoom");if(t.clusterMinZoom&&t.clusterMinZoom<3)throw new Error("clusterMinZoom must be greater than 3");if(t.clusterMaxZoom&&t.clusterMaxZoom>23)throw new Error("clusterMaxZoom must be less than 23");if(t.clusterMinZoom&&t.clusterMaxZoom&&t.clusterMinZoom>t.clusterMaxZoom)throw new Error("clusterMinZoom must be less than clusterMaxZoom");if(t.clusterType){if(!(t.clusterType instanceof Array))throw new Error("clusterType must be an array");if(t.clusterType.length<1)throw new Error("clusterType must be greater than 0");for(let e=0;e<t.clusterType.length;e++){if(t.clusterType[e].length<4)throw new Error("clusterType must be greater than 4");if(!t.clusterType[e][0])throw new Error("clusterType item startZoom must not be null");if(t.clusterType[e][1]&&t.clusterType[e][0]>t.clusterType[e][1])throw new Error("clusterType item endZoom must be less than starZoom");if(null===t.clusterType[e][1]&&e<t.clusterType.length-1)throw new Error("clusterType item endZoom must not be null,excluding the last item endZoom");if(e<t.clusterType.length-1&&null!==t.clusterType[e][1]&&t.clusterType[e][1]>t.clusterType[e+1][0])throw new Error("clusterType item endZoom must be less than the next startZoom")}}}},pointTransformer:(t,e)=>{let s=[];return t.forEach((t=>{const{point:i=null,properties:r={}}=e(t);i&&s.push({type:"Feature",geometry:{type:"Point",coordinates:i},properties:r})})),s}});return N}));