UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) 9.98 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as t}from"tslib";import e from"../../../../../core/Accessor.js";import{resizeFilled as r}from"../../../../../core/arrayUtils.js";import{deg2rad as o}from"../../../../../core/mathUtils.js";import{abortMaybe as s}from"../../../../../core/maybe.js";import{debounce as i,throwIfAborted as n}from"../../../../../core/promiseUtils.js";import{valueInUnit as a}from"../../../../../core/quantity.js";import{lengthUnitFromSpatialReference as l,areaUnitFromSpatialReference as d}from"../../../../../core/units.js";import{property as h}from"../../../../../core/accessorSupport/decorators/property.js";import{subclass as p}from"../../../../../core/accessorSupport/decorators/subclass.js";import{e as m}from"../../../../../chunks/earcut.js";import{set as c}from"../../../../../core/libs/gl-matrix-2/math/vec2.js";import{create as u}from"../../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{copy as _,set as g,cross as f,subtract as P,dot as j,scale as x,add as v}from"../../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as w}from"../../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as C}from"../../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import y from"../../../../../geometry/Polygon.js";import R from"../../../../../geometry/SpatialReference.js";import{isPCPF as U}from"../../../../../geometry/spatialReferenceEllipsoidUtils.js";import{i as W,e as M}from"../../../../../chunks/simplifyOperator.js";import{projectDirection as D}from"../../../../../geometry/projection/projectDirection.js";import{projectPointToVector as A}from"../../../../../geometry/projection/projectPointToVector.js";import{projectVectorToVector as V}from"../../../../../geometry/projection/projectVectorToVector.js";import{compactIndices as b}from"../../../../../geometry/support/Indices.js";import{Sphere as F}from"../../../../../geometry/support/sphere.js";import{triangulate as S}from"../../../../../geometry/support/triangulationUtils.js";import{bestFitPlane as I,planePointDistance as T,boundingSphere as O}from"../../support/measurementUtils.js";import{getElevationAtPoint as k}from"../../../support/ElevationProvider.js";import{midpoint3d as z,makeOrthonormal as q}from"../../../support/mathUtils.js";import{useGeodesicAreaMeasurement as E}from"../../../../support/automaticAreaMeasurementUtils.js";import{flatten2DVertexDataToArray as H}from"../../../../support/euclideanAreaMeasurementUtils.js";import{computeEuclideanMeasurementSR as L}from"../../../../support/measurementUtils.js";import{MeasurementWorkerHandle as B}from"../../../../support/MeasurementWorkerHandle.js";class G{constructor(t){this.positionsWorld=[],this.positionsRender=[],this.positionsFittedRender=[],this.positionsFittedRenderComplex=[],this.positionsFittedWorldPlaneProjectedComplex=[],this.triangleIndices=null,this.areaPolygon=new y({rings:[[]],spatialReference:t}),this.positionsFittedWorldPlaneProjected=this.areaPolygon.rings[0],this.trianglePositions=this.positionsFittedRender,this.triangleUvs=this.positionsFittedWorldPlaneProjected}}class Z{constructor(t,e=null,r=null,o=null,s=null,i=null,n=null){this.mode=t,this.area=e,this.geodesicArea=r,this.perimeter=o,this.geodesicPerimeter=s,this.areaCentroidRenderCoords=i,this.geodesicAreaCentroidRenderCoords=n}}let J=class extends e{get numVertices(){return this._length}get hasStagedVertex(){return null!=this._lastCursorPoint}get fittingMode(){return this._fittingMode}get measurements(){return this._measurements}get updateId(){return this._updateId}constructor(t){super(t),this._length=0,this._lastCursorPoint=null,this._fittingMode=null,this._measurements=null,this._updateId=0,this._centroidRenderCoords=w(),this._planeWorldCoords=C(),this._worldUp=w(),this._worldTangent=w(),this._frame=[w(),w(),w()],this._worldOrigin=w(),this._updateAxisU=w(),this._updateAxisV=w(),this._updateWorldOrigin=w(),this._lastPathVersion=-1,this._mode=null,this._tempU=w(),this._tempV=w(),this._tempVec3=w(),this._tempSphere=new F,this._measurementWorker=new B,this._updateAbortController=null,this._updateMeasurements=i(async(t,e,r,o,s,i)=>{const a=t.spatialReference,l=E(a);_(this._updateAxisU,this._frame[0]),_(this._updateAxisV,this._frame[1]),_(this._updateWorldOrigin,this._worldOrigin);const d=(e,r)=>(e&&t.renderCoordsHelper.toRenderCoords(e,r)||g(r,0,0,0),r),h=e.areaMeasurement?.geometry,p=l&&1!==r&&h?await this._measurementWorker.geodeticLength(h,{stagedPoint:o?s:null}):null;n(i);const m=this._calculateMode(r,p),c="geodesic"===m,[u,f]=await Promise.all([c?null:this._measurementWorker.area2D(this.vertexData.areaPolygon,{unit:this._areaMeasurementUnit,lengthUnit:this._lengthMeasurementUnit,returnCentroid:!0,returnLength:!0}),c&&h?await this._measurementWorker.geodeticArea(h,{stagedPoint:o?s:null,returnCentroid:!0}):null]);n(i);const P=c?null:w();P&&u?.centroid&&this._projectWorldPlaneProjectedPointToRender(P,this._updateWorldOrigin,[u.centroid?.x??0,u.centroid?.y??0],this._updateAxisU,this._updateAxisV,this.view.renderSpatialReference,this._measurementSR);const j=f?.centroid?d(f.centroid,w()):null;this._measurements=new Z(m,c?null:u?.area,c?f?.area:null,c?null:u?.length,c?p:null,c?null:P,c?j:null)});const e=L(t.view.spatialReference);this._measurementSR=e,this._lengthMeasurementUnit=l(e)??"meters",this._areaMeasurementUnit=d(e)??"square-meters";const r=U(e)?R.WebMercator:e;this.vertexData=new G(r),this._measurementWorker.preloadGeodetic()}destroy(){this._measurementWorker.destroy()}update(t,e,r,o,s,i,n){const a=this._lastPathVersion===t.version,l=e?e.equals(this._lastCursorPoint):null==this._lastCursorPoint,d=this._mode===s;return!(a&&!i&&d&&l)&&(this._lastPathVersion=t.version,this._lastCursorPoint=e,this._update(t,e,r,o,s,n),!0)}_update(t,e,r,o,i,n){const a=this.view.renderSpatialReference,l=this._measurementSR;let d=t.numVertices;const h=!(null==e||e.equals(t.lastPoint)||d>2&&e.equals(t.firstPoint)||t.polygonIsClosed);h&&(d+=1);const p=!t.polygonIsClosed&&d>2,m=t.polygonIsClosed||p;this._resize(d);const{positionsWorld:c,positionsRender:u}=this.vertexData,_=(t,e)=>{K(r.elevationProvider,t),A(t,c[e],l),A(t,u[e],a)};if(t.forEachVertexPosition((t,e)=>_(t,e)),h&&_(e,d-1),this.vertexData.areaPolygon.clearCache(),!m)return this._measurements=null,this.vertexData.triangleIndices=null,this._updateId++,void(this._updateAbortController=s(this._updateAbortController));this._updateVertexData(r,a,l,o),this._updateId++,this._updateAbortController??=new AbortController,n.addPromise(this._updateMeasurements(r,t,i,h,e,this._updateAbortController.signal))}_resize(t){const{positionsWorld:e,positionsRender:o,positionsFittedWorldPlaneProjected:s,positionsFittedRender:i}=this.vertexData;r(e,t,w),r(o,t,w),r(s,t,u),r(i,t,w),this._length=t}_updateVertexData(t,e,r,o){const s=t.renderCoordsHelper,{positionsWorld:i,positionsRender:n}=this.vertexData,a=this._planeWorldCoords,l=this._centroidRenderCoords;z(n,l),s.worldUpAtPosition(l,this._worldUp),s.worldBasisAtPosition(l,0,this._worldTangent),D(l,this._worldUp,e,this._worldUp,r),D(l,this._worldTangent,e,this._worldTangent,r),i.length>2&&I(i,a),this._fittingMode=this._selectFittingMode(a,i,this._worldUp,o);let d=0;if("horizontal"===this._fittingMode){let t=-1/0;n.forEach((e,r)=>{const o=s.getAltitude(n[r]);o>t&&(t=o,d=r)})}const{_worldOrigin:h}=this;_(this._worldOrigin,i[d]);let p=a,m=this._worldTangent;"horizontal"===this._fittingMode?p=this._worldUp:"vertical"===this._fittingMode&&(p=this._tempVec3,m=this._worldUp,q(a,this._worldUp,p));const u=this._frame[0],g=this._frame[1];_(this._frame[2],p),q(m,p,u),f(g,u,this._frame[2]);const{positionsFittedRender:x,positionsFittedWorldPlaneProjected:v}=this.vertexData,w=this._tempVec3;for(let _=0;_<this._length;++_){const t=v[_],o=x[_];P(w,i[_],h),c(t,j(u,w),j(g,w)),this._projectWorldPlaneProjectedPointToRender(o,h,t,u,g,e,r)}this._triangulate(new Q(h,u,g,e,r))}_triangulate(t){!W(this.vertexData.areaPolygon)&&this._triangulateComplexPolygon(t)||this._triangulateSimplePolygon()}_triangulateSimplePolygon(){const{positionsFittedWorldPlaneProjected:t}=this.vertexData;this.vertexData.triangleIndices=b(m(H(t),[],2)),this.vertexData.trianglePositions=this.vertexData.positionsFittedRender,this.vertexData.triangleUvs=t,this.vertexData.positionsFittedWorldPlaneProjectedComplex.length=0,this.vertexData.positionsFittedRenderComplex.length=0}_triangulateComplexPolygon({worldOrigin:t,axisU:e,axisV:o,renderSR:s,worldSR:i}){const{positionsFittedWorldPlaneProjectedComplex:n,positionsFittedRenderComplex:a,areaPolygon:l}=this.vertexData,d=M(l);if(!d)return!1;const{position:h,faces:p}=S(d),m=h.length/3;r(n,m,u),r(a,m,w);for(let r=0,u=0;r<h.length;r+=3,u++){const l=n[u];c(l,h[r],h[r+1]);const d=a[u];this._projectWorldPlaneProjectedPointToRender(d,t,l,e,o,s,i)}return this.vertexData.triangleIndices=p,this.vertexData.trianglePositions=a,this.vertexData.triangleUvs=n,!0}_projectWorldPlaneProjectedPointToRender(t,e,r,o,s,i,n){const a=this._tempU,l=this._tempV;x(a,o,r[0]),x(l,s,r[1]),v(t,a,l),v(t,t,e),V(t,n,t,i)}_selectFittingMode(t,e,r,s){const i=e.map(e=>Math.abs(T(t,e))).reduce((t,e)=>Math.max(t,e),0);O(e,this._tempSphere);const n=i/(2*this._tempSphere.radius),a=n<s.maxRelativeErrorCoplanar,l=n<s.maxRelativeErrorAlmostCoplanar;let d="horizontal";if(a)d="oblique";else if(l){d=Math.abs(j(r,t))>Math.cos(o(s.verticalAngleThreshold))?"horizontal":"vertical"}return d}_calculateMode(t,e){return null!=e&&0===t?a(e,"meters")>N?"geodesic":"euclidean":null==e||1===t?"euclidean":"geodesic"}};function K(t,e){e.hasZ||(e.z=k(t,e,"ground")??0)}t([h()],J.prototype,"_measurements",void 0),t([h()],J.prototype,"_updateId",void 0),t([h()],J.prototype,"view",void 0),J=t([p("esri.views.3d.analysis.AreaMeasurement.support.MeasurementData")],J);const N=1e5;class Q{constructor(t,e,r,o,s){this.worldOrigin=t,this.axisU=e,this.axisV=r,this.renderSR=o,this.worldSR=s}}export{Z as AreaMeasurementQuantities,J as MeasurementData};