首先來看看實現的效果:
比較醜陋,還望大家見怪,呵呵~~~,接下來給大家看看設計的界面吧:
界面比較醜陋,主要控件爲: 四個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、沒實現控制其擺放位置和方向。 後續還會繼續對之上述問題進行優化,還望大家多多支持與鼓勵!同時,有能解決上述方法的同仁還望不吝賜教!