@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 7.21 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import e from"../../../../core/Logger.js";import{copy as t,set as n,length as r}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{ZEROS as l,fromValues as a}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as c,center as s,height as i}from"../../../../geometry/support/aaBoundingBox.js";import{labelMarginPx as o}from"./constants.js";import{getGraphics3DSymbol as f}from"./graphicSymbolUtils.js";import{LabelPlacement as m}from"./LabelParameters.js";import{textVerticalPaddingPx as h}from"../../webgl-engine/lib/TextRenderer.js";import{HUDMaterial as p}from"../../webgl-engine/materials/HUDMaterial.js";const b=()=>e.getLogger("esri.views.3d.layers.graphics.labelPlacement");class u{constructor(e,t,n,r=null){this._graphic=e,this._symbol=t,this._class=n,this._disablePlacement=r}get placement(){const e=this._verticalOffsetPlacement;if(null==e)return null;const t=this._getPlacementInfo(e);if(null==t)return null;const n=t.anchor,r=!!e.hasLabelVerticalOffset,l=e.verticalOffset,a=new m(l,n,r);return this._calculatePlacementOffsets(a,t)}get _verticalOffsetPlacement(){const e=this._class.labelPlacement,{_symbol:t,_graphic:n}=this,r=f(n.graphics3DSymbol),l="point-3d"===r?.symbol.type?r.symbol:null,a=d[e]||this._defaultPlacementInfo;return l?.supportsCallout()&&l.hasVisibleVerticalOffset()&&!n.isDraped?{placement:null,hasLabelVerticalOffset:!1,verticalOffset:l.verticalOffset.clone(),anchor:null,normalizedOffset:null}:!t?.hasVisibleVerticalOffset()||null!=l&&l.supportsCallout()&&l.verticalOffset&&!n.isDraped?{placement:null,verticalOffset:null,anchor:null,normalizedOffset:null,hasLabelVerticalOffset:!1}:a&&P(a.placement)?{placement:"above-center",verticalOffset:t.verticalOffset.clone(),anchor:"bottom",normalizedOffset:[0,a.normalizedOffset[1],0],hasLabelVerticalOffset:!0}:(b().errorOncePerTick("Callouts and vertical offset on labels are currently only supported with 'above-center' label placement (not with "+e+" placement)"),null)}_getPlacementInfo(e){if(e.anchor)return e;const t=this._class.labelPlacement,n=d[t],r=n||this._defaultPlacementInfo;return t&&!n&&b().warnOnce(`the requested label placement '${t}' is currently unsupported in SceneView.`),this._validatePlacementInfo(r)}_calculatePlacementOffsets(e,t){const n=this._graphic.graphic.geometry;if(null==n)return null;switch(n.type){case"point":this._setPointSpecificPlacement(e,t);break;case"mesh":this._setMeshSpecificPlacement(e,t);break;case"polygon":this._setPolygonSpecificPlacement(e,t)}const r=o-h;return e.screenOffset[0]+=r*t.normalizedOffset[0],e.screenOffset[1]+=r*t.normalizedOffset[1],e}get _defaultPlacementInfo(){const e=this._graphic.graphic.geometry;if(null==e)return null;switch(e.type){case"polyline":case"extent":case"multipoint":return{placement:"center-center",normalizedOffset:l,anchor:"center"};case"polygon":{const e=this._firstSymbolLayer;return"extrude"===e?.type?d["above-center"]:{placement:"center-center",normalizedOffset:l,anchor:"center"}}case"point":case"mesh":return d["above-center"];default:return}}_validatePlacementInfo(e){const t=this._graphic.graphic.geometry;if(null==t)return null;if(null!=this._disablePlacement){const t=this._class.labelPlacement;return t?(b().warnOncePerTick(g(t,this._disablePlacement.logEntityDescription)),this._defaultPlacementInfo):e}const n=t.type;switch(n){case"polyline":case"polygon":case"extent":case"multipoint":{const e=this._class.labelPlacement;if(e)return d[e]&&b().warnOnce(g(e,`'${n}' geometries`)),this._defaultPlacementInfo;break}case"point":case"mesh":return e}return e}_setPointSpecificPlacement(e,r){const l=this._firstSymbolLayer;if(null==l)return;const a=this._graphic.layers[0];switch(null!=a?t(e.translation,a.getCenterObjectSpace()):n(e.translation,0,0,0),l.type){case"icon":case"text":this._setHUDSpecificPlacement(e,r,a);break;case"object":O(e,r,a)}}_setMeshSpecificPlacement(e,t){const n=this._firstSymbolLayer;if(null!=n&&"fill"===n.type){O(e,t,this._graphic.layers[0])}}_setPolygonSpecificPlacement(e,t){const r=this._firstSymbolLayer;if(null!=r)switch(r.type){case"extrude":{const r=this._graphic.layers[0];null!=r?(r.getBoundingBoxObjectSpace(v),s(v,e.translation),e.translation[2]=i(v)/2):n(e.translation,0,0,0),O(e,t,r);break}}}_setHUDSpecificPlacement(e,t,n){const r=null!=n?n.getScreenSize():null;if(this._graphic.isDraped||null==r)e.hasLabelVerticalOffset||"center"===e.anchor||(d[this._class.labelPlacement]&&b().warnOncePerTick(`the requested placement '${t.placement}' is currently unsupported for draped graphics`),e.anchor="center");else{const n=this._normalizedSymbolAnchorPos;e.screenOffset[0]=r[0]/2*(t.normalizedOffset[0]-n[0]);const l=r[1]/2*(t.normalizedOffset[1]-n[1]);e.hasLabelVerticalOffset?(e.centerOffset[1]=l,e.centerOffsetUnits="screen"):e.screenOffset[1]=l}}get _firstSymbolLayer(){const e=this._graphic.graphics3DSymbol,t=f(e);return null!=t?t.symbol.symbolLayers.at(0):null}get _normalizedSymbolAnchorPos(){const e=this._graphic.layers[0],t=e?.stageObject.geometries[0].material??null;if(t&&t instanceof p){const e=t.parameters.anchorPosition;_[0]=2*(e[0]-.5),_[1]=2*(e[1]-.5)}else _[0]=0,_[1]=0;return _}}function g(e,t){return`the requested label placement '${e}' is currently unsupported for ${t} in SceneView.`}function O(e,t,n){const l=null!=n?n.getBoundingBoxObjectSpace(v):v,c=a(l[3]-l[0],l[4]-l[1],l[5]-l[2]),s=Math.sqrt(c[0]*c[0]+c[1]*c[1]);e.centerOffset[0]=s/2*t.normalizedOffset[0];const i=e.translation[2],o=c[2]/2*t.normalizedOffset[1];e.translation[2]=0,e.elevationOffset=i+o;const f=r(c);e.centerOffset[2]=f/2*t.normalizedOffset[2]}function P(e){return"above-center"===e}const d={"above-center":{placement:"above-center",normalizedOffset:[0,1,0],anchor:"bottom"},"above-left":{placement:"above-left",normalizedOffset:[-1,1,0],anchor:"bottom-right"},"above-right":{placement:"above-right",normalizedOffset:[1,1,0],anchor:"bottom-left"},"below-center":{placement:"below-center",normalizedOffset:[0,-1,2],anchor:"top"},"below-left":{placement:"below-left",normalizedOffset:[-1,-1,0],anchor:"top-right"},"below-right":{placement:"below-right",normalizedOffset:[1,-1,0],anchor:"top-left"},"center-center":{placement:"center-center",normalizedOffset:[0,0,1],anchor:"center"},"center-left":{placement:"center-left",normalizedOffset:[-1,0,0],anchor:"right"},"center-right":{placement:"center-right",normalizedOffset:[1,0,0],anchor:"left"}},y={"above-center":["default","esriServerPointLabelPlacementAboveCenter"],"above-left":["esriServerPointLabelPlacementAboveLeft"],"above-right":["esriServerPointLabelPlacementAboveRight"],"below-center":["esriServerPointLabelPlacementBelowCenter"],"below-left":["esriServerPointLabelPlacementBelowLeft"],"below-right":["esriServerPointLabelPlacementBelowRight"],"center-center":["esriServerPointLabelPlacementCenterCenter"],"center-left":["esriServerPointLabelPlacementCenterLeft"],"center-right":["esriServerPointLabelPlacementCenterRight"]};for(const S in y){const e=y[S],t=d[S];e.forEach(e=>{d[e]=t})}Object.freeze&&(Object.freeze(d),Object.keys(d).forEach(e=>{Object.freeze(d[e]),Object.freeze(d[e]?.normalizedOffset)}));const _=[0,0],v=c();export{u as LabelInfo};