@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.3 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"../../../../core/has.js";import e from"../../../../core/Logger.js";import{i as t,l as n}from"../../../../chunks/vec32.js";import{ZEROS as r,fromValues as l}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as a,center as c,height as s}from"../../../../geometry/support/aaBoundingBox.js";import{labelMarginPx as i}from"./constants.js";import{getGraphics3DSymbol as o}from"./graphicSymbolUtils.js";import{LabelPlacement as f}from"./LabelParameters.js";import{textVerticalPaddingPx as m}from"../../webgl-engine/lib/TextRenderer.js";import{HUDMaterial as h}from"../../webgl-engine/materials/HUDMaterial.js";const p=()=>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 f(l,n,r);return this._calculatePlacementOffsets(a,t)}get _verticalOffsetPlacement(){const e=this._class.labelPlacement,{_symbol:t,_graphic:n}=this,r=o(n.graphics3DSymbol),l="point-3d"===r?.symbol.type?r.symbol:null,a=P[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&&O(a.placement)?{placement:"above-center",verticalOffset:t.verticalOffset.clone(),anchor:"bottom",normalizedOffset:[0,a.normalizedOffset[1],0],hasLabelVerticalOffset:!0}:(p().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=P[t],r=n||this._defaultPlacementInfo;return t&&!n&&p().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=i-m;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:r,anchor:"center"};case"polygon":{const e=this._firstSymbolLayer;return"extrude"===e?.type?P["above-center"]:{placement:"center-center",normalizedOffset:r,anchor:"center"}}case"point":case"mesh":return P["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?(p().warnOncePerTick(b(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 P[e]&&p().warnOnce(b(e,`'${n}' geometries`)),this._defaultPlacementInfo;break}case"point":case"mesh":return e}return e}_setPointSpecificPlacement(e,n){const r=this._firstSymbolLayer;if(null==r)return;const l=this._graphic.layers[0];switch(null!=l?l.getCenterObjectSpace(e.translation):t(e.translation,0,0,0),r.type){case"icon":case"text":this._setHUDSpecificPlacement(e,n,l);break;case"object":g(e,n,l)}}_setMeshSpecificPlacement(e,t){const n=this._firstSymbolLayer;if(null!=n&&"fill"===n.type){g(e,t,this._graphic.layers[0])}}_setPolygonSpecificPlacement(e,n){const r=this._firstSymbolLayer;if(null!=r)switch(r.type){case"extrude":{const r=this._graphic.layers[0];null!=r?(r.getBoundingBoxObjectSpace(_),c(_,e.translation),e.translation[2]=s(_)/2):t(e.translation,0,0,0),g(e,n,r);break}}}_setHUDSpecificPlacement(e,t,n){const{_graphic:r}=this,l=null!=n?n.getScreenSize():null;if(r.isDraped||null==l)e.hasLabelVerticalOffset||"center"===e.anchor||(P[this._class.labelPlacement]&&p().warnOncePerTick(`the requested placement '${t.placement}' is currently unsupported for draped graphics`),e.anchor="center");else{const n=this._normalizedSymbolAnchorPos;e.screenOffset[0]=l[0]/2*(t.normalizedOffset[0]-n[0]);const r=l[1]/2*(t.normalizedOffset[1]-n[1]);e.hasLabelVerticalOffset?(e.centerOffset[1]=r,e.centerOffsetUnits="screen"):e.screenOffset[1]=r}}get _firstSymbolLayer(){const e=this._graphic.graphics3DSymbol,t=o(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 h){const e=t.parameters.anchorPosition;y[0]=2*(e[0]-.5),y[1]=2*(e[1]-.5)}else y[0]=0,y[1]=0;return y}}function b(e,t){return`the requested label placement '${e}' is currently unsupported for ${t} in SceneView.`}function g(e,t,r){const a=null!=r?r.getBoundingBoxObjectSpace(_):_,c=l(a[3]-a[0],a[4]-a[1],a[5]-a[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=n(c);e.centerOffset[2]=f/2*t.normalizedOffset[2]}function O(e){return"above-center"===e}const P={"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"}},d={"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 v in d){const e=d[v],t=P[v];e.forEach((e=>{P[e]=t}))}Object.freeze&&(Object.freeze(P),Object.keys(P).forEach((e=>{Object.freeze(P[e]),Object.freeze(P[e]?.normalizedOffset)})));const y=[0,0],_=a();export{u as LabelInfo};