2012년 3월 15일 목요일

[ArcObjects]레이어 라벨 Expression 적용하기..

- 시군구별 데이터 매칭률을 계산하고 결과를 도면에 표시하는 기능을 추가하기 위해서 개발 하던중 도면에 표시할때 시군구 명칭과 매칭률을 동시에 라벨로 표현해야 했다.

- ArcMap 에서는 아래 그림과 같이 Label 속성에서 Expression을 사용해 VBScript 를 통해 다양한 라벨을 만들어 표현할 수 있다.

image

- 이런 형식으로 라벨을 만들어 표현하기 위해서 ArcObjects에서는 아래의 방법으로 구현이 가능하다.

- 주요 인터페이스

    > ESRI.ArcGIS.Carto.IAnnotateLayerPropertiesCollection

    > ESRI.ArcGIS.Carto.IAnnotateLayerProperties

    > ESRI.ArcGIS.Carto.IAnnotationExpressionEngine

    > ESRI.ArcGIS.Carto.IAnnotationExpressionParser

- VBScript 라벨 생성 함수 소스

   1: /// <summary>
   2: /// VBScript 형식의 라벨 표현
   3: /// </summary>
   4: /// <param name="pFeatureLayer"></param>
   5: /// <param name="sExpression"></param>
   6: /// <param name="pTextSym"></param>
   7: public static void SetLayerLabelByVBScriptEngine(IFeatureLayer pFeatureLayer, string sExpression, ITextSymbol pTextSym)
   8: {
   9:     IGeoFeatureLayer pGeoFLayer = (IGeoFeatureLayer)pFeatureLayer;
  10:     pGeoFLayer.DisplayAnnotation = true;    //라벨 ON
  11:  
  12:     //기존 라벨형식 Clear
  13:     IAnnotateLayerPropertiesCollection pAnnoLyrPropCol = pGeoFLayer.AnnotationProperties;
  14:     pAnnoLyrPropCol.Clear();    
  15:  
  16:     //VBScript 생성
  17:     IAnnotationExpressionEngine pAnnoExpEngine = new AnnotationVBScriptEngineClass();
  18:     IAnnotationExpressionParser pAnnoExpParser = pAnnoExpEngine.SetExpression(string.Empty, sExpression);
  19:  
  20:     //sExpression 에러체크
  21:     int nNumber = -1;
  22:     int nLine = -1;
  23:     string sDesc = string.Empty;
  24:  
  25:     pAnnoExpParser.LastError(ref nNumber, ref nLine, ref sDesc);
  26:  
  27:     if (nNumber != 0)
  28:     {
  29:         System.Diagnostics.Debug.Print(sDesc);
  30:         return;
  31:     }
  32:  
  33:     //Simple방식으로 Expression 적용
  34:     ILabelEngineLayerProperties pLabelEngLyrProp = new LabelEngineLayerPropertiesClass();
  35:     pLabelEngLyrProp.IsExpressionSimple = true;
  36:     pLabelEngLyrProp.ExpressionParser = pAnnoExpEngine;
  37:     pLabelEngLyrProp.Expression = sExpression;
  38:     pLabelEngLyrProp.Symbol = pTextSym;
  39:     
  40:     //라벨의 특성(위치, Conflict 등등)
  41:     IBasicOverposterLayerProperties pBasicProp = pLabelEngLyrProp.BasicOverposterLayerProperties;
  42:     pBasicProp.NumLabelsOption = esriBasicNumLabelsOption.esriOneLabelPerShape;
  43:     pBasicProp.GenerateUnplacedLabels = true;
  44:  
  45:     //라벨 스케일 설정
  46:     IAnnotateLayerProperties pAnnoLyrProp = (IAnnotateLayerProperties)pLabelEngLyrProp;
  47:     pAnnoLyrProp.AnnotationMaximumScale = 0;
  48:     pAnnoLyrProp.AnnotationMinimumScale = 0;
  49:  
  50:     //추가
  51:     pAnnoLyrPropCol.Add(pAnnoLyrProp);
  52: }

    > IAnnotateLayerPropertiesCollection 에는 여러 개의 IAnnotateLayerProperties가 생성될 수 있는데 IAnnotateLayerProperties.WhereClause 속성에서 쿼리 되는 Feature별로 다르게 라벨을 정할 수 있기 때문이다.


    > IAnnotationExpressionEngine.SetExpression 으로 사용자가 정의한 Expression을 적용하고 난 뒤 IAnnotationExpressionParser.LastError를 통해 사용자의 Expression을 검증할 수 있다.


    > 위 소스에서 적용된 Expression은 sExpression = “[SGG_NM] & vbcrlf & Round( [J_RATIO] , 2) & \"%\"” 이다.


    > ILabelEngineLayerProperties.IsExpressionSimple 속성에 따라 ArcMap에서 [Advanced]의 구분과 같은 역할을 한다.


    > IsExpressionSimple = true : 단순 VBScript를 통한 라벨 표현


    > IsExpressionSimple = False : Function을 통한 보다 강력한 라벨을 표현