@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 8.28 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.19/LICENSE.txt */
import{result as e}from"../../core/asyncUtils.js";import t from"../../core/Error.js";import{assertIsSome as a}from"../../core/maybe.js";import{whenOrAbort as n,throwIfAbortError as o}from"../../core/promiseUtils.js";import{getMetersPerUnitForSR as i}from"../../core/units.js";import{initializeProjection as l,project as r}from"../../geometry/projectionUtils.js";import{fromExtent as s}from"../../geometry/support/aaBoundingRect.js";import{GeometryQueryContext as c,ExtentQueryContext as u,isTileInfoTilemapCache as m,getLods as f}from"./ElevationQueryContext.js";import{ElevationTile as p}from"./ElevationTile.js";import y from"./ElevationTileData.js";import{GeometryDescriptor as d}from"./GeometryDescriptor.js";import{TileElevationSampler as w}from"./TileElevationSampler.js";import{TileKey as h}from"./TileKey.js";async function v(e,a,n){if(e=n?.ignoreInvisibleLayers?e.filter(e=>e.visible):e.slice(),!e.length)throw new t(N,"Elevation queries require at least one elevation layer to fetch tiles from");const o=d.fromGeometry(a),i={...j,...n,returnSampleInfo:!0},l=e.pop(),r=await g(l,o,i),s=await I(e,r,i);return s.geometry=s.geometry.export(),n?.returnSampleInfo||delete s.sampleInfo,s}async function g(e,a,n){if(!e)throw new t(N,"Elevation queries require an elevation layer to fetch tiles from");if(!a||!(a instanceof d)&&"point"!==a.type&&"multipoint"!==a.type&&"polyline"!==a.type)throw new t("elevation-query:invalid-geometry","Only point, polyline and multipoint geometries can be used to query elevation");const o={...j,...n},i=o.signal;if("integrated-mesh-3dtiles"===e.type){const t=d.fromGeometry(a);if(e.queryElevationCallback&&e.replacesTerrain){const l=12.9*(n?.minDemResolution||0)+.71,r=await e.queryElevationCallback(t,{signal:i,maxGeometricError:l}),s=t.coordinates.map(()=>({demResolution:1,source:e})),c=await r.project(a.spatialReference,i);if(c){if(void 0!==o.noDataValue&&o.noDataValue!==Number.MAX_VALUE)for(const e of c.coordinates)e.z===Number.MAX_VALUE&&(e.z=o.noDataValue);return{geometry:c.export(),noDataValue:o.noDataValue??Number.MAX_VALUE,sampleInfo:s}}}const l=t.coordinates.map(()=>({demResolution:-1,source:e}));return{geometry:t.export(),noDataValue:Number.MAX_VALUE,sampleInfo:l}}const l=new c(e,a.spatialReference,o);return await e.load({signal:i}),await C(l,a,i),await R(l,i),await k(l,i),$(l),z(l,i)}async function T(e,a,n){if(e=Array.isArray(e)?e:[e],0===(e=n?.ignoreInvisibleLayers?e.filter(e=>e.visible):e.slice()).length)throw new t(N,"Elevation queries require at least one elevation layer to fetch tiles from");if(!a||"extent"!==a.type)throw new t("elevation-query:invalid-extent","Invalid or undefined extent");const o={...j,...n,returnSampleInfo:!0},i=E(e[e.length-1],a,o);if(1===e.length)return i;return D(e,a,await i,o)}async function E(e,t,a,n){const o=a.signal;await e.load({signal:o});const i=t.spatialReference,s=e.tileInfo.spatialReference;i.equals(s)||(await l([{source:i,dest:s}],{signal:o}),t=r(t,s));const c=new u(e,t,a,n);await R(c,o),await k(c,o);const m=c.elevationTiles,f=c.layer.tileInfo,p=c.parameters.noDataValue;return new w({noDataValue:p,tiles:m,tileInfo:f})}async function D(e,t,a,n){if(e.pop(),!e.length)return a;const o=a.samplers.filter(e=>!e.tile.hasNoDataValues).map(e=>s(e.extent)),i=await E(e[e.length-1],t,n,o);if(0===i.samplers.length)return a;const l=a.samplers.concat(i.samplers),r=n.noDataValue;return D(e,t,new w({samplers:l,noDataValue:r}),n)}async function I(e,t,n){const o=t.geometry.coordinates,i=t.sampleInfo;a(i);const l=new Array,r=new Array;for(let a=0;a<o.length;a++){i[a].demResolution<0&&e.length&&(l.push(o[a]),r.push(a))}const s=e.pop();if(null==s||0===l.length)return t;const c=t.geometry.clone(l),u=await g(s,c,n),m=u.sampleInfo;if(!m)throw new Error("no sampleInfo");return r.forEach((e,t)=>{o[e].z=u.geometry.coordinates[t].z,i[e].demResolution=m[t].demResolution,i[e].source=m[t].source}),I(e,t,n)}async function R(e,a){"geometry"===e.type&&L(e);const n=e.parameters.demResolution;if("number"==typeof n)U(e,n);else if("finest-contiguous"===n)await x(e,a);else{if("auto"!==n)throw new t("elevation-query:invalid-dem-resolution",`Invalid dem resolution value '${n}', expected a number, "finest-contiguous" or "auto"`);await A(e,a)}}async function x(e,t){const{tileInfo:a,tilemapCache:n}=e.layer,o=q(a,n,e.parameters.minDemResolution);await V(e,o,t)}async function V(e,a,i){const l=e.layer;if(e.selectTilesAtLOD(a),a<0)return;const r=l.tilemapCache,s=e.getTilesToFetch();try{if(r&&!m(r))await n(Promise.all(s.map(e=>r.fetchAvailability(e.level,e.row,e.col,{signal:i}))),i);else if(await k(e,i),!e.allElevationTilesFetched())throw e.clearElevationTiles(),new t("elevation-query:has-unavailable-tiles","Some elevation tiles are unavailable")}catch(c){o(c),await V(e,a-1,i)}}async function A(t,a){F(t),M(t);const i=t.layer.tilemapCache;if(!i||m(i))return b(t,a);const l=t.getTilesToFetch(),r={},s=l.map(async t=>{const n=new h(0,0,0),l=await e(i.fetchAvailabilityUpsample(t.level,t.row,t.col,n,{signal:a}));!1!==l.ok?null!=t.id&&(r[t.id]=n):o(l.error)});await n(Promise.all(s),a),t.remapTiles(r)}async function b(e,t){const a=e.layer.tileInfo;await k(e,t);let n=!1;e.forEachTileToFetch((e,t)=>{a.upsampleTile(e)?n=!0:t()}),n&&await b(e,t)}function q(e,t,a=0){const n=f(e,t);let o=n.length-1;if(a>0){const t=a/i(e.spatialReference),l=n.findIndex(e=>e.resolution<t);0===l?o=0:l>0&&(o=l-1)}return o}const j={maximumAutoTileRequests:20,noDataValue:0,returnSampleInfo:!1,demResolution:"auto",minDemResolution:0,signal:null};async function C(e,a,n){let o;const i=e.layer.tileInfo.spatialReference;if(a instanceof d?o=await a.project(i,n):(await l([{source:a.spatialReference,dest:i}],{signal:n}),o=r(a,i)),!o)throw new t("elevation-query:spatial-reference-mismatch",`Cannot query elevation in '${a.spatialReference.wkid}' on an elevation service in '${i.wkid}'`);e.geometry=d.fromGeometry(o)}function L(e){if(null==e.layer.fullExtent)return;const t=new p(new h(-1,-1,-1));t.sample=()=>e.parameters.noDataValue,e.outsideExtentTile=t;const a=e.layer.fullExtent;e.geometry.coordinates.forEach(e=>{const n=e.x,o=e.y;(n<a.xmin||n>a.xmax||o<a.ymin||o>a.ymax)&&(e.elevationTile=t)})}function S(e,t){const{tileInfo:a,tilemapCache:n}=e.layer,o=t/i(a.spatialReference),l=f(a,n);let r=l[0],s=0;for(let i=1;i<l.length;i++){const e=l[i];Math.abs(e.resolution-o)<Math.abs(r.resolution-o)&&(r=e,s=i)}return s}function U(e,t){const a=S(e,t);e.selectTilesAtLOD(a)}function F(e){const{tileInfo:t,tilemapCache:a}=e.layer,n=q(t,a,e.parameters.minDemResolution);e.selectTilesAtLOD(n,e.parameters.maximumAutoTileRequests)}async function k(e,t){const a=e.getTilesToFetch(),o={},i=e.parameters.cache,l=e.parameters.noDataValue,r={noDataValue:l,signal:t},s=a.map(async t=>{if(null==t.id)return;const a=`${e.layer.uid}:${t.id}:${l}`,n=i?.get(a),s=n??y.from(await e.layer.fetchTile(t.level,t.row,t.col,r));i?.put(a,s),o[t.id]=new p(t,s)});await n(Promise.allSettled(s),t),e.populateElevationTiles(o)}function M(e){const t=e.layer.tileInfo;let a=0;const n={},o=e=>{null!=e.id&&(e.id in n?n[e.id]++:(n[e.id]=1,a++))},i=e=>{if(null==e.id)return;const t=n[e.id];1===t?(delete n[e.id],a--):n[e.id]=t-1};e.forEachTileToFetch(o,i);let l=!0;for(;l&&(l=!1,e.forEachTileToFetch(n=>{a<=e.parameters.maximumAutoTileRequests||(i(n),t.upsampleTile(n)&&(l=!0),o(n))},i),l););}function $(e){e.geometry.coordinates.forEach(t=>{const a=t.elevationTile;let n=e.parameters.noDataValue;if(a){const e=a.sample(t.x,t.y);null==e?t.elevationTile=null:n=e}t.z=n})}async function z(e,t){const n=await e.geometry.project(e.outSpatialReference,t);a(n);const o={geometry:n.export(),noDataValue:e.parameters.noDataValue};return e.parameters.returnSampleInfo&&(o.sampleInfo=G(e)),e.geometry.coordinates.forEach(e=>{e.tile=null,e.elevationTile=null}),o}function G(e){const t=e.layer.tileInfo,a=i(t.spatialReference);return e.geometry.coordinates.map(n=>{let o=-1;if(n.elevationTile&&n.elevationTile!==e.outsideExtentTile){o=t.lodAt(n.elevationTile.key.level).resolution*a}return{demResolution:o,source:-1===o?void 0:e.layer}})}const N="elevation-query:invalid-layer";export{N as InvalidLayerError,T as createSampler,j as defaultOptions,q as getFinestLodIndex,g as query,v as queryAll};