• Annotation研究的一些学习资料


    转自chanyinhelv原文Annotation研究的一些学习资料

    下面是我最近对Annotation研究的一些学习资料,收集于此,供大家学习之用。

    一、Annotation要素类介绍

    在GeoDatabase中有五种类型的要素类,即点、线、面、标注要素类和注记要素类。注记要素类涉及的较少,这里不谈。本文主要讨论标注要素类的特征,即Annotation FeatureClass的特性。

    标注要素类是一种专门用于存储和显示文本或图形元素的数据结构,在这之前,我们只谈过文本或图像只能通过MXD的方式来存储。标注要素类可以是独立的,也可以与一个要素类相关联。如果是独立standalone的要素类,它就是其它要素类的一种背景;一旦与某个要素类相联系link,那么标注要素显示的内容就取决于与之相关的要素。

    如果要新建一个标注要素类,无论是直接在工作空间中还是在一个要素数据集中,都需要使用到IFeatureWorkspaceAnno的接口,下面我们通过这个接口的CreateAnnotationClass方法来介绍标注要素类的一系列特性:

    public IFeatureClass CreateAnnotationClass (
        string Name,
        IFields Fields,
        UID CLSID,
        UID EXTCLSID,
        string ShapeFieldName,
        string ConfigKeyword,
        IFeatureDataset dstFeatureDataset,
        IFeatureClass srcFeatureClass,
        object annoProperties,
        object referenceScale,
        object symbolCollection,
        bool autoCreate
    );

    Name是新建的标注要素类的名称,这个字符串可以随意设置。
    Fields是标注要素类的字段,与其它要素类不同的是,标注要素类的系统字段相当的多,这是因为标注字段涉及到存储字符和修饰字符的Symbol样式,因此,我们也不建议用户自己添加这些难以记忆的字段,在这种情况下,我们可以使用一种简单的方式实现:
    IObjectClassDescription pOCDesc=New AnnotationFeatureClassDescription;
    Fields=pOCDesc.RequiredFields;
    也许有人会问,如果除了这些系统字段外,我们还有自己的字段怎么办?这个很简单,使用IFieldsEdit的方法再加自定义字段就可以了。

    CLSID和EXTCLSID两个参数也是必须的,它们的含义非常有趣。我们知道,GeoDatabase中的每个对象都有个唯一标识符UID,系统是靠认证这个64位的随机值来区分不同对象的,同样的,要素类和要素类的扩展部分也有这么个标识,只不过在一般情况下我们无法看到这个UID值而已。如何产生这两个值呢,也很简单,使用:
    CLSID=pOCDesc.InstanceCLSID;
    EXTCLSID=pOCDesc.ClassExtensionCLSID;

    ShapeFieldName是指一个要素类的Shape字段名,一般都是"SHAPE"。

    ConfigKeyword一般不用设置,可以设置为空字符串。

    dstFeatureDataset是指一个标注要素类被放置的要素数据集,当然,如果这个标注要素类直接放在工作空间中,这个参数将被设置为null即可。

    srcFeatureClass是标注要素类关联的要素类,如果标注要素类是独立的,则这个参数也可以为null。

    接下来的四个参数的前三个就是关键了,可以说,整个要素类的正常显示就是依赖它们。

    二、使用Annotation对象进行要素标注并设置标注位置

     AO中有两种方法实现要素标注,一种是自己添加TextElement对象到文档对象中,另一种就是使用AO提供的Annotation对象,它的功能更加强大和丰富,它以更复杂的方法和属性对要素图层进行标注,标注的内容可以保存到地理数据库中。实现这个要素标注涉及到的对象包括IAnnotateLayerPropertiesCollection对象、IAnnotateLayerProperties对象和ILabelEngineLayerProperties对象,其实现代码如下:(c#)

              public void CreateAnno(IFeatureLayer pFeatureLayer )

             {

                   IGeoFeatureLayer pGeoFLayer = pFeatureLayer as IGeoFeatureLayer;
                    //得到图层的标注属性集合对象
             IAnnotateLayerPropertiesCollection pAnnoLayerpRropColl = new AnnotateLayerPropertiesCollectionClass();
                    pAnnoLayerpRropColl = pGeoFLayer.AnnotationProperties;

                    //清空这个集合中的对象
                    pAnnoLayerpRropColl.Clear();

                    //新建一个图层标注引擎对象,设置它的属性
                    ILabelEngineLayerProperties pLabelEngineLayerProp = new LabelEngineLayerPropertiesClass();
                    pLabelEngineLayerProp.Expression = "[DYP]";

                    //创建注记文本的文本符号
                    ITextSymbol pTextSym = new TextSymbolClass();
                    pTextSym.Color = GeoTool.GetColor(255, 0, 0);
                    pTextSym.Size = 10;
                    IFont font = new StdFontClass();
                    font.Name = "Times New Roman";
                    pTextSym.Font = (IFontDisp)font;
                    pLabelEngineLayerProp.Symbol = pTextSym;

                    //设置注记文本的位置
             IBasicOverposterLayerProperties pBasicOverposeterLayerProp = new BasicOverposterLayerPropertiesClass();
                    pBasicOverposeterLayerProp.FeatureType = esriBasicOverposterFeatureType.esriOverposterPoint;
                    pBasicOverposeterLayerProp.FeatureWeight = esriBasicOverposterWeight.esriNoWeight;
                    pBasicOverposeterLayerProp.LabelWeight = esriBasicOverposterWeight.esriHighWeight;
                    pBasicOverposeterLayerProp.BufferRatio = 0;

                    //方式一:标注位于点特征顶部
                   //pBasicOverposeterLayerProp.PointPlacementOnTop = true;

                    //方式二:标注环绕点特征
       pBasicOverposeterLayerProp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriAroundPoint;
                    IPointPlacementPriorities pPointPlacement = new PointPlacementPrioritiesClass();
                    pPointPlacement.AboveCenter = 0;
                    pPointPlacement.AboveLeft = 0;
                    pPointPlacement.AboveRight = 0;
                    pPointPlacement.BelowCenter = 1;
                    pPointPlacement.BelowLeft = 0;
                    pPointPlacement.BelowRight = 0;
                    pPointPlacement.CenterLeft = 0;
                    pPointPlacement.CenterRight = 0;
                    pBasicOverposeterLayerProp.PointPlacementPriorities = pPointPlacement;

                    //方式三:标准旋转一定角度
    //pBasicOverposeterLayerProp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriSpecifiedAngles;
                    //double[] angle = new double[2];
                    //angle[0] = 45;
                    //angle[1] = 90;
                    //pBasicOverposeterLayerProp.PointPlacementAngles = angle;
                    
                    pLabelEngineLayerProp.BasicOverposterLayerProperties = pBasicOverposeterLayerProp;

                    IAnnotateLayerProperties pAnnoLayerProp = (IAnnotateLayerProperties)pLabelEngineLayerProp;
                    pAnnoLayerpRropColl.Add(pAnnoLayerProp);

                    pGeoFLayer.DisplayField = pLabelEngineLayerProp.Expression;
                    pGeoFLayer.DisplayAnnotation = true;

            }

     

    三、使用TextElement对象进行要素标注

    使用TextElement对象进行要素标注可以控制标注字体的样式,标注的流程是首先获取要素图层中所有要进行标注的要素,然后对各个要素创建TextElement对象,并将其Text设为要素的某个字段属性,而Geometry是要素包括线的中间点。一下是在三维GlobeControl中的实现代码如:(c#)

               //获取图层要素对象

                IFeatureCursor pFeatCurso = new FeatureCursorClass();
                pFeatCurso = pFeatClass.Search(null, true);
                IFeature pFeature = null;
                pFeature = pFeatCurso.NextFeature();
                while (pFeature != null)
                {
                    //读取要素
                    .........................

                    pFeature = pFeatCurso.NextFeature();
                }

              以上是有关读取图层要素的过程,这里省略。

              添加标注代码:

              说明:pArray中存放的是IGeometry对象

             public void AddElement(ArrayList pArray, IGlobeGraphicsLayer pGlobeGraphicsLayer)
            {
                //删除上次添加的element
                IGraphicsContainer pGraphicsContainer = pGlobeGraphicsLayer as IGraphicsContainer;
                pGraphicsContainer.DeleteAllElements();
                pGlobeGraphicsLayer.UpdateAllElements();

                //设置显示属性
                IGlobeGraphicsElementProperties pGlobeGraphicsElementProperties = new GlobeGraphicsElementPropertiesClass();
                pGlobeGraphicsElementProperties.DrapeElement = true;
                pGlobeGraphicsElementProperties.FixedScreenSize = true;
                pGlobeGraphicsElementProperties.DrapeQuality = true;
                pGlobeGraphicsElementProperties.OrientationMode = esriGlobeGraphicsOrientation.esriGlobeGraphicsOrientationLocal;

                int hh;

                for (int i = 0; i < pArray.Count; i = i + 2)
                {
                    IGeometry pGeometry = (IGeometry)pArray[i + 1];
                    IPoint point = new PointClass();
                    point = GeoTool.GetGeo(pGeometry);


                    //添加点element对象(设置标注对象形状)
                    IElement pElement = new MarkerElementClass();              //定义为标注性对象方便后续设置
                    ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbolClass();   //设置形状
                    pSimpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                    IMarkerSymbol pMarkerSymbol = pSimpleMarkerSymbol as IMarkerSymbol;        //设置颜色大小
                    pMarkerSymbol.Color = GeoTool.GetColor(0, 255, 0);
                    pMarkerSymbol.Size = 5;

                    pElement.Geometry = point as IGeometry;
                    IMarkerElement pMarkerElement = pElement as IMarkerElement;
                    pMarkerElement.Symbol = pMarkerSymbol;
                    pGlobeGraphicsLayer.AddElement(pElement as IElement, pGlobeGraphicsElementProperties, out hh);

                    //添加文本element对象(标注的文字部分)
                    ITextElement pTextElement = new TextElementClass();
                    ITextSymbol pTextSymbol = new TextSymbolClass();
                    pTextSymbol.Color = GeoTool.GetColor(255, 0, 0);
                    pTextSymbol.Size = 10;
                    IFontDisp pFontDisp = (IFontDisp)new StdFontClass();             //设置字体
                    pFontDisp.Name = "Times New Roman";
                    pFontDisp.Bold = true;
                    pFontDisp.Size = 10;
                    pTextSymbol.Font = pFontDisp;
                    pTextSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
                    pTextElement.Symbol = pTextSymbol;
                    pTextElement.Text = pArray[i].ToString();
                    ((IElement)pTextElement).Geometry = point as IGeometry;
                    pGlobeGraphicsLayer.AddElement(pTextElement as IElement, pGlobeGraphicsElementProperties, out hh);
                }
            }

     

            对于二维中要加载TextElement标注,其创建TextElement的方法相同,主要是在于后面加载的方式不同而已,加载到的对象不同而已,三维GlobeControl中是加载到一个IGlobeGraphicsLayer中,二维中则是加载到MapControl的Map对象中。其核心代码如下:

            IMap pMap = axMapControl1.Map;

            IActiveView pActiveView = pMap as IActiveView;

            IGraphicsContainer pGraphicsContainer = pMap as IGraphicsContainer;

            //将元素添加进Map对象中

           pGraphicsContainer.AddElement(pElement,0);

           pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null);

  • 相关阅读:
    C# WinForm dataGridView 技巧小结
    Win7设置局域网共享
    vs2010快捷键大全
    C# WebBrowser.DocumentCompleted 多次调用解决方法
    为应用程序池 'DefaultAppPool' 提供服务的进程关闭时间超过了限制
    VB高清图标制作方法
    sqlite 中文排序
    一个vbs文件将指定文件夹下的文件名输出到指定文件夹下
    用DOS命令获取文件列表
    文件搜索神器 Everything
  • 原文地址:https://www.cnblogs.com/arxive/p/6262971.html
Copyright © 2020-2023  润新知