比较丑陋,还望大家见怪,呵呵~~~,接下来给大家看看设计的界面吧:
界面比较丑陋,主要控件为:
四个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、没实现控制其摆放位置和方向。
后续还会继续对之上述问题进行优化,还望大家多多支持与鼓励!同时,有能解决上述方法的同仁还望不吝赐教!