@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 10.7 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{__decorate as e}from"tslib";import{onLocaleChange as t,fetchMessageBundle as i}from"../../../../../intl.js";import s from"../../../../../core/Accessor.js";import{multiplyOpacityToUnitRGBA as r,getContrast as a,multiplyOpacity as n}from"../../../../../core/colorUtils.js";import"../../../../../core/has.js";import{nextHighestPowerOfTen as o,floatEqualUlp as l}from"../../../../../core/mathUtils.js";import{destroyMaybe as m}from"../../../../../core/maybe.js";import{toAdaptiveAreaUnit as h,adaptiveLengthUnitForArea as c}from"../../../../../core/quantity.js";import{formatDecimal as p}from"../../../../../core/quantityFormatUtils.js";import{watch as d,syncAndInitial as u,initial as _}from"../../../../../core/reactiveUtils.js";import{lengthUnitFromSpatialReference as v,convertUnit as g,adaptiveAreaUnit as b}from"../../../../../core/units.js";import{property as w,subclass as f}from"../../../../../core/accessorSupport/decorators.js";import{fromTranslation as D}from"../../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as L}from"../../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{subtract as y,squaredDistance as S}from"../../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as C}from"../../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{LabelVisualElement as x}from"../../../interactive/visualElements/LabelVisualElement.js";import{LineVisualElement as j}from"../../../interactive/visualElements/LineVisualElement.js";import{MeasurementAreaVisualElement as V}from"../../../interactive/visualElements/MeasurementAreaVisualElement.js";import{GeodesicSegment as A,EuclideanSegment as M}from"../../../interactive/visualElements/support/Segment.js";import{midpoint3d as R}from"../../../support/mathUtils.js";import{createStipplePatternSimple as k}from"../../../webgl-engine/materials/lineStippleUtils.js";let z=class extends s{get _parameters(){const{accentColor:e,textColor:t}=this.view.effectiveTheme,i=e.toUnitRGBA(),s=r(e,.5),o=r(a(e),.5),l=a(t,160);return{accentColor:i,transparentAccentColor:s,transparentContrastColor:o,textColor:t,textBackgroundColor:n(l,.6),textCalloutColor:n(l,.5),pathLineWidth:3,perimeterLineWidth:2,projectionLineWidth:2,projectionLineStippleSize:5,labelDistance:25}}get viewData(){return this._viewData}get visible(){return this.analysisViewData.visible}get _renderUnits(){const e=this.view.renderCoordsHelper.spatialReference;return v(e)??"meters"}get testData(){}constructor(e){super(e),this._path=null,this._perimeter=null,this._projectionLines=null,this._measurementArea=null,this._areaLabel=null,this._perimeterLabel=null,this._pathSegments=[],this._perimeterSegments=[],this._origin=C(),this._originTransform=L(),this.messages=null,this._viewData=new P,this.areaLabel=null,this.perimeterLabel=null,this.loadingMessages=!0}initialize(){const{analysisViewData:e,_parameters:i,view:s}=this;this._path=new j({view:s,attached:!0,width:i.pathLineWidth,polygonOffset:!0,renderOccluded:4,tansparentRenderOrder:1,isDecoration:!0}),this._perimeter=new j({view:s,attached:!0,width:i.perimeterLineWidth,polygonOffset:!0,renderOccluded:4,tansparentRenderOrder:2,isDecoration:!0}),this._projectionLines=new j({view:s,attached:!0,width:i.projectionLineWidth,stipplePattern:k(i.projectionLineStippleSize),polygonOffset:!0,renderOccluded:4,tansparentRenderOrder:3,isDecoration:!0}),this._measurementArea=new V({view:s,attached:!0,isDecoration:!0,renderOccluded:4,testsTransparentRenderOrder:5});const r={attached:!0,view:s,isDecoration:!0};this._areaLabel=new x({...r,fontSize:16,distance:0}),this._perimeterLabel=new x({...r,fontSize:12}),this.addHandles([d(()=>[e.mode,this.visible,e.unit,e.measurementData?.updateId,null!=e.measurementData?.measurements,E(e.measurementData?.measurements?.mode)],()=>this._update(),u),d(()=>e.measurementData?.measurements,e=>this._updateMeasurements(e)),d(()=>s.state?.camera,()=>this._updateLabels(),u),t(()=>this._updateMessageBundle()),d(()=>this._parameters,({accentColor:e,transparentAccentColor:t,transparentContrastColor:i,textColor:s,textBackgroundColor:r,textCalloutColor:a})=>{const{_path:n,_perimeter:o,_projectionLines:l,_measurementArea:m,_areaLabel:h,_perimeterLabel:c}=this;n.color=e,o.color=e,l.color=e,m.color1=t,m.color2=i,h.textColor=s,h.backgroundColor=r,h.calloutColor=a,c.textColor=s,c.backgroundColor=r,c.calloutColor=a},_)]),this._updateMessageBundle()}destroy(){this._measurementArea=m(this._measurementArea),this._path=m(this._path),this._perimeter=m(this._perimeter),this._areaLabel=m(this._areaLabel),this._perimeterLabel=m(this._perimeterLabel),this._projectionLines=m(this._projectionLines),this.set("view",null)}_update(){if(this.destroyed||!this.view.ready||!this.view.renderCoordsHelper)return;const{analysisViewData:{measurementData:e},analysisViewData:t}=this;null!=e&&(this._updateViewData(e,t.path),this._updateOrigin(),this._updatePathSegments(),this._updatePerimeterSegments(),this._updateArea(),this._updateProjectionLines(),this._updateLabels())}_calculateCheckerSize(e){const t=I(e?.mode)?e?.geodesicArea:e?.area;if(null==t)return 1;const i=h(t,this.analysisViewData.unit),s=Math.sqrt(g(1,i.unit,"square-meters"));return g(o(Math.sqrt(i.value)/Math.sqrt(300))*s,"meters",this._renderUnits)}_updateMeasurements(e){Object.assign(this.viewData,this._getMeasurementsViewData(e)),this._updateCheckerSize(),this._updateLabels()}_updateCheckerSize(){this._measurementArea.size=[this.viewData.checkerSize,this.viewData.checkerSize]}_updateViewData(e,t){const i=e.measurements,s=new P({validMeasurement:!!i,numVertices:e.numVertices,hasStagedVertex:e.hasStagedVertex,path:t,mode:i?.mode,vertexData:e.vertexData,perimeterLabelSegmentIndex:0,...this._getMeasurementsViewData(i)});this._viewData=s}_getMeasurementsViewData(e){const t=I(e?.mode),i=this._calculateCheckerSize(e);return{areaCentroid:t?e?.geodesicAreaCentroidRenderCoords:e?.areaCentroidRenderCoords,area:t?e?.geodesicArea:e?.area,perimeter:t?e?.geodesicPerimeter:e?.perimeter,checkerSize:i}}_updateOrigin(){const e=this.viewData;R(e.vertexData.positionsRender,this._origin),D(this._originTransform,this._origin),this._measurementArea.transform=this._originTransform,this._projectionLines.transform=this._originTransform}_createSegments(e,t){const i=this.viewData,s=this.view.renderCoordsHelper.spatialReference,r=E(i.mode),a=[],n=i.numVertices,o=i.validMeasurement?n:n-1;for(let m=0;m<o;++m){const o=i.vertexData[e][m],h=i.vertexData[e][(m+1)%n];let c=!0;if(t){const e=i.vertexData.positionsRender[m],t=i.vertexData.positionsRender[(m+1)%n];let s=!0;for(let i=0;i<3;++i)s&&=l(e[i],o[i])&&l(t[i],h[i]);s&&(c=!1)}let p=null;switch(r){case"geodesic":p=new A(o,h,s,c);break;case"euclidean":p=new M(o,h,c)}a.push(p)}return a}_updatePathSegments(){const{visible:e}=this,t=this._createSegments("positionsRender");this._path.setGeometryFromSegments(t,this._origin),this._path.visible=e,this._pathSegments=t}_updatePerimeterSegments(){const e=this.visible&&"euclidean"===this.viewData.mode&&!!this.viewData.path&&this.viewData.path.numVertices>2,t=!0,i=this._createSegments("positionsFittedRender",t);this._perimeter.setGeometryFromSegments(i,this._origin),this._perimeter.visible=e,this._perimeterSegments=i}_updateArea(){const e=this.viewData;switch(E(e.mode)){case"euclidean":this._updateAreaEuclidean(e);break;case"geodesic":this._updateAreaGeodesic()}}_updateAreaEuclidean(e){const t=this.visible;e.validMeasurement&&e.vertexData.triangleIndices?(this._measurementArea.geometry={uv:e.vertexData.triangleUvs,position:e.vertexData.trianglePositions,triangleIndices:e.vertexData.triangleIndices},this._updateCheckerSize(),this._measurementArea.visible=t):this._measurementArea.visible=!1}_updateAreaGeodesic(){this._measurementArea.visible=!1}_updateProjectionLines(){const e=this.viewData,t=this.visible,i=e.mode,s=e.numVertices;if(s>0&&e.validMeasurement&&"euclidean"===i){const i=[];for(let t=0;t<s;++t){const s=C();y(s,e.vertexData.positionsRender[t],this._origin);const r=C();y(r,e.vertexData.positionsFittedRender[t],this._origin),l(S(s,r),0)||i.push([s,r])}this._projectionLines.geometry=i,this._projectionLines.visible=t}else this._projectionLines.geometry=null,this._projectionLines.visible=!1}_updateLabels(){if(this.destroyed)return;const{viewData:e}=this,{area:t,path:i}=e;if(!i)return;const s=this.visible,r=this._areaLabel,a=this._perimeterLabel,n=e.validMeasurement;r.visible=!0,a.visible=!0;let o=!1;const l=O(this.messages,t,this.analysisViewData.unit);if(null!=l&&e.areaCentroid&&s&&(r.geometry={type:"point",point:e.areaCentroid},r.text=l,o=e.validMeasurement),this._set("areaLabel",l),s&&n){const t=I(e.mode),i=e.perimeter,s=U(this.messages,i,this.analysisViewData.unit);this._set("perimeterLabel",s),a.distance=this._parameters.labelDistance,a.anchor="top",a.text=s;let r=!0;for(let n=0;n<e.numVertices;++n){const i=(e.perimeterLabelSegmentIndex+n)%e.numVertices,s=t?this._pathSegments[i]:this._perimeterSegments[i];if(r=!0,a.geometry={type:"segment",segment:s,sampleLocation:"center"},!a.overlaps(this._areaLabel))break;r=!1}a.visible=r}else a.visible=!1;r.visible=o}_updateMessageBundle(){this.loadingMessages=!0,i("esri/core/t9n/Units").then(e=>{this.messages=e,this.view&&this._update()}).finally(()=>{this.loadingMessages=!1})}};function O(e,t,i){return e&&t&&p(e,t,b(t.value,t.unit,i))}function U(e,t,i){return e&&t&&p(e,t,c(t,i))}e([w()],z.prototype,"_parameters",null),e([w()],z.prototype,"view",void 0),e([w()],z.prototype,"messages",void 0),e([w()],z.prototype,"analysis",void 0),e([w()],z.prototype,"_viewData",void 0),e([w()],z.prototype,"analysisViewData",void 0),e([w({readOnly:!0})],z.prototype,"areaLabel",void 0),e([w({readOnly:!0})],z.prototype,"perimeterLabel",void 0),e([w()],z.prototype,"loadingMessages",void 0),e([w()],z.prototype,"visible",null),e([w()],z.prototype,"_renderUnits",null),z=e([f("esri.views.3d.analysis.AreaMeasurement.support.AreaMeasurementVisualization")],z);class P{constructor(e){this.validMeasurement=e?.validMeasurement??!1,this.numVertices=e?.numVertices??0,this.hasStagedVertex=e?.hasStagedVertex??!1,this.path=e?.path,this.vertexData=e?.vertexData??{positionsRender:[],positionsFittedWorldPlaneProjected:[],positionsFittedRender:[],triangleIndices:null,trianglePositions:[],triangleUvs:[]},this.mode=e?.mode,this.areaCentroid=e?.areaCentroid,this.perimeterLabelSegmentIndex=e?.perimeterLabelSegmentIndex??0,this.checkerSize=e?.checkerSize??1,this.area=e?.area,this.perimeter=e?.perimeter}}function E(e){switch(e){case"euclidean":case void 0:case null:return"euclidean";case"geodesic":return"geodesic"}}function I(e){return"geodesic"===E(e)}export{z as AreaMeasurementVisualization,P as ViewData};