UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

3 lines (2 loc) 8.63 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{throwIfAborted as e}from"../../../core/promiseUtils.js";import{open as a}from"../../../core/workers.js";import t from"../../../geometry/Point.js";import{projectAsync as r}from"../../../geometry/projectionUtils.js";import{imageToWorld as n,imageToWorldPanoramic as i}from"../../../layers/orientedImagery/transformations/imageToWorld.js";import{convertSphereVertexToPixelLocation as c}from"../../../layers/orientedImagery/transformations/utils.js";import{getMeasurementProperties as o,pixelAreaMeasurement2D as s,pixelDistanceMeasurement2D as u,getRootOfSumOfSquaredErrors as l,heightMeasurementPanoramic as m,heightMeasurement2D as g,getMeasurementPropertiesPanoramic as p,calculateLocationAccuracyFromDeviations as y,pixelAreaMeasurementPanoramic as h,pixelDistanceMeasurementPanoramic as f,computeTriangulatedAreaMeasurement as w,computeTriangulatedDistanceMeasurement as d,getModeCorrectedPoints as v,computeTriangulatedVector as M}from"../imageMeasurementUtils.js";import{extractHorizonAnglesFromMedia as P}from"../utils.js";class x{constructor(e){this.referenceTransformationService=null,this.measurementVectors=[],this._connection=null,this.transformationService=e.transformationService,this.referenceTransformationService=e.referenceTransformationService}async _load(){this._connection??=await a("ImageMeasurementWorker")}async calculateAccuracy(a){await this._load();const{measurementArray:r,measurementType:n,currentBestFeature:i,currentBestFeatureMeasurementImage:c,activeViewer:m,imageSize:g,layer:p,triangularMeasurementActive:y,footprintExtent:h,signal:f}=a,w=p?.orientationAccuracy,d=w?.every(e=>0===e)||!w?.length;if("area"===n&&r.length<3||"distance"===n&&r.length<2||!i||!m?.imageSize||d)return null;let v=null;if(y&&c&&g?v=await o(c,g,h):(v=await o(i,m?.imageSize,h),e(f)),!v)return null;const M="area"===n?await s(r,v,!0):await u([r.at(0),r.at(-1)],v,!0);e(f);const{updateElevationProps:P}=v,x=this.getWorkerMethodProps(v,w),A=await(this._connection?.invoke("generateCombinationsWorker",x,{signal:f}));if(e(f),!A?.length)return null;const V=A.map(async a=>{const i={...a,cameraLocation:new t(a.cameraLocation),updateElevationProps:P},c="area"===n?await s(r,i,!0):await u([r.at(0),r.at(-1)],i,!0);if(e(f),c&&M){if("area"===n){const e="number"!=typeof c?c.area:null;return e?Math.abs(e-M.area):null}return Math.abs(c-M)}return null}),S=await Promise.all(V);e(f);const z=S.filter(e=>null!==e);return 0===z.length?null:l(z)}async calculateHeightAccuracy(e){await this._load();const{mode:a,pixelObj:t,accuracyParameters:r,height:n,properties:i,currentBestFeature:c,signal:o}=e;return"panoramic"===a?this.calculateHeightAccuracyPanoramic(r,t,i,n,c,o):this.calculateHeightAccuracy2D(r,t,i,n,o)}async calculateHeightAccuracyPanoramic(a,r,n,i,c,o){if(r.length<2||!i||!n||!a||!c)throw new Error("Missing parameters");const s=this.getWorkerMethodProps(n,a),u=await(this._connection?.invoke("generateCombinationsPanoramicWorker",s,{signal:o}));if(e(o),!u?.length)return null;const l=r.map(e=>[e.x,e.y]),g=l.at(0),p=l.at(-1),y=u.map(e=>(e.cameraLocation=new t(e.cameraLocation),m([g,p],e,a,c,!0,!1,o))),h=await Promise.all(y);e(o);let f=0;for(const e of h){if(!e)return 0;const a=Math.abs(e-i);f=Math.max(a,f)}return f}async calculateHeightAccuracy2D(a,r,n,i,c){if(r.length<2||!i||!n||!a)throw new Error("Missing parameters");const o=this.getWorkerMethodProps(n,a),s=await(this._connection?.invoke("generateCombinationsWorker",o,{signal:c}));if(e(c),!s?.length)return null;const u=r.map(e=>[e.x,e.y]),l=u.at(0),m=u.at(-1);if(!l||!m)return null;const p=s.map(e=>(e.cameraLocation=new t(e.cameraLocation),g([l,m],e,a,!0,!1,c))),y=await Promise.all(p);e(c);let h=0;for(const e of y){if(!e)return 0;const a=Math.abs(e-i);h=Math.max(a,h)}return h}async calculateLocationAccuracy(a){await this._load();const{pixel:c,currentResult:s,currentBestFeature:u,mode:l,activeViewer:m,footprintExtent:g,accuracyParameters:h,viewSpatialReference:f,signal:w}=a,d=l??"default",v=f??null,M="default"===d?await o(u,m?.imageSize,g):await p(u,m?.imageSize,g);if(e(w),!M)return null;const{updateElevationProps:P}=M,x="default"===d?"generateCombinationsWorker":"generateCombinationsPanoramicWorker",A=this.getWorkerMethodProps(M,h),V=await(this._connection?.invoke(x,A,{signal:w}));if(e(w),!V?.length)return null;const S=V.map(async a=>{const o={...a,cameraLocation:new t(a.cameraLocation)},{...u}=o;let l="default"===d?await n(c,u,P):await i(c,u,P);return e(w),v&&!l.spatialReference.equals(v)&&(l=await r(l,v),e(w)),l&&s?[Math.abs(l.x-s.x),Math.abs(l.y-s.y),l.z&&s.z?Math.abs(l.z-s.z):0]:null}),z=await Promise.all(S);if(e(w),!z?.length)return null;const k=z.map(e=>[e?.[0]??0,e?.[1]??0,e?.[2]??0]),[T,b,F]=y(k);return{x:T,y:b,z:F}}async calculateAccuracyPanoramic(a){await this._load();const{measurementArray:r,measurementType:n,secondaryViewer:i,currentBestFeature:c,currentBestFeatureMeasurementImage:o,activeViewer:s,activeTriangulatedViewer:u,layer:m,footprintExtent:g,signal:y}=a,w=i??!1,d=m?.orientationAccuracy,v=d?.every(e=>0===e)||!d?.length;if("area"===n&&r.length<3||"distance"===n&&r.length<2||!c||!s?.imageSize||v)return null;const M=u?.imageSize,P=w&&o&&M?await p(o,M,g):await p(c,s?.imageSize,g);if(e(y),!P)return null;const x="area"===n?await h(r,P,!0):await f([r.at(0),r.at(-1)],P,!0);e(y);const{updateElevationProps:A}=P,V=this.getWorkerMethodProps(P,d),S=await(this._connection?.invoke("generateCombinationsPanoramicWorker",V,{signal:y}));if(e(y),!S?.length)return null;const z=S.map(async a=>{const i={...a,cameraLocation:new t(a.cameraLocation),updateElevationProps:A},c="area"===n?await h(r,i,!0):await f([r.at(0),r.at(-1)],i,!0);if(e(y),c&&x){if("area"===n){const e="number"!=typeof c?c.area:null;return e?Math.abs(e-x.area):null}return Math.abs(c-x)}return null}),k=await Promise.all(z);e(y);const T=k.filter(e=>null!==e);return 0===T.length?null:l(T)}async calculateTriangulatedMeasurements(e){const{pixels:a,measureType:t,currentBestFeature:r,currentBestFeatureMeasurementImage:n,activeViewer:i,activeTriangulatedViewer:o,mode:s,imageSize:u,layer:l,footprintExtent:m}=e;if(!o?.imageSize)return;const[g,p]=o.imageSize;switch(t){case"distance":{const e=await d(this.measurementVectors),t=a.map(([e,a,t])=>c({x:e,y:a,z:t},g,p)),y={measurementArray:a,measurementType:"distance",currentBestFeature:r,currentBestFeatureMeasurementImage:n,activeViewer:i,imageSize:u,layer:l,triangularMeasurementActive:!0,footprintExtent:m},h={measurementArray:t.map(({x:e,y:a})=>[e,a]),measurementType:"distance",secondaryViewer:!0,currentBestFeature:r,currentBestFeatureMeasurementImage:n,activeViewer:i,activeTriangulatedViewer:o,layer:l,footprintExtent:m},f="default"===s?await this.calculateAccuracy(y):await this.calculateAccuracyPanoramic(h);if(f&&e?.distance){return{distance:e,accuracy:{distanceAccuracy:f,angleAccuracy:Math.atan(f/e.distance)}}}break}case"area":if(n?.geometry.spatialReference){const e=await w(this.measurementVectors,n.geometry.spatialReference);let t=null;if("default"===s){const e={measurementArray:a,measurementType:"area",currentBestFeature:r,currentBestFeatureMeasurementImage:n,activeViewer:i,imageSize:u,layer:l,triangularMeasurementActive:!0,footprintExtent:m},c=await this.calculateAccuracy(e);c&&(t=c)}else if("panoramic"===s){const e={measurementArray:a.map(([e,a,t])=>c({x:e,y:a,z:t},g,p)).map(({x:e,y:a})=>[e,a]),measurementType:"area",secondaryViewer:!0,currentBestFeature:r,currentBestFeatureMeasurementImage:n,activeViewer:i,activeTriangulatedViewer:o,layer:l,footprintExtent:m},s=await this.calculateAccuracyPanoramic(e);s&&(t=s)}return{area:e,accuracy:t}}}if("panoramic"===s){o.viewModel.restoreNavigationHandles()}}async computeMeasurementVector(e){const{pixels:a,activeFeature:t,activeViewer:n,mode:i,spatialReference:c}=e,o=n?.imageSize,s=P(n?.media);if(!a||!t||!o)return;const u=v(a,i,o,s).map(async e=>{const a={x:e[0],y:e[1]};let t=null;return t=0===this.measurementVectors.length?await this.transformationService.pixelToMapPoint(a):await(this.referenceTransformationService?.pixelToMapPoint(a)),t?(c&&!t.spatialReference.equals(c)&&(t=await r(t,c)),t):null}),l=(await Promise.all(u)).filter(e=>null!==e);return M(l,t)}resetMeasurementVectors(){this.measurementVectors=[]}async updateMeasurementVectorsArray(e){const{activeFeature:a}=e;if(a){const a=await this.computeMeasurementVector(e);a&&this.measurementVectors.push(a)}}getWorkerMethodProps(e,a){const{updateElevationProps:t,...r}=e;return{imageToWorldProps:{...r,cameraLocation:r.cameraLocation.toJSON()},accuracyParameters:a}}}export{x as ImageMeasurementService};