@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.27 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{GridIndex as e,isSearchCircleOverlapingSymbol as s,tileCoordChange as l}from"./util.js";const o=32,t=8,i=64,n=20;class r{constructor(e,s,l){this.tileCoordRange=e,this._visibleTiles=s,this._createUnique=l,this._tiles=new Map,this._uniqueSymbolsReferences=new Map}get uniqueSymbols(){return null==this._uniqueSymbolLayerArray&&(this._uniqueSymbolLayerArray=this._createUniqueSymbolLayerArray()),this._uniqueSymbolLayerArray}get uniqueSymbolsReferences(){return this._uniqueSymbolsReferences}add(s,l){this._uniqueSymbolLayerArray=null;let n=this._tiles.get(s.id);n||(n={symbols:new Map},this._tiles.set(s.id,n));const r=new Map;if(l)for(const e of l)n.symbols.has(e)&&(r.set(e,n.symbols.get(e)),n.symbols.delete(e));else for(const[e,o]of s.layerData)n.symbols.has(e)&&(r.set(e,n.symbols.get(e)),n.symbols.delete(e));this._removeSymbols(r);const y=s.symbols,a=new Map;for(const[f,u]of y){let s=u.length;if(s>=o){let l=this.tileCoordRange;do{l/=2,s/=4}while(s>t&&l>i);const o=new e(this.tileCoordRange,this.tileCoordRange,l);a.set(f,{flat:u,index:o}),n.symbols.set(f,{flat:u,index:o});for(const e of u)o.getCell(e.xTile,e.yTile).push(e)}else a.set(f,{flat:u}),n.symbols.set(f,{flat:u})}this._addSymbols(s.key,y)}deleteStyleLayers(e){this._uniqueSymbolLayerArray=null;for(const[s,l]of this._tiles){const o=new Map;for(const s of e)l.symbols.has(s)&&(o.set(s,l.symbols.get(s)),l.symbols.delete(s));this._removeSymbols(o),0===l.symbols.size&&this._tiles.delete(s)}}removeTile(e){this._uniqueSymbolLayerArray=null;const s=this._tiles.get(e.id);if(!s)return;const l=new Map;for(const[o,t]of e.symbols)s.symbols.has(o)&&(l.set(o,s.symbols.get(o)),s.symbols.delete(o));this._removeSymbols(l),0===s.symbols.size&&this._tiles.delete(e.id)}querySymbols(e,l,o,t){const i=[],n=this.uniqueSymbols;for(const r of n){const t=r.styleLayerUID,n=r.uniqueSymbols;for(const r of n){const n=r.tileSymbols.find((e=>e.selectedForRendering));n&&s(n,e,l*(window.devicePixelRatio||1),o)&&i.push({vtlSymbol:n,styleLayerUID:t,tileKey:n.tile.key})}}return i}_removeSymbols(e){for(const[s,{flat:l}]of e)for(const e of l){const l=e.unique,o=l.tileSymbols,t=o.length-1;for(let s=0;s<t;s++)if(o[s]===e){o[s]=o[t];break}if(o.length=t,0===t){const e=this._uniqueSymbolsReferences.get(s);e.delete(l),0===e.size&&this._uniqueSymbolsReferences.delete(s)}e.unique=null}}_addSymbols(e,s){if(0===s.size)return;const l=this._visibleTiles;for(const o of l)o.parentTile||o.key.world!==e.world||o.key.level===e.level&&!o.key.equals(e)||this._matchSymbols(o,e,s);for(const[o,t]of s)for(const e of t)if(null==e.unique){const s=this._createUnique();e.unique=s,s.tileSymbols.push(e);let l=this._uniqueSymbolsReferences.get(o);l||(l=new Set,this._uniqueSymbolsReferences.set(o,l)),l.add(s)}}_matchSymbols(e,s,o){if(e.key.level>s.level){const l=e.key.level-s.level;if(e.key.row>>l!==s.row||e.key.col>>l!==s.col)return}if(s.level>e.key.level){const l=s.level-e.key.level;if(s.row>>l!==e.key.row||s.col>>l!==e.key.col)return}if(s.equals(e.key)){for(const l of e.childrenTiles)this._matchSymbols(l,s,o);return}const t=new Map;for(const[i,r]of o){const o=[];for(const t of r){const i=l(this.tileCoordRange,t.xTile,s.level,s.col,e.key.level,e.key.col),n=l(this.tileCoordRange,t.yTile,s.level,s.row,e.key.level,e.key.row);i>=0&&i<this.tileCoordRange&&n>=0&&n<this.tileCoordRange&&o.push({symbol:t,xTransformed:i,yTransformed:n})}const y=[],a=(e.key.level<s.level?1:1<<e.key.level-s.level)+n,f=this._tiles.get(e.id).symbols.get(i);if(f){const e=f.flat;for(const s of o){let l,o=!1;const t=s.xTransformed,i=s.yTransformed;l=null!=f.index?f.index.getCell(t,i):e;const n=s.symbol,r=n.hash;for(const e of l)if(r===e.hash&&Math.abs(t-e.xTile)<=a&&Math.abs(i-e.yTile)<=a){const s=e.unique;n.unique=s,s.tileSymbols.push(n),o=!0;break}o||y.push(n)}}y.length>0&&t.set(i,y)}for(const l of e.childrenTiles)this._matchSymbols(l,s,t)}_createUniqueSymbolLayerArray(){const e=this._uniqueSymbolsReferences,s=new Array(e.size);let l,o=0;for(const[t,i]of e){const e=new Array(i.size);l=0;for(const s of i)e[l++]=s;s[o]={styleLayerUID:t,uniqueSymbols:e},o++}return s}}export{r as SymbolRepository};