@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.75 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 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{BucketType as i}from"./enums.js";import o from"./Feature.js";import{getTileMargins as l}from"./GeometryUtils.js";import a from"./SourceLayerData.js";import{IndexItem as n}from"./style/StyleLayer.js";const y=8,c=512,u=4096,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 d{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 d(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,m),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,o]of this._tileLayerData){const l=t[r],a=s.find((e=>e.sourceName===l.source));if(!a)continue;const{protobuff:n,key:y}=a;if(o.type!==i.SYMBOL){const t=1<<e.level-y.level,s=e.row-y.row*t,r=e.col-y.col*t;this._indexLayer(l,n,e.level,t,s,r)}}}_indexLayer(e,t,r,i,y,h){const d=e.sourceLayer,m=e.getFeatureFilter(),f=r,_=r+1,p=l(f),g=new s(new Uint8Array(t),new DataView(t));for(;g.next();)switch(g.tag()){case 3:{const t=g.getMessage(),s=new a(t);if(t.release(),s.name!==d)continue;const l=s.getData(),w=s.extent/i,x=w*h-p,b=w*y-p,I=x+w+2*p,L=b+w+2*p,v=w/c,D=u/w,T=w*h,S=w*y;for(;l.nextTag(2);){const t=l.getMessage(),i=new o(t,s);if(t.release(),m&&!m.filter(i,r))continue;const a=i.values||{},y=a._minzoom,c=a._maxzoom;if(y&&y>=10*_||c&&c<=10*f)continue;const u=e.getFeatureInflatedBounds(i,f,s.extent,v);null==u||u[0]>I||u[1]>L||u[2]<x||u[3]<b||(u[0]=(u[0]-T)*D,u[1]=(u[1]-S)*D,u[2]=(u[2]-T)*D,u[3]=(u[3]-S)*D,this._index.insert(new n(e,i,u,D,T,S)))}break}default:g.skip()}}async _getSymbolsAttributes(e,t){if(!t||0===t.length)return e;const s=[];t.sort(h);let r=t[0].styleLayerUID,i=0;for(let l=0;l<t.length;l++)r!==t[l].styleLayerUID&&(s.push({from:i,to:l,styleLayerUID:r,sourceTileKey:t[l].vtlSymbol.sourceTile}),i=l,r=t[l].styleLayerUID);s.push({from:i,to:t.length,styleLayerUID:r,sourceTileKey:t[t.length-1].vtlSymbol.sourceTile});const o=this._styleRepository.layers;for(const l of s){const s=await this._getTilePayload(l.sourceTileKey),i=o[l.styleLayerUID],a=!!i&&s.find((e=>e.sourceName===i.source));a&&this._addSymbolsAttributes(e,t.slice(l.from,l.to).map((e=>e.vtlSymbol)),r,a)}return e}_addSymbolsAttributes(t,s,r,i){const o=this._styleRepository.layers,l=i.key,a=this.tileKey,n=1<<a.level-l.level,y=a.row-l.row*n,c=a.col-l.col*n;this._getSymbolAttributes(i.protobuff,s,r,n,y,c).forEach((s=>{const{attributes:i,tilePoint:l}=s;t.push({layerId:o[r].id,layerIndex:r,graphic:new e({attributes:i,origin:{type:"vector-tile",layerId:o[r].id,layerIndex:r,layer:this._parentLayer}}),tilePoint:l})}))}_getSymbolAttributes(e,t,r,i,l,n){const y=[],c=this._styleRepository.layers;let h=0;t.sort(((e,t)=>e.featureIndex-t.featureIndex));const d=new s(new Uint8Array(e),new DataView(e));for(;d.next();)switch(d.tag()){case 3:{const e=d.getMessage(),s=new a(e);if(e.release(),s.name!==c[r].sourceLayer)continue;const m=s.getData(),f=s.extent/i,_=u/f,p=f*n,g=f*l;let w=0;for(;m.nextTag(2);){const e=m.getMessage();if(w++===t[h].featureIndex){const t=new o(e,s),r=t.values,i=t.getGeometry(),l=null!=i?[_*(i[0][0].x-p),_*(i[0][0].y-g)]:null;y.push({attributes:r,tilePoint:l}),h++}if(e.release(),h===t.length)return y}break}default:d.skip()}return y}_queryIndex(t,s,r,i,o,l){const a=y*i*(window.devicePixelRatio||1);return this._index?.search({minX:s-a,minY:r-a,maxX:s+a,maxY:r+a},(a=>{const{layer:n,feature:y}=a;n.isIntersectingFeature(s,r,i,y,o,l,a)&&t.push({layerId:n.id,layerIndex:n.uid,tilePoint:null,graphic:new e({attributes:y.values,origin:{type:"vector-tile",layerId:a.layer.id,layerIndex:a.layer.uid,layer:this._parentLayer}})})})),t}async _getTilePayload(e){return t(this._tileKeyToPBF,e.id,(()=>this._tileHandler.fetchTilePBFs(e))).then((e=>e))}}const m=e=>({minX:e.bounds[0],minY:e.bounds[1],maxX:e.bounds[2],maxY:e.bounds[3]});export{d as default};