1 |
- import{s as J,a7 as D,da as N,aq as W,ci as g,t as T,e8 as K,b5 as X,e9 as Y,a as v,g as d,bA as I,cx as $,dW as ee,ea as k,eb as A,aM as L,cq as te,ec as U,ed as ie,cz as q,cy as se,ee as O}from"./index.6c049565.js";const z=J.getLogger("esri.layers.support.ElevationSampler");class Q{queryElevation(e){return oe(e.clone(),this)}on(){return ce}projectIfRequired(e,t){return B(e,t)}}class ne extends Q{constructor(e,t,i){super(),this.tile=e,this.noDataValue=i;const s=e.tile.extent;this.extent=N(s,t.spatialReference),this.extent.zmin=e.zmin,this.extent.zmax=e.zmax,this._aaExtent=s;const n=g(t.spatialReference),o=t.lodAt(e.tile.level).resolution*n;this.demResolution={min:o,max:o}}get spatialReference(){return this.extent.spatialReference}contains(e){const t=this.projectIfRequired(e,this.spatialReference);return!T(t)&&this.containsAt(t.x,t.y)}containsAt(e,t){return K(this._aaExtent,e,t)}elevationAt(e,t){if(!this.containsAt(e,t)){const i=this.extent,s=`${i.xmin}, ${i.ymin}, ${i.xmax}, ${i.ymax}`;return z.warn("#elevationAt()",`Point used to sample elevation (${e}, ${t}) is outside of the sampler extent (${s})`),this.noDataValue}return X(this.tile.sample(e,t),this.noDataValue)}}class Z extends Q{constructor(e,t,i){let s;super(),typeof t=="number"?(this.noDataValue=t,s=null):(s=t,this.noDataValue=i),this.samplers=s?e.map(o=>new ne(o,s,this.noDataValue)):e;const n=this.samplers[0];if(n){this.extent=n.extent.clone();const{min:o,max:l}=n.demResolution;this.demResolution={min:o,max:l};for(let a=1;a<this.samplers.length;a++){const c=this.samplers[a];this.extent.union(c.extent),this.demResolution.min=Math.min(this.demResolution.min,c.demResolution.min),this.demResolution.max=Math.max(this.demResolution.max,c.demResolution.max)}}else this.extent=N(W(),s.spatialReference),this.demResolution={min:0,max:0}}get spatialReference(){return this.extent.spatialReference}elevationAt(e,t){for(const i of this.samplers)if(i.containsAt(e,t))return i.elevationAt(e,t);return z.warn("#elevationAt()",`Point used to sample elevation (${e}, ${t}) is outside of the sampler`),this.noDataValue}}function oe(r,e){const t=B(r,e.spatialReference);if(!t)return null;switch(r.type){case"point":ae(r,t,e);break;case"polyline":le(r,t,e);break;case"multipoint":re(r,t,e)}return r}function B(r,e){if(T(r))return null;const t=r.spatialReference;if(t.equals(e))return r;const i=Y(r,e);return i||z.error(`Cannot project geometry spatial reference (wkid:${t.wkid}) to elevation sampler spatial reference (wkid:${e.wkid})`),i}function ae(r,e,t){r.z=t.elevationAt(e.x,e.y)}function le(r,e,t){y.spatialReference=e.spatialReference;const i=r.hasM&&!r.hasZ;for(let s=0;s<r.paths.length;s++){const n=r.paths[s],o=e.paths[s];for(let l=0;l<n.length;l++){const a=n[l],c=o[l];y.x=c[0],y.y=c[1],i&&(a[3]=a[2]),a[2]=t.elevationAt(y.x,y.y)}}r.hasZ=!0}function re(r,e,t){y.spatialReference=e.spatialReference;const i=r.hasM&&!r.hasZ;for(let s=0;s<r.points.length;s++){const n=r.points[s],o=e.points[s];y.x=o[0],y.y=o[1],i&&(n[3]=n[2]),n[2]=t.elevationAt(y.x,y.y)}r.hasZ=!0}const y=new D,ce={remove(){}};class ue{constructor({values:e,width:t,height:i,noDataValue:s},n){this.pixelData=e,this.width=t,this.height=i,this.safeWidth=.99999999*(t-1),this.noDataValue=s,this.dx=(t-1)/(n[2]-n[0]),this.dy=(t-1)/(n[3]-n[1]),this.x0=n[0],this.y1=n[3]}}class G{constructor(e,t=null){if(this.tile=e,this.zmin=0,this.zmax=0,v(t)&&v(e)){const i=e.extent;this._samplerData=new ue(t,i),this.zmin=t.minValue,this.zmax=t.maxValue}}sample(e,t){if(T(this._samplerData))return;const{safeWidth:i,width:s,pixelData:n,noDataValue:o,dx:l,dy:a,y1:c,x0:u}=this._samplerData,m=P(a*(c-t),0,i),p=P(l*(e-u),0,i),h=Math.floor(m),M=Math.floor(p),_=h*s+M,C=_+s,R=n[_],E=n[C],F=n[_+1],b=n[C+1];if(R!==o&&E!==o&&F!==o&&b!==o){const V=p-M,S=R+(F-R)*V;return S+(E+(b-E)*V-S)*(m-h)}}}function P(r,e,t){return r<e?e:r>t?t:r}class fe{async queryAll(e,t,i){if(!(e=i&&i.ignoreInvisibleLayers?e.filter(c=>c.visible):e.slice()).length)throw new d("elevation-query:invalid-layer","Elevation queries require at least one elevation layer to fetch tiles from");const s=x.fromGeometry(t);let n=!1;i&&i.returnSampleInfo||(n=!0);const o={...w,...i,returnSampleInfo:!0},l=await this.query(e[e.length-1],s,o),a=await this._queryAllContinue(e,l,o);return a.geometry=a.geometry.export(),n&&delete a.sampleInfo,a}async query(e,t,i){if(!e)throw new d("elevation-query:invalid-layer","Elevation queries require an elevation layer to fetch tiles from");if(!t||!(t instanceof x)&&t.type!=="point"&&t.type!=="multipoint"&&t.type!=="polyline")throw new d("elevation-query:invalid-geometry","Only point, polyline and multipoint geometries can be used to query elevation");const s={...w,...i},n=new he(e,t.spatialReference,s),o=s.signal;return await e.load({signal:o}),await this._createGeometryDescriptor(n,t,o),await this._selectTiles(n,o),await this._populateElevationTiles(n,o),this._sampleGeometryWithElevation(n),this._createQueryResult(n,o)}async createSampler(e,t,i){if(!e)throw new d("elevation-query:invalid-layer","Elevation queries require an elevation layer to fetch tiles from");if(!t||t.type!=="extent")throw new d("elevation-query:invalid-extent","Invalid or undefined extent");const s={...w,...i};return this._createSampler(e,t,s)}async createSamplerAll(e,t,i){if(!(e=i&&i.ignoreInvisibleLayers?e.filter(o=>o.visible):e.slice()).length)throw new d("elevation-query:invalid-layer","Elevation queries require at least one elevation layer to fetch tiles from");if(!t||t.type!=="extent")throw new d("elevation-query:invalid-extent","Invalid or undefined extent");const s={...w,...i,returnSampleInfo:!0},n=await this._createSampler(e[e.length-1],t,s);return this._createSamplerAllContinue(e,t,n,s)}async _createSampler(e,t,i,s){const n=i.signal;await e.load({signal:n});const o=t.spatialReference,l=e.tileInfo.spatialReference;o.equals(l)||(await I([{source:o,dest:l}],{signal:n}),t=$(t,l));const a=new pe(e,t,i,s);return await this._selectTiles(a,n),await this._populateElevationTiles(a,n),new Z(a.elevationTiles,a.layer.tileInfo,a.options.noDataValue)}async _createSamplerAllContinue(e,t,i,s){if(e.pop(),!e.length)return i;const n=i.samplers.map(c=>ee(c.extent)),o=await this._createSampler(e[e.length-1],t,s,n);if(o.samplers.length===0)return i;const l=i.samplers.concat(o.samplers),a=new Z(l,s.noDataValue);return this._createSamplerAllContinue(e,t,a,s)}async _queryAllContinue(e,t,i){const s=e.pop(),n=t.geometry.coordinates,o=t.sampleInfo;k(o);const l=[],a=[];for(let p=0;p<n.length;p++){const h=o[p];h.demResolution>=0?h.source||(h.source=s):e.length&&(l.push(n[p]),a.push(p))}if(!e.length||l.length===0)return t;const c=t.geometry.clone(l),u=await this.query(e[e.length-1],c,i),m=u.sampleInfo;if(!m)throw new Error("no sampleInfo");return a.forEach((p,h)=>{n[p].z=u.geometry.coordinates[h].z,o[p].demResolution=m[h].demResolution}),this._queryAllContinue(e,t,i)}async _createQueryResult(e,t){const i=await e.geometry.project(e.outSpatialReference,t);k(i);const s={geometry:i.export(),noDataValue:e.options.noDataValue};return e.options.returnSampleInfo&&(s.sampleInfo=this._extractSampleInfo(e)),e.geometry.coordinates.forEach(n=>{n.tile=null,n.elevationTile=null}),s}async _createGeometryDescriptor(e,t,i){let s;const n=e.layer.tileInfo.spatialReference;if(t instanceof x?s=await t.project(n,i):(await I([{source:t.spatialReference,dest:n}],{signal:i}),s=$(t,n)),!s)throw new d("elevation-query:spatial-reference-mismatch",`Cannot query elevation in '${t.spatialReference.wkid}' on an elevation service in '${n.wkid}'`);e.geometry=x.fromGeometry(s)}async _selectTiles(e,t){const i=e.options.demResolution;if(e.type==="geometry"&&this._preselectOutsideLayerExtent(e),typeof i=="number")this._selectTilesClosestResolution(e);else if(i==="finest-contiguous")await this._selectTilesFinestContiguous(e,t);else{if(i!=="auto")throw new d("elevation-query:invalid-dem-resolution",`Invalid dem resolution value '${i}', expected a number, "finest-contiguous" or "auto"`);await this._selectTilesAuto(e,t)}}_preselectOutsideLayerExtent(e){if(T(e.layer.fullExtent))return;const t=new G(null);t.sample=()=>e.options.noDataValue,e.outsideExtentTile=t;const i=e.layer.fullExtent;e.geometry.coordinates.forEach(s=>{const n=s.x,o=s.y;(n<i.xmin||n>i.xmax||o<i.ymin||o>i.ymax)&&(s.elevationTile=t)})}_selectTilesClosestResolution(e){const t=e.layer.tileInfo,i=this._findNearestDemResolutionLODIndex(t,e.options.demResolution);e.selectTilesAtLOD(i)}_findNearestDemResolutionLODIndex(e,t){const i=t/g(e.spatialReference);let s=e.lods[0],n=0;for(let o=1;o<e.lods.length;o++){const l=e.lods[o];Math.abs(l.resolution-i)<Math.abs(s.resolution-i)&&(s=l,n=o)}return n}async _selectTilesFinestContiguous(e,t){const i=j(e.layer.tileInfo,e.options.minDemResolution);await this._selectTilesFinestContiguousAt(e,i,t)}async _selectTilesFinestContiguousAt(e,t,i){const s=e.layer;if(e.selectTilesAtLOD(t),t<0)return;const n=s.tilemapCache,o=e.getTilesToFetch();try{if(n)await A(Promise.all(o.map(l=>n.fetchAvailability(l.level,l.row,l.col,{signal:i}))),i);else if(await this._populateElevationTiles(e,i),!e.allElevationTilesFetched())throw e.clearElevationTiles(),new d("elevation-query:has-unavailable-tiles")}catch(l){L(l),await this._selectTilesFinestContiguousAt(e,t-1,i)}}async _populateElevationTiles(e,t){const i=e.getTilesToFetch(),s={},n=e.options.cache,o=e.options.noDataValue,l=i.map(async a=>{if(a.id==null)return;const c=`${e.layer.uid}:${a.id}:${o}`,u=v(n)?n.get(c):null,m=v(u)?u:await e.layer.fetchTile(a.level,a.row,a.col,{noDataValue:o,signal:t});v(n)&&n.put(c,m),s[a.id]=new G(a,m)});await A(te(l),t),e.populateElevationTiles(s)}async _selectTilesAuto(e,t){this._selectTilesAutoFinest(e),this._reduceTilesForMaximumRequests(e);const i=e.layer.tilemapCache;if(!i)return this._selectTilesAutoPrefetchUpsample(e,t);const s=e.getTilesToFetch(),n={},o=s.map(async l=>{const a=new U(null,0,0,0,W()),c=await ie(i.fetchAvailabilityUpsample(l.level,l.row,l.col,a,{signal:t}));c.ok!==!1?l.id!=null&&(n[l.id]=a):L(c.error)});await A(Promise.all(o),t),e.remapTiles(n)}_reduceTilesForMaximumRequests(e){const t=e.layer.tileInfo;let i=0;const s={},n=a=>{a.id!=null&&(a.id in s?s[a.id]++:(s[a.id]=1,i++))},o=a=>{if(a.id==null)return;const c=s[a.id];c===1?(delete s[a.id],i--):s[a.id]=c-1};e.forEachTileToFetch(n,o);let l=!0;for(;l&&(l=!1,e.forEachTileToFetch(a=>{i<=e.options.maximumAutoTileRequests||(o(a),t.upsampleTile(a)&&(l=!0),n(a))},o),l););}_selectTilesAutoFinest(e){const t=j(e.layer.tileInfo,e.options.minDemResolution);e.selectTilesAtLOD(t,e.options.maximumAutoTileRequests)}async _selectTilesAutoPrefetchUpsample(e,t){const i=e.layer.tileInfo;await this._populateElevationTiles(e,t);let s=!1;e.forEachTileToFetch((n,o)=>{i.upsampleTile(n)?s=!0:o()}),s&&await this._selectTilesAutoPrefetchUpsample(e,t)}_sampleGeometryWithElevation(e){e.geometry.coordinates.forEach(t=>{const i=t.elevationTile;let s=e.options.noDataValue;if(i){const n=i.sample(t.x,t.y);v(n)?s=n:t.elevationTile=null}t.z=s})}_extractSampleInfo(e){const t=e.layer.tileInfo,i=g(t.spatialReference);return e.geometry.coordinates.map(s=>{let n=-1;return s.elevationTile&&s.elevationTile!==e.outsideExtentTile&&(n=t.lodAt(s.elevationTile.tile.level).resolution*i),{demResolution:n}})}}class x{export(){return this._exporter(this.coordinates,this.spatialReference)}clone(e){const t=new x;return t.geometry=this.geometry,t.spatialReference=this.spatialReference,t.coordinates=e||this.coordinates.map(i=>i.clone()),t._exporter=this._exporter,t}async project(e,t){if(this.spatialReference.equals(e))return this.clone();await I([{source:this.spatialReference,dest:e}],{signal:t});const i=new q({spatialReference:this.spatialReference,points:this.coordinates.map(l=>[l.x,l.y])}),s=$(i,e);if(!s)return null;const n=this.coordinates.map((l,a)=>{const c=l.clone(),u=s.points[a];return c.x=u[0],c.y=u[1],c}),o=this.clone(n);return o.spatialReference=e,o}static fromGeometry(e){const t=new x;if(t.geometry=e,t.spatialReference=e.spatialReference,e instanceof x)t.coordinates=e.coordinates.map(i=>i.clone()),t._exporter=(i,s)=>{const n=e.clone(i);return n.spatialReference=s,n};else switch(e.type){case"point":{const i=e,{hasZ:s,hasM:n}=i;t.coordinates=s&&n?[new f(i.x,i.y,i.z,i.m)]:s?[new f(i.x,i.y,i.z)]:n?[new f(i.x,i.y,null,i.m)]:[new f(i.x,i.y)],t._exporter=(o,l)=>e.hasM?new D(o[0].x,o[0].y,o[0].z,o[0].m,l):new D(o[0].x,o[0].y,o[0].z,l);break}case"multipoint":{const i=e,{hasZ:s,hasM:n}=i;t.coordinates=s&&n?i.points.map(o=>new f(o[0],o[1],o[2],o[3])):s?i.points.map(o=>new f(o[0],o[1],o[2])):n?i.points.map(o=>new f(o[0],o[1],null,o[2])):i.points.map(o=>new f(o[0],o[1])),t._exporter=(o,l)=>e.hasM?new q({points:o.map(a=>[a.x,a.y,a.z,a.m]),hasZ:!0,hasM:!0,spatiaReference:l}):new q(o.map(a=>[a.x,a.y,a.z]),l);break}case"polyline":{const i=e,s=[],n=[],{hasZ:o,hasM:l}=e;let a=0;for(const c of i.paths)if(n.push([a,a+c.length]),a+=c.length,o&&l)for(const u of c)s.push(new f(u[0],u[1],u[2],u[3]));else if(o)for(const u of c)s.push(new f(u[0],u[1],u[2]));else if(l)for(const u of c)s.push(new f(u[0],u[1],null,u[2]));else for(const u of c)s.push(new f(u[0],u[1]));t.coordinates=s,t._exporter=(c,u)=>{const m=e.hasM?c.map(h=>[h.x,h.y,h.z,h.m]):c.map(h=>[h.x,h.y,h.z]),p=n.map(h=>m.slice(h[0],h[1]));return new se({paths:p,hasM:e.hasM,hasZ:!0,spatialReference:u})};break}}return t}}class f{constructor(e,t,i=null,s=null,n=null,o=null){this.x=e,this.y=t,this.z=i,this.m=s,this.tile=n,this.elevationTile=o}clone(){return new f(this.x,this.y,this.z,this.m)}}class H{constructor(e,t){this.layer=e,this.options=t}}class he extends H{constructor(e,t,i){super(e,i),this.outSpatialReference=t,this.type="geometry"}selectTilesAtLOD(e){if(e<0)this.geometry.coordinates.forEach(t=>{t.tile=null});else{const t=this.layer.tileInfo,i=t.lods[e].level;this.geometry.coordinates.forEach(s=>{s.tile=t.tileAt(i,s.x,s.y)})}}allElevationTilesFetched(){return!this.geometry.coordinates.some(e=>!e.elevationTile)}clearElevationTiles(){for(const e of this.geometry.coordinates)e.elevationTile!==this.outsideExtentTile&&(e.elevationTile=null)}populateElevationTiles(e){var t;for(const i of this.geometry.coordinates)!i.elevationTile&&((t=i.tile)==null?void 0:t.id)&&(i.elevationTile=e[i.tile.id])}remapTiles(e){var t;for(const i of this.geometry.coordinates){const s=(t=i.tile)==null?void 0:t.id;i.tile=s?e[s]:null}}getTilesToFetch(){var i;const e={},t=[];for(const s of this.geometry.coordinates){const n=s.tile;if(!n)continue;const o=(i=s.tile)==null?void 0:i.id;s.elevationTile||!o||e[o]||(e[o]=n,t.push(n))}return t}forEachTileToFetch(e){for(const t of this.geometry.coordinates)t.tile&&!t.elevationTile&&e(t.tile,()=>{t.tile=null})}}class pe extends H{constructor(e,t,i,s){super(e,i),this.type="extent",this.elevationTiles=[],this._candidateTiles=[],this._fetchedCandidates=new Set,this.extent=t.intersection(e.fullExtent),this.maskExtents=s}selectTilesAtLOD(e,t){const i=this._maximumLodForRequests(t),s=Math.min(i,e);s<0?this._candidateTiles.length=0:this._selectCandidateTilesCoveringExtentAt(s)}_maximumLodForRequests(e){const t=this.layer.tileInfo;if(!e)return t.lods.length-1;const i=this.extent;if(T(i))return-1;for(let s=t.lods.length-1;s>=0;s--){const n=t.lods[s],o=n.resolution*t.size[0],l=n.resolution*t.size[1];if(Math.ceil(i.width/o)*Math.ceil(i.height/l)<=e)return s}return-1}allElevationTilesFetched(){return this._candidateTiles.length===this.elevationTiles.length}clearElevationTiles(){this.elevationTiles.length=0,this._fetchedCandidates.clear()}populateElevationTiles(e){for(const t of this._candidateTiles){const i=t.id&&e[t.id];i&&(this._fetchedCandidates.add(t),this.elevationTiles.push(i))}}remapTiles(e){this._candidateTiles=this._uniqueNonOverlappingTiles(this._candidateTiles.map(t=>e[t.id]))}getTilesToFetch(){return this._candidateTiles}forEachTileToFetch(e,t){const i=this._candidateTiles;this._candidateTiles=[],i.forEach(s=>{if(this._fetchedCandidates.has(s))return void(t&&t(s));let n=!1;e(s,()=>n=!0),n?t&&t(s):this._candidateTiles.push(s)}),this._candidateTiles=this._uniqueNonOverlappingTiles(this._candidateTiles,t)}_uniqueNonOverlappingTiles(e,t){const i={},s=[];for(const o of e){const l=o.id;l&&!i[l]?(i[l]=o,s.push(o)):t&&t(o)}const n=s.sort((o,l)=>o.level-l.level);return n.filter((o,l)=>{for(let a=0;a<l;a++){const c=n[a].extent;if(c&&o.extent&&O(c,o.extent))return t&&t(o),!1}return!0})}_selectCandidateTilesCoveringExtentAt(e){this._candidateTiles.length=0;const t=this.extent;if(T(t))return;const i=this.layer.tileInfo,s=i.lods[e],n=i.tileAt(s.level,t.xmin,t.ymin),o=n.extent;if(T(o))return;const l=s.resolution*i.size[0],a=s.resolution*i.size[1],c=Math.ceil((t.xmax-o[0])/l),u=Math.ceil((t.ymax-o[1])/a);for(let m=0;m<u;m++)for(let p=0;p<c;p++){const h=new U(null,n.level,n.row-m,n.col+p);i.updateTileInfo(h),this._tileIsMasked(h)||this._candidateTiles.push(h)}}_tileIsMasked(e){return!!this.maskExtents&&this.maskExtents.some(t=>e.extent&&O(t,e.extent))}}function j(r,e=0){let t=r.lods.length-1;if(e>0){const i=e/g(r.spatialReference),s=r.lods.findIndex(n=>n.resolution<i);s===0?t=0:s>0&&(t=s-1)}return t}const w={maximumAutoTileRequests:20,noDataValue:0,returnSampleInfo:!1,demResolution:"auto",minDemResolution:0};export{fe as ElevationQuery,x as GeometryDescriptor,j as getFinestLodIndex};
|