ArcEnbine開發之添加標註

首先來看看實現的效果:

比較醜陋,還望大家見怪,呵呵~~~,接下來給大家看看設計的界面吧:

界面比較醜陋,主要控件爲: 四個combox,三個textbox和兩個按鈕,屬性值設置在此不詳述,還望見諒…… 下面看看實現代碼:

1、窗體加載事件:

/// <summary>
        /// 窗體加載
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void formLabel_Load(object sender, EventArgs e)
        {
            //字體大小
            for (int i = 5; i < 73; i++)
            {
                this.cmbFontsSize.Items.Add(i.ToString());
            }
            //字體樣式
            string[] strFontsStyle = new string[] {"宋體","Times New Roman","隸書","黑體","仿宋","新宋體","幼圓" };
            for (int i = 0; i < strFontsStyle.Length; i++)
            {
                this.cmbFontsStyle.Items.Add(strFontsStyle[i]);
            }
            //添加圖層
            AddLayers();
        }

此處,調用了AddLayers這個方法,其代碼爲:

/// <summary>
        /// 添加圖層
        /// </summary>
        private void AddLayers()
        {
            //首先清除
            cmbLayers.Items.Clear();
            //加載圖層,默認選擇第一個圖層
            int layerCount = _mapControl.LayerCount;
            for (int i = 0; i < layerCount; i++)
            {
                cmbLayers.Items.Add(_mapControl.get_Layer(i).Name);
            }
            if (layerCount != 0)
            {
                cmbLayers.SelectedIndex = 0;
            }
        }

在窗體加載事件中,完成了圖層的加載,以及字體大小,字體樣式值等的初始化工作,接着,圖層cmbLayers的選擇改變事件,實現加載該圖層的字段,詳細代碼如下:

/// <summary>
        /// 顯示字段
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbLayers_SelectedIndexChanged(object sender, EventArgs e)
        {
            //清空字段列表
            cmbFields.Items.Clear();
            //改變字段列表
            //獲取選擇的圖層
            IFeatureLayer featureLayer = _mapControl.get_Layer(cmbLayers.SelectedIndex) as IFeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            int fieldsCount = featureClass.Fields.FieldCount;
            for (int i = 0; i < fieldsCount; i++)
            {
                IField field = featureClass.Fields.get_Field(i);
                //除去Shape字段
                if (field.Name == "Shape")
                {
                    continue;
                }
                cmbFields.Items.Add(field.Name);
            }
        }

到此,標註樣式的設置工作業已完成,接下來就是要進行對圖層進行標註了,看看那個“確定”按鈕的事件:

/// <summary>
        /// 添加標註
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOk_Click(object sender, EventArgs e)
        {
            AddLabel addlabel = new AddLabel();
            ILayer mLayer = _mapControl.get_Layer(cmbLayers.SelectedIndex) as ILayer;
            addlabel.AddAnnotate(mLayer, this.cmbFields.Text, cmbFontsStyle.Text, double.Parse(cmbFontsSize.Text), int.Parse(txtR.Text), int.Parse(txtG.Text), int.Parse(txtB.Text));
            _mapControl.ActiveView.Refresh();
            this.Close();
        }

在該按鈕事件中調用了AddLabel這個類的AddAnnotate方法,在AddAnnotate方法中包含7個參數,標註的圖層,標註字段,字體大小,字體樣式以及字體顏色的RGB值,類AddLabel的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;

//ArcEngine引用
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using stdole;

namespace MapDemo
{
    public class AddLabel
    {
        private GetRgbColor getrgbcolor = new GetRgbColor();
        //添加標註,比TextElment功能更強大
        public void AddAnnotate(ILayer layer, string fieldName,string fontFamily,double fontSize,int colorR,int colorG,int colorB)
        {
            IGeoFeatureLayer pGeoLayer = layer as IGeoFeatureLayer;
            IAnnotateLayerPropertiesCollection IPALPColl = pGeoLayer.AnnotationProperties;
            IPALPColl.Clear();

            IRgbColor pColor = getrgbcolor.GetRGBColor(colorR, colorG, colorB);
            IFontDisp pFont = new StdFont()
            {
                Name = fontFamily,
                Bold = true
            } as IFontDisp;

            ITextSymbol pTextSymbol = new TextSymbolClass()
            {
                Color = pColor,
                Font = pFont,
                Size = fontSize
            };

            //用來控制標註和要素的相對位置關係
            ILineLabelPosition pLineLpos = new LineLabelPositionClass()
            {
                Parallel = false,  //修改標註的屬性
                Perpendicular = true,
                InLine = true
            };
            //用來控制標註衝突
            ILineLabelPlacementPriorities pLinePlace = new LineLabelPlacementPrioritiesClass()
            {
                AboveStart = 5, //讓above 和start的優先級爲5
                BelowAfter = 4
            };
            //用來實現對ILineLabelPosition 和 ILineLabelPlacementPriorities以及更高級屬性的控制
            IBasicOverposterLayerProperties pBOLP = new BasicOverposterLayerPropertiesClass()
            {
                FeatureType = esriBasicOverposterFeatureType.esriOverposterPolygon,
                LineLabelPlacementPriorities = pLinePlace,
                LineLabelPosition = pLineLpos
            };

            //創建標註對象
            ILabelEngineLayerProperties pLableEngine = new LabelEngineLayerPropertiesClass()
            {
                Symbol = pTextSymbol,
                BasicOverposterLayerProperties = pBOLP,
                IsExpressionSimple = true,
                Expression = "[" + fieldName + "]"
            };

            //設置標註的參考比例尺
            IAnnotateLayerTransformationProperties pAnnoLyrPros = pLableEngine as IAnnotateLayerTransformationProperties;
            pAnnoLyrPros.ReferenceScale = 2500000;

            //設置標註可見的最大最小比例尺
            IAnnotateLayerProperties pAnnoPros = pLableEngine as IAnnotateLayerProperties;
            pAnnoPros.AnnotationMaximumScale = 2500000;
            pAnnoPros.AnnotationMinimumScale = 25000000;
            //pAnnoPros.WhereClause屬性  設置過濾條件

            IPALPColl.Add(pAnnoPros);
            pGeoLayer.DisplayAnnotation = true;
        }
    }
}

至此,已完成標註工作,那個取消按鈕就不說了。 總結一下,本實例完成了對圖層屬性的標註,但存在以下問題: 1、不能夠隨地圖的放大與縮小而產生相對應的放大或者縮小的變化; 2、對於標註的重疊沒有處理; 3、沒實現控制其擺放位置和方向。 後續還會繼續對之上述問題進行優化,還望大家多多支持與鼓勵!同時,有能解決上述方法的同仁還望不吝賜教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章