/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import e from"../../../../Graphic.js";import{getOrCreateMapValue as t}from"../../../../core/MapUtils.js";import s from"../../../../core/pbf.js";import{PooledRBush as r}from"../../../../core/libs/rbush/PooledRBush.js";import i from"../../../../graphic/VectorTileGraphicOrigin.js";import{tilePixelSize as o,tileCoordSize as l,tilePixelRatio as n}from"./constants.js";import a from"./Feature.js";import{getTileMargins as y}from"./GeometryUtils.js";import c from"./SourceLayerData.js";import{IndexItem as u}from"./style/StyleLayer.js";const h=(e,t)=>{const s=e.vtlSymbol.sourceTile,r=t.vtlSymbol.sourceTile;return s.level!==r.level?s.level-r.level:s.row!==r.row?s.row-r.row:s.col!==r.col?s.col-r.col:e.styleLayerUID-t.styleLayerUID};class m{constructor(e,t,s,r,i){this.tileKey=e,this._tileLayerData=t,this._styleRepository=s,this._tileHandler=r,this._parentLayer=i,this._index=null,this._tileKeyToPBF=new Map}static create(e,t,s,r,i){return new m(e,t,s,r,i)}clear(){this._index?.clear(),this._tileKeyToPBF.clear()}async queryAttributes(e,t,s,i,o){if(0===this._tileLayerData.size||!this._styleRepository||!this._tileHandler)return[];null===this._index&&(this._index=new r(100,f),await this._indexLayers());const l=[];return this._queryIndex(l,e,t,s,this.tileKey.level,i),o&&o?.length>0&&await this._getSymbolsAttributes(l,o),l}async _indexLayers(){const e=this.tileKey,t=this._styleRepository.layers,s=await this._getTilePayload(e);for(const[r,i]of this._tileLayerData){const o=t[r],l=s.find(e=>e.sourceName===o.source);if(!l)continue;const{protobuff:n,key:a}=l;if(3!==i.type){const t=1<<e.level-a.level,s=e.row-a.row*t,r=e.col-a.col*t;this._indexLayer(o,n,e.level,t,s,r)}}}_indexLayer(e,t,r,i,n,h){const m=e.sourceLayer,f=e.getFeatureFilter(),d=r,_=r+1,p=y(d),g=new s(new Uint8Array(t),new DataView(t));for(;g.next();)switch(g.tag()){case 3:{const t=g.getMessage(),s=new c(t);if(t.release(),s.name!==m)continue;const y=s.getData(),w=s.extent/i,b=w*h-p,x=w*n-p,L=b+w+2*p,v=x+w+2*p,I=w/o,T=l/w,D=w*h,P=w*n;for(;y.nextTag(2);){const t=y.getMessage(),i=new a(t,s);if(t.release(),f&&!f.filter(i,r))continue;const o=i.values||{},l=o._minzoom,n=o._maxzoom;if(l&&l>=10*_||n&&n<=10*d)continue;const c=e.getFeatureInflatedBounds(i,d,s.extent,I);null==c||c[0]>L||c[1]>v||c[2]<b||c[3]<x||(c[0]=(c[0]-D)*T,c[1]=(c[1]-P)*T,c[2]=(c[2]-D)*T,c[3]=(c[3]-P)*T,this._index.insert(new u(e,i,c,T,D,P)))}break}default:g.skip()}g.release()}async _getSymbolsAttributes(e,t){if(!t||0===t.length)return e;const s=[];if(t.sort(h),t.length>0){let e=0,{styleLayerUID:r}=t[0];for(let o=1;o<t.length;o++){const{styleLayerUID:i}=t[o];i!==r&&(s.push({from:e,to:o,styleLayerUID:r,sourceTileKey:t[o-1].vtlSymbol.sourceTile}),e=o,r=i)}const i=t.length-1;s.push({from:e,to:t.length,styleLayerUID:r,sourceTileKey:t[i].vtlSymbol.sourceTile})}const r=this._styleRepository.layers;for(const i of s){const s=await this._getTilePayload(i.sourceTileKey),o=r[i.styleLayerUID],l=!!o&&s.find(e=>e.sourceName===o.source);l&&this._addSymbolsAttributes(e,t.slice(i.from,i.to).map(e=>e.vtlSymbol.featureIndex),i.styleLayerUID,l)}return e}_addSymbolsAttributes(t,s,r,o){const l=this._styleRepository.layers,n=o.key,a=this.tileKey,y=1<<a.level-n.level,c=a.row-n.row*y,u=a.col-n.col*y;this._getSymbolAttributes(o.protobuff,s,r,y,c,u).forEach(s=>{const{attributes:o,tilePoint:n}=s;t.push({layerId:l[r].id,layerIndex:r,graphic:new e({attributes:o,origin:new i(this._parentLayer,l[r].id,r)}),tilePoint:n})})}_getSymbolAttributes(e,t,r,i,o,n){const y=[],u=this._styleRepository.layers;let h=0;t.sort((e,t)=>e-t);const m=new s(new Uint8Array(e),new DataView(e));for(;m.next();)switch(m.tag()){case 3:{const e=m.getMessage(),s=new c(e);if(e.release(),s.name!==u[r].sourceLayer)continue;const f=s.getData(),d=s.extent/i,_=l/d,p=d*n,g=d*o;let w=0;for(;f.nextTag(2);){const e=f.getMessage();if(w++===t[h]){const t=new a(e,s),r=t.values,i=t.getGeometry(),o=null!=i?[_*(i[0][0].x-p),_*(i[0][0].y-g)]:null;y.push({attributes:r,tilePoint:o}),h++}if(e.release(),h===t.length)return y}break}default:m.skip()}return m.release(),y}_queryIndex(t,s,r,o,l,a){const y=n*o*(window.devicePixelRatio||1);return this._index?.search({minX:s-y,minY:r-y,maxX:s+y,maxY:r+y},n=>{const{layer:y,feature:c}=n;y.isIntersectingFeature(s,r,o,c,l,a,n)&&t.push({layerId:y.id,layerIndex:y.uid,tilePoint:null,graphic:new e({attributes:c.values,origin:new i(this._parentLayer,n.layer.id,n.layer.uid)})})}),t}async _getTilePayload(e){return t(this._tileKeyToPBF,e.id,()=>this._tileHandler.fetchTilePBFs(e)).then(e=>e)}}const f=e=>({minX:e.bounds[0],minY:e.bounds[1],maxX:e.bounds[2],maxY:e.bounds[3]});export{m as default};
