@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.73 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 has from"../../../../core/has.js";import{pt2px as e}from"../../../../core/screenUtils.js";import{r as t}from"../../../../chunks/rbush.js";import{create as s,intersects as o,copy as i}from"../../../../geometry/support/aaBoundingRect.js";import{normalizeMapX as r}from"../../../../geometry/support/normalizeUtils.js";import{getInfo as n}from"../../../../geometry/support/spatialReferenceUtils.js";import{HittestDrawHelper as m}from"../../../../symbols/cim/CIMSymbolDrawHelper.js";import{CIMSymbolInflatedSizeHelper as l}from"../../../../symbols/cim/CIMSymbolHelper.js";import{hittestToleranceSmallSymbol as a,hittestToleranceMobile as u,hittestToleranceDesktop as h}from"../../engine/webgl/definitions.js";import{GraphicStoreItem as c}from"./GraphicStoreItem.js";import{pixelBuffer as d}from"./graphicsUtils.js";import{GraphicUpdateMessage as f}from"./GraphicUpdateMessage.js";const p=1e-5;function _(e,t){return t.zOrder-e.zOrder}class y{constructor(e,t,s,o,i){this._items=new Map,this._boundsDirty=!1,this._outSpatialReference=e,this._cimResourceManager=t,this._hittestDrawHelper=new m(t),this._tileInfoView=s,this._store=i;const r=s.getClosestInfoForScale(o);this._resolution=this._tileInfoView.getTileResolution(r.level)}destroy(){this._hittestDrawHelper.destroy()}items(){return this._items.values()}getItem(e){return this._items.get(e)}async update(e,t,s){const o=[],i=[],r=[],n=new Set,m=[];let l=0;for(const a of e.items){l++;const e=a.uid,r=this._items.get(e),u=t(a);if(n.add(e),r){const e=r.update(a,u,l),t=r.updateDensificationResolution(this._resolution);e&&m.push(this._updateItem(r,s)),(e||t)&&i.push(r);continue}const h=this._store.createDisplayIdForObjectId(e),d=c.fromGraphic(a,u,l,h);d.updateDensificationResolution(this._resolution),m.push(this._updateItem(d,s)),this._items.set(d.objectId,d),o.push(d)}for(const[a,u]of this._items.entries())n.has(a)||(this._store.releaseDisplayIdForObjectId(a),this._items.delete(a),r.push(u));return await Promise.all(m),this._index=null,new f(o,i,r)}updateLevel(e){if(this._resolution===e)return!1;this._index=null,this._boundsDirty=!0,this._resolution=e;for(const t of this.items())if(t.hasCurvedGeoemtry)return!0;return!1}hitTest(e,t,i,n,m){const l=has("esri-mobile"),c=l?u:h,f=c+(l?0:a);e=r(e,this._tileInfoView.spatialReference);const p=n*window.devicePixelRatio*f,y=s();y[0]=e-p,y[1]=t-p,y[2]=e+p,y[3]=t+p;const b=n*window.devicePixelRatio*c,I=s();I[0]=e-b,I[1]=t-b,I[2]=e+b,I[3]=t+b;const g=.5*n*(f+d),w=this._searchIndex(e-g,t-g,e+g,t+g);if(!w||0===w.length)return[];const x=[],j=s(),R=s();for(const s of w){if(!s.visible)continue;const{geometryBounds:e,symbolResource:t}=s;this._getSymbolBounds(j,t,e,R,m),R[3]=R[2]=R[1]=R[0]=0,o(j,y)&&x.push(s)}if(0===x.length)return[];const S=this._hittestDrawHelper,B=[];for(const s of x){const{projectedGeometry:e,symbolResource:t}=s;if(!t)continue;const{textInfo:o,symbolInfo:i}=t,r=i.cimSymbol;S.hitTest(I,r.symbol,e,o,m,n)&&B.push(s)}return B.sort(_),B.map((e=>e.objectId))}queryItems(e){return 0===this._items.size?[]:this._searchForItems(e)}clear(){this._items.clear(),this._index=null}async _updateItem(e,t){await e.projectAndNormalize(this._outSpatialReference),await t(e);const{size:s}=e;s[0]=s[1]=s[2]=s[3]=0,this._getSymbolBounds(e.symbolBounds,e.symbolResource,e.geometryBounds,e.size,0)}_searchIndex(e,s,o,i){return this._boundsDirty&&(this._items.forEach((e=>this._getSymbolBounds(e.symbolBounds,e.symbolResource,e.geometryBounds,e.size,0))),this._boundsDirty=!1),this._index||(this._index=t(9,(e=>({minX:e.symbolBounds[0],minY:e.symbolBounds[1],maxX:e.symbolBounds[2],maxY:e.symbolBounds[3]}))),this._index.load(Array.from(this._items.values()))),this._index.search({minX:e,minY:s,maxX:o,maxY:i})}_searchForItems(e){const t=this._tileInfoView.spatialReference,o=e.bounds,i=n(t);if(i&&t.isWrappable){const[t,r]=i.valid,n=Math.abs(o[2]-r)<p,m=Math.abs(o[0]-t)<p;if((!n||!m)&&(n||m)){const i=e.resolution;let m;m=s(n?[t,o[1],t+i*d,o[3]]:[r-i*d,o[1],r,o[3]]);const l=this._searchIndex(o[0],o[1],o[2],o[3]),a=this._searchIndex(m[0],m[1],m[2],m[3]);return[...new Set([...l,...a])]}}return this._searchIndex(o[0],o[1],o[2],o[3])}_getSymbolBounds(t,o,r,n,m){if(!o||!o.symbolInfo.linearCIM)return null;if(t||(t=s()),i(t,r),!n||0===n[0]&&0===n[1]&&0===n[2]&&0===n[3]){const{textInfo:t,symbolInfo:s}=o,i=s.cimSymbol;n||(n=[0,0,0,0]);const r=l.getSymbolInflateSize(n,i.symbol,this._cimResourceManager,m,t);n[0]=e(r[0]),n[1]=e(r[1]),n[2]=e(r[2]),n[3]=e(r[3])}const a=this._resolution,u=l.safeSize(n);return t[0]-=u*a,t[1]-=u*a,t[2]+=u*a,t[3]+=u*a,t}}export{y as default};