@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 5.11 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{UniqueSymbol as e}from"./core.js";import{isSearchCircleOverlapingSymbol as t,tileCoordChangeX as s,tileCoordChangeY as i,GridIndex as l}from"./util.js";class o{static fromSymbols(e,t){let s=e.length;if(s>=n){let i=t;do{i/=2,s/=4}while(s>r&&i>y);const n=new l(t,t,i);for(const t of e)n.getCell(t.xTile,t.yTile).push(t);return new o(t,e,n)}return new o(t,e,null)}constructor(e,t,s){this.tileCoordRange=e,this._symbols=t,this._index=s}addSymbols(e){for(const t of e)this._symbols.push(t);if(this._index)for(const t of e)this._index.getCell(t.xTile,t.yTile).push(t)}removeSymbols(e){const t=new Set(e);if(this._symbols=this._symbols.filter(e=>!t.has(e)),this._index)for(const s of this._index.cells)for(let e=0;e<s.length;e++)s[e]=s[e].filter(e=>!t.has(e))}getSymbols(){return this._symbols}getCandidate(e,t,s,i){if(!this._index){for(const l of this._symbols)if(s===l.hash&&Math.abs(e-l.xTile)<=i&&Math.abs(t-l.yTile)<=i)return l;return null}const l=this._index.getCellSpan(e-i,t-i,e+i,t+i),[o,n,r,y]=l;for(let a=n;a<=y;a++)for(let l=o;l<=r;l++){const o=this._index.cells[a][l];for(const l of o)if(s===l.hash&&Math.abs(e-l.xTile)<=i&&Math.abs(t-l.yTile)<=i)return l}return null}}const n=32,r=8,y=64,a=20;class u{constructor(e,t){this.tileCoordRange=e,this._visibleTiles=t,this._indexMapByTile=new Map,this._uniqueSymbolsByStyleLayerId=new Map}get uniqueSymbols(){return null==this._uniqueSymbolLayerArray&&(this._uniqueSymbolLayerArray=this._createUniqueSymbolLayerArray()),this._uniqueSymbolLayerArray}registerVectorTile(e,t){const s=this._ensureIndexMap(e),i=t?.values()??s.keys();for(const l of i){const e=s.get(l);e&&(this._removeSymbols(l,e.getSymbols()),s.delete(l))}this._addSymbols(e.key,s,e.symbols),this._invalidate()}unregisterVectorTile(e){this._removeTile(e),this._invalidate()}registerFeatureTile(e){this._ensureIndexMap(e),this._invalidate()}unregisterFeatureTile(e){this._removeTile(e),this._invalidate()}insertFeatureTileMetrics(e,t){const s=this._indexMapByTile.get(e);if(!s)throw new Error(`tile ${e.id} not registered!`);this._addSymbols(e.key,s,h(t)),this._invalidate()}removeFeatureTileMetrics(e,t){const s=this._indexMapByTile.get(e);if(!s)return;const i=h(t);for(const[l,o]of s.entries()){const e=i.get(l);e&&(o.removeSymbols(e),this._removeSymbols(l,e))}this._invalidate()}deleteStyleLayers(e){for(const t of this._indexMapByTile.values())for(const s of e){const e=t.get(s);e&&(this._removeSymbols(s,e.getSymbols()),t.delete(s))}this._invalidate()}querySymbols(e,s,i,l){const o=[];for(const[n,r]of this._uniqueSymbolsByStyleLayerId.entries())for(const l of r){const r=l.tileSymbols.find(e=>e.selectedForRendering);r&&t(r,e,s,i)&&o.push({vtlSymbol:r,styleLayerUID:n,tileKey:r.tile.key})}return o}_ensureIndexMap(e){let t=this._indexMapByTile.get(e);return t||(t=new Map,this._indexMapByTile.set(e,t)),t}_invalidate(){this._uniqueSymbolLayerArray=null}_addSymbols(e,t,s){for(const[i,l]of s){let e=t.get(i);e?e.addSymbols(l):(e=o.fromSymbols(l,this.tileCoordRange),t.set(i,e))}this._updateUniqueSymbols(e,s)}_removeTile(e){const t=this._indexMapByTile.get(e);if(t){for(const[e,s]of t.entries())this._removeSymbols(e,s.getSymbols());this._indexMapByTile.delete(e),this._invalidate()}}_removeSymbols(e,t){for(const s of t){const t=s.uniqueSymbol;if(t){if(t.tileSymbols=t.tileSymbols.filter(e=>e!==s),0===t.tileSymbols.length){const s=this._uniqueSymbolsByStyleLayerId.get(e);s.delete(t),0===s.size&&this._uniqueSymbolsByStyleLayerId.delete(e)}s.uniqueSymbol=null}}}_updateUniqueSymbols(t,s){if(0!==s.size){for(const e of this._visibleTiles)e.parentTile||e.key.world!==t.world||e.key.level===t.level&&!e.key.equals(t)||this._matchSymbols(e,t,s);for(const[t,i]of s)for(const s of i)if(!s.uniqueSymbol){s.uniqueSymbol=new e(s);let i=this._uniqueSymbolsByStyleLayerId.get(t);i||(i=new Set,this._uniqueSymbolsByStyleLayerId.set(t,i)),i.add(s.uniqueSymbol)}}}_matchSymbols(e,t,l){if(e.key.level>t.level){const s=e.key.level-t.level;if(e.key.row>>s!==t.row||e.key.col>>s!==t.col)return}if(t.level>e.key.level){const s=t.level-e.key.level;if(t.row>>s!==e.key.row||t.col>>s!==e.key.col)return}const o=new Map;for(const[n,r]of l){const l=[],y=e.key.level<t.level?1:1<<Math.abs(e.key.level-t.level),u=this._indexMapByTile.get(e),h=u?.get(n);if(h)for(const o of r){if(o.uniqueSymbol)continue;const n=s(this.tileCoordRange,o.xTile,t,e.key),r=i(this.tileCoordRange,o.yTile,t,e.key),u=-a,f=this.tileCoordRange+a;if(!(n>=u&&n<f&&r>=u&&r<f)){l.push(o);continue}const m=h.getCandidate(n,r,o.hash,y),c=m?.uniqueSymbol;c?(o.uniqueSymbol=c,c.tileSymbols.push(o)):l.push(o)}l.length>0&&o.set(n,l)}for(const s of e.childrenTiles||[])this._matchSymbols(s,t,o)}_createUniqueSymbolLayerArray(){const e=this._uniqueSymbolsByStyleLayerId,t=new Array(e.size);let s,i=0;for(const[l,o]of e){const e=new Array(o.size);s=0;for(const t of o)e[s++]=t;t[i]={styleLayerUID:l,uniqueSymbols:e},i++}return t}}function h(e){const t=new Map;for(const s of e){const e=s.labelClassId;let i=t.get(e);i||(i=[],t.set(e,i)),i.push(s)}return t}export{u as SymbolRepository};