@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.76 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import e from"../../../../request.js";import has from"../../../../core/has.js";import s from"../../../../core/Logger.js";import{throwIfAborted as t,after as r,throwIfAbortError as o}from"../../../../core/promiseUtils.js";import{Milliseconds as n}from"../../../../core/time.js";import{join as a,parseData as i}from"../../../../core/urlUtils.js";import{generateBracedUUID as c}from"../../../../core/uuid.js";import u from"../../../../geometry/SpatialReference.js";import{externalIsOnService as l,externalSourceToMultiPart as p,assetFormatId as m,ServiceAsset as f,ServiceAssetPart as d}from"../../../../geometry/support/meshUtils/External.js";import{UnsupportedError as g,NoSupportedSourceError as y,NoGlbSupportError as w,Convert3DFailedError as h,UnsupportedFormatUploadedError as P,BadResponseError as b,UploadFailedError as j,NotBase64Error as T,UnableToPrepareOptionsError as v}from"./uploadAssetErrors.js";import{uploadProgressWeights as A}from"./uploadProgressWeights.js";import{uploadItem as S}from"./uploads.js";import{getPrjFormatId as F,getWorldFileFormatId as R,getGlbFormatId as U,getMimeTypeFormatId as x,getFormatIdMimeType as D}from"../../../support/infoFor3D.js";import{getMeshTransformForMetersToSpatialReference as N}from"../../../support/meshSpatialReferenceScaleUtils.js";import{extractMeshFeatureTransform as E,extractMeshFeatureOrigin as C}from"../../../../rest/support/meshFeatureAttributes.js";import{makeProgressManager as O,estimatedConversionTime as k,simulateProgress as I}from"../../../../support/progressUtils.js";async function B(e,s,t){const r=e.length;if(!r)return t?.onProgress?.(1),[];const o=O(r,t?.onProgress,"uploadAssets");return Promise.all(e.map(((e,r)=>q(e,s,{...t,onProgress:o.makeOnProgress(r)}))))}async function q(e,{layer:s,ongoingUploads:t},r){const o=t.get(e);if(o)return o;if(!ne(s))throw new g;if(L(e,s))return r?.onProgress?.(1),e;const n=H(e,s,r);t.set(e,n);try{await n}finally{t.delete(e)}return e}function L(e,s){const{parsedUrl:t}=s;return null!=t&&e.metadata.externalSources.some((e=>l(e,t)))}async function H(e,s,r){const{metadata:o}=e,{displaySource:n}=o,a=W(n?.source,s,{checkForConversionRequired:has("enable-feature:georeferenced-uploads")}),i=null!=a?$(a,s,r):o.externalSources.length>0?J(e,s,r):z(e,s,r),c=await i;return t(r),e.addExternalSources([c]),e}async function $(e,s,t){return{source:{type:"service",assets:await Q(e,s,t)},original:!0,unitConversionDisabled:!0}}async function J(e,s,t){const r=ae(s),{externalSources:o}=e.metadata,n=M(o,s);if(!n)throw new y;const a=O(A.uploadConvertibleSource,t?.onProgress,"uploadConvertibleSource"),i={type:"service",assets:await Q(n,s,{onProgress:a.makeOnProgress("uploadEditSource")})};e.addExternalSources([{source:i,original:!0}]);const c=n.reduce(((e,{asset:s})=>s instanceof File?e+s.size:e),0),u=a.simulate("serviceAssetsToGlb",k(c));try{const{source:o,transform:n,origin:a}=await se(i,s,r);return e.transform=n,a&&(e.metadata.georeferenced=!0,t?.useAssetOrigin&&(e.vertexSpace.origin=[a.x,a.y,a.z??0],e.spatialReference=a.spatialReference)),{source:o,unitConversionDisabled:!0}}finally{u.remove()}}async function z(e,s,t){const r=O(A.uploadLocalMesh,t?.onProgress,"uploadLocalMesh"),o=G(e,s,{...t,onProgress:r.makeOnProgress("meshToAssetBlob")});return{source:{type:"service",assets:await V([o],s,{...t,onProgress:r.makeOnProgress("uploadAssetBlobs")})},extent:e.extent.clone(),original:!0}}async function G(e,s,r){const o=ae(s),n=await e.load(r),a=await n.toBinaryGLTF({origin:n.origin,signal:r?.signal,ignoreLocalTransform:!0,unitConversionDisabled:!0});return t(r),{blob:new Blob([a],{type:"model/gltf-binary"}),assetName:`${c()}.glb`,assetType:o}}function M(e,s){for(const t of e){const e=W(t.source,s);if(e)return e}return null}function W(e,{infoFor3D:s},t={}){if(!e)return null;const r=p(e);if(!r)return null;const{supportedFormats:o,editFormats:n}=s,a=new Array,i=F(s),c=R(s);let u=!1;for(const l of r){const e=K(l,o);if(!e)return null;const{assetType:s}=e;if(t.checkForConversionRequired&&(s===i||s===c))return null;n.includes(s)&&(u=!0),a.push(e)}return u?a:null}function K(e,s){const t=m(e,s);return t?{asset:e,assetType:t}:null}async function Q(e,s,t){return V(e.map((e=>X(e,t))),s,t)}async function V(e,s,r){const o=O(A.uploadAssetBlobs,r?.onProgress,"uploadAssetBlobs"),n=await Z(e,s,{...r,onProgress:o.makeOnProgress("prepareAssetItems")});t(r);const a=n.map((({item:e})=>e)),{uploadResults:i}=await _(a,s,{...r,onProgress:o.makeOnProgress("uploadAssetItems")});return t(r),e.map(((e,t)=>ee(n[t],i[t],s)))}async function X(e,s){const{asset:r,assetType:o}=e;if(r instanceof File)return{blob:r,assetName:r.name,assetType:o};const n=await r.toBlob(s);return t(s),{blob:n,assetName:r.assetName,assetType:o}}async function Y(e,s,r){const{blob:n,assetType:a,assetName:c}=e;let u=null;try{const e=await S({data:n,name:c},s.url,r);t(r),u={assetType:a,assetUploadId:e.itemID}}catch(l){o(l),ie().warnOnce(`Service ${s.url} does not support the REST Uploads API.`)}if(!u){const e=await i(n);if(t(r),!e.isBase64)throw new T;u={assetType:a,assetData:e.data}}if(!u)throw new v;return{item:u,assetName:c}}function Z(e,s,r){const o=O(e.length,r?.onProgress,"prepareAssetItems");return Promise.all(e.map((async(e,n)=>{const a=Y(await e,s,{...r,onProgress:o.makeOnProgress(n)});return t(r),a})))}async function _(s,r,o){const n=I(o?.onProgress);try{const n=await e(a(r.parsedUrl.path,"uploadAssets"),{timeout:0,query:{f:"json",assets:JSON.stringify(s)},method:"post",responseType:"json"});if(t(o),n.data.uploadResults.length!==s.length)throw new b(s.length,n.data.uploadResults.length);return n.data}finally{n.remove()}}function ee(e,s,t){const{success:r}=s;if(!r){const{error:t}=s;throw new j(e.assetName,t)}const{assetHash:o}=s,{assetName:n,item:{assetType:a}}=e,{infoFor3D:{supportedFormats:i}}=t,c=D(a,i);if(!c)throw new P(a);return new f(n,c,[new d(`${t.parsedUrl.path}/assets/${o}`,o)])}async function se({assets:e},s,t){const r=e.map((({assetName:e,parts:s})=>({assetName:e,assetHash:s[0].partHash})));let o;try{const e=a(s.parsedUrl.path,"convert3D"),n=s.capabilities?.operations.supportsAsyncConvert3D;o=(await(n?oe:re)(e,{query:{f:"json",assets:JSON.stringify(r),transportType:"esriTransportTypeUrl",targetFormat:t,async:n},responseType:"json",timeout:0})).data}catch(n){throw new h}return te(s,o)}function te(e,s){const t={source:{type:"service",assets:s.assets.map((s=>{const t=x(s.contentType,e.infoFor3D.supportedFormats);if(!t)throw new P(t);return new f(s.assetName,s.contentType,[new d(s.assetURL,s.assetHash)])}))},origin:void 0,transform:void 0};if(has("enable-feature:georeferenced-uploads")&&s.transform){if(t.transform=E(s.transform),s.spatialReference){const e=u.fromJSON(s.spatialReference);t.origin=C(s.transform,e)}}else t.transform=N(e.spatialReference);return t}function re(s,t){return e(s,t)}async function oe(s,t){const o=(await e(s,t)).data.statusUrl;for(;;){const s=(await e(o,{query:{f:"json"},responseType:"json"})).data;switch(s.status){case"Completed":return e(s.resultUrl,{query:{f:"json"},responseType:"json"});case"CompletedWithErrors":throw new Error(s.status);case"Failed ImportChanges":case"InProgress":case"Pending":case"ExportAttachments":case"ExportChanges":case"ExportingData":case"ExportingSnapshot":case"ImportAttachments":case"ProvisioningReplica":case"UnRegisteringReplica":break;default:throw new Error}await r(ce)}}function ne(e){return!!e.infoFor3D&&!!e.url}function ae({infoFor3D:e}){const s=U(e);if(!s)throw new w;return s}function ie(){return s.getLogger("esri.layers.graphics.sources.support.uploadAssets")}const ce=n(1e3);export{B as uploadAssets};