@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 6.34 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{indexOf as t,PositionHint as i}from"../../arrayUtils.js";import{toConst as n}from"../../compilerUtils.js";import"../../has.js";import e from"../../PooledArray.js";import{q as h}from"../../../chunks/quickselect.js";class s{constructor(t=9,i){this._compareMinX=u,this._compareMinY=d,this._toBBox=t=>t,this._maxEntries=Math.max(4,t||9),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),i&&("function"==typeof i?this._toBBox=i:this._initFormat(i)),this.clear()}destroy(){this.clear(),Y.prune(),B.prune(),w.prune(),j.prune()}all(t){r(this._data,t)}search(t,i){let n=this._data;const e=this._toBBox;if(M(t,n))for(Y.clear();n;){for(let h=0,s=n.children.length;h<s;h++){const s=n.children[h],a=n.leaf?e(s):s;M(t,a)&&(n.leaf?i(s):g(t,a)?r(s,i):Y.push(s))}n=Y.pop()}}collides(t){let i=this._data;const n=this._toBBox;if(!M(t,i))return!1;for(Y.clear();i;){for(let e=0,h=i.children.length;e<h;e++){const h=i.children[e],s=i.leaf?n(h):h;if(M(t,s)){if(i.leaf||g(t,s))return!0;Y.push(h)}}i=Y.pop()}return!1}load(t){if(!t.length)return this;if(t.length<this._minEntries){for(let i=0,n=t.length;i<n;i++)this.insert(t[i]);return this}let i=this._build(t.slice(),0,t.length-1,0);if(this._data.children.length)if(this._data.height===i.height)this._splitRoot(this._data,i);else{if(this._data.height<i.height){const t=this._data;this._data=i,i=t}this._insert(i,this._data.height-i.height-1,!0)}else this._data=i;return this}insert(t){return t&&this._insert(t,this._data.height-1),this}clear(){return this._data=new S([]),this}remove(i){if(!i)return this;let e,h=this._data,s=null,a=0,r=!1;const o=this._toBBox(i);for(w.clear(),j.clear();h||w.length>0;){if(h||(h=w.pop(),s=w.data[w.length-1],a=j.pop()??0,r=!0),h.leaf&&(e=t(h.children,n(i),h.children.length,h.indexHint),-1!==e))return h.children.splice(e,1),w.push(h),this._condense(w),this;r||h.leaf||!g(h,o)?s?(a++,h=s.children[a],r=!1):h=null:(w.push(h),j.push(a),a=0,s=h,h=h.children[0])}return this}toJSON(){return this._data}fromJSON(t){return this._data=t,this}_build(t,i,n,e){const h=n-i+1;let s=this._maxEntries;if(h<=s){const e=new S(t.slice(i,n+1));return l(e,this._toBBox),e}e||(e=Math.ceil(Math.log(h)/Math.log(s)),s=Math.ceil(h/s**(e-1)));const a=new y([]);a.height=e;const r=Math.ceil(h/s),o=r*Math.ceil(Math.sqrt(s));X(t,i,n,o,this._compareMinX);for(let l=i;l<=n;l+=o){const i=Math.min(l+o-1,n);X(t,l,i,r,this._compareMinY);for(let n=l;n<=i;n+=r){const h=Math.min(n+r-1,i);a.children.push(this._build(t,n,h,e-1))}}return l(a,this._toBBox),a}_insert(t,i,n){const e=this._toBBox,h=n?t:e(t);w.clear();const s=a(h,this._data,i,w);for(s.children.push(t),m(s,h);i>=0&&w.data[i].children.length>this._maxEntries;)this._split(w,i),i--;o(h,w,i)}_split(t,i){const n=t.data[i],e=n.children.length,h=this._minEntries;this._chooseSplitAxis(n,h,e);const s=this._chooseSplitIndex(n,h,e);if(!s)return;const a=n.children.splice(s,n.children.length-s),r=n.leaf?new S(a):new y(a);r.height=n.height,l(n,this._toBBox),l(r,this._toBBox),i?t.data[i-1].children.push(r):this._splitRoot(n,r)}_splitRoot(t,i){this._data=new y([t,i]),this._data.height=t.height+1,l(this._data,this._toBBox)}_chooseSplitIndex(t,i,n){let e,h,s;e=h=1/0;for(let a=i;a<=n-i;a++){const i=c(t,0,a,this._toBBox),r=c(t,a,n,this._toBBox),o=p(i,r),l=f(i)+f(r);o<e?(e=o,s=a,h=l<h?l:h):o===e&&l<h&&(h=l,s=a)}return s}_chooseSplitAxis(t,i,n){const e=t.leaf?this._compareMinX:u,h=t.leaf?this._compareMinY:d;this._allDistMargin(t,i,n,e)<this._allDistMargin(t,i,n,h)&&t.children.sort(e)}_allDistMargin(t,i,n,e){t.children.sort(e);const h=this._toBBox,s=c(t,0,i,h),a=c(t,n-i,n,h);let r=x(s)+x(a);for(let o=i;o<n-i;o++){const i=t.children[o];m(s,t.leaf?h(i):i),r+=x(s)}for(let o=n-i-1;o>=i;o--){const i=t.children[o];m(a,t.leaf?h(i):i),r+=x(a)}return r}_condense(i){for(let n=i.length-1;n>=0;n--){const e=i.data[n];if(0===e.children.length)if(n>0){const h=i.data[n-1],s=h.children;s.splice(t(s,e,s.length,h.indexHint),1)}else this.clear();else l(e,this._toBBox)}}_initFormat(t){const i=["return a"," - b",";"];this._compareMinX=new Function("a","b",i.join(t[0])),this._compareMinY=new Function("a","b",i.join(t[1])),this._toBBox=new Function("a","return {minX: a"+t[0]+", minY: a"+t[1]+", maxX: a"+t[2]+", maxY: a"+t[3]+"};")}}function a(t,i,n,e){for(;e.push(i),!0!==i.leaf&&e.length-1!==n;){let n,e=1/0,h=1/0;for(let s=0,a=i.children.length;s<a;s++){const a=i.children[s],r=f(a),o=_(t,a)-r;o<h?(h=o,e=r<e?r:e,n=a):o===h&&r<e&&(e=r,n=a)}i=n||i.children[0]}return i}function r(t,i){let e=t;for(B.clear();e;){if(!0===e.leaf)for(const t of e.children)i(n(t));else B.pushArray(e.children);e=B.pop()??null}}function o(t,i,n){for(let e=n;e>=0;e--)m(i.data[e],t)}function l(t,i){c(t,0,t.children.length,i,t)}function c(t,i,n,e,h){h||(h=new S([])),h.minX=1/0,h.minY=1/0,h.maxX=-1/0,h.maxY=-1/0;for(let s,a=i;a<n;a++)s=t.children[a],m(h,t.leaf?e(s):s);return h}function m(t,i){t.minX=Math.min(t.minX,i.minX),t.minY=Math.min(t.minY,i.minY),t.maxX=Math.max(t.maxX,i.maxX),t.maxY=Math.max(t.maxY,i.maxY)}function u(t,i){return t.minX-i.minX}function d(t,i){return t.minY-i.minY}function f(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function x(t){return t.maxX-t.minX+(t.maxY-t.minY)}function _(t,i){return(Math.max(i.maxX,t.maxX)-Math.min(i.minX,t.minX))*(Math.max(i.maxY,t.maxY)-Math.min(i.minY,t.minY))}function p(t,i){const n=Math.max(t.minX,i.minX),e=Math.max(t.minY,i.minY),h=Math.min(t.maxX,i.maxX),s=Math.min(t.maxY,i.maxY);return Math.max(0,h-n)*Math.max(0,s-e)}function g(t,i){return t.minX<=i.minX&&t.minY<=i.minY&&i.maxX<=t.maxX&&i.maxY<=t.maxY}function M(t,i){return i.minX<=t.maxX&&i.minY<=t.maxY&&i.maxX>=t.minX&&i.maxY>=t.minY}function X(t,i,n,e,s){const a=[i,n];for(;a.length;){const i=a.pop(),n=a.pop();if(i-n<=e)continue;const r=n+Math.ceil((i-n)/e/2)*e;h(t,r,n,i,s),a.push(n,r,r,i)}}const Y=new e,B=new e,w=new e,j=new e({deallocator:void 0});class E{constructor(){this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0}}class b extends E{constructor(){super(...arguments),this.height=1,this.indexHint=new i}}class S extends b{constructor(t){super(),this.children=t,this.leaf=!0}}class y extends b{constructor(t){super(),this.children=t,this.leaf=!1}}export{E as BBox,s as PooledRBush};