• 【ESRI论坛6周年征文】ArcEngine注记(Anno/ Label/Element等)处理专题 -入门篇


    原发表于ESRI中国社区,转过来。我的社区帐号:jhlong

    ----------------------------------------我是分割线,下面才是正文--------------------------------------------------------
     
    1.说明
    6周年征文

    似乎就我这一篇ArcEngine开发的,搞开发的很少么?还是搞开发的都不善于言语?欢迎做ArcEngine开发的交流心得。


    ArcGis里的注记,个人认为常用的有:
    1.图层标注如arcmap里图层右键属性-labels内的label。这些有不少高级注记功能,其实ArcEngine都可以实现。看到论坛里也有不少没解决的于此相关的问题。具体看下面代码。
    2.屏幕element。这类有文本、点、线、面等,且可设置各种样式和符号。这些不保存在数据库中,可以通过保存mxd的方式进行保存。
    3.注记图层。就是IAnnoClass,存于数据库的注记。


    以下代码也是针对以上3种注记类型进行说明。

    个人文字描述不是太好,所以不多说,主要是代码加注释。需要时去找对应的大标题下的内容即可,总体不难理解。

    文档看起来排版有点乱,附上下载,下载的可能不是最新的,以本帖为准。

    http://pan.baidu.com/share/link?shareid=104303&uk=305065349

    CSDN下载:
    http://download.csdn.net/detail/jhlong12345/4768967

     【初级】ArcEngine注记处理专题.zip (45.79 KB) 

    新浪爱问下载:http://ishare.iask.sina.com.cn/f/34753842.html

    值此论坛6周年之际,发出来庆祝论坛生日快乐。

    主要适合初学者,也有一些高级功能及不常用的。自行选择。
    代码应该都可以直接复制粘贴使用,不能用时请自己思考,还不行可以pm我。
    如果看的过程中有任何疑问,请pm我。回帖也可以,但有可能漏掉。
    初次写这种文章,如果有不对的或需要补充或描述不清晰的地方,烦请大家告知。

    如果觉得对你有用,请多多支持。
     

    请勿用于商业用途,请免费转载和分享,转载请注明作者和出处。


    目录
    1.说明        1
    2.准备工作        2
    2.1创建一个自定义颜色IRgbColor        2
    2.2添加Element到地图窗口        2
    2.3字体不随地图缩放变化        2
    3.为图层增加注记表达式        2
    4.注记表达式转图层要素        5
    5.创建注记图层要素        6
    6.创建文本注记TextElement        7
    6.1创建一个字体        7
    6.2创建文本注记样式        8
    6.3.创建文本注记        8
    7.创建面注记PolygonElement        8
    7.1根据4点创建一个面        8
    7.2.创建面符号        9
    7.3.创建PolygonElement        9
    8.创建线注记LineElement        9
    8.1根据2点创建一条线        9
    8.2.创建线符号        10
    8.3.创建线注记        10
    9创建一个点状注记(MarkerElement)        10
    9.1根据XY创建一个点        10
    9.2.创建MarkerElement        11
    10.符号        11



    内容整理自我的博客:http://jhlong12345.blog.163.com/ ... 631292012625336861/ 。
    2.准备工作
    2.1创建一个自定义颜色IRgbColor
    下面会用到,很简单的一个小函数
    /// <summary>
    
    /// 自定义颜色,3个0是黑色,3个255是白色/// </summary>
    /// <param name="r">红,取值0—255,下同</param>
    /// <param name="g">绿.</param>
    /// <param name="b"></param>
    /// <returns>IRgbColor</returns>
    /// <remarks></remarks>
    private static IRgbColor ColorCustom(int r, int g, int b)
    {
    IRgbColor myColor = new RgbColor();
    myColor.Red = r; 
    myColor.Blue = b;
    myColor.Green = g;
    return myColor;
    }
    2.2添加Element到地图窗口
    创建完Element后,用下面这句就可以加到当前地图窗口了。
    (pMap as IGraphicsContainer) .AddElement(ele, 0);
    2.3字体不随地图缩放变化
    IMAP的ReferenceScale方法设置为0时,无论地图如何缩放,字体大小的屏幕距离不变,地图距离随比例尺变化。设置为其他比例尺如10000时,字体的地图距离就保持比例尺为10000时的高度,屏幕距离一直随比例尺变化。

    3.为图层增加注记表达式

    从注记表达式的文本文件中程序里读取并动态地增加注记。label expression 可以为简单的或vb脚本等。[]内的是字段名称。
    例如:
    Function FindLabel ([BH],[BM],[KD],[XZ])
    FindLabel = FormatNumber([KD],2,true,false,false)
    if (IsNull([XZ]) or ([XZ] = "")) then FindLabel = [BH] &"/"& [BM]&chr(13)&chr(10)&FindLabel 
    if left([XZ],1)=1 or left([XZ],1)=2 then  FindLabel = [BH]&"G/"&[BM]&chr(13)&chr(10)&FindLabel 
    if left([XZ],1)=3 or left([XZ],1)=4 then  FindLabel = [BH] &"/"&[BM]&chr(13)&chr(10)&FindLabel 
    End Function
    或者简单的一个字段:
    [XZ]


    这里的接口很少用,但是合理利用的话可以达到ArcMap里的高级效果

    代码如下:
    /// <summary>
    /// 图层增加注记表达式
    /// </summary>
    /// <param name="map">The map.</param>
    /// <param name="tcname">The tcname.</param>
    public static void AddAnno(ILayer plyr , string tcname)
    {
    if (!System.IO.File.Exists(注记文件存储路径))
    return;
    IGeoFeatureLayer pGeoFeaLayer = (plyr as IFeatureLayer) as IGeoFeatureLayer;
    IAnnotateLayerPropertiesCollection pAnoLayPC = pGeoFeaLayer.AnnotationProperties;
    pAnoLayPC.Clear();
    ILabelEngineLayerProperties pAnnoLayerProps = new LabelEngineLayerPropertiesClass();
    (pAnnoLayerProps.BasicOverposterLayerProperties as IOverposterLayerProperties2).TagUnplaced = false;  ////是否覆盖,对应Arcmap:layer properties-》labels-》placement properties-》conflict detection ::place overlapping labels
    pAnnoLayerProps.SymbolID = 0;
    IBasicOverposterLayerProperties4 blp = pAnnoLayerProps.BasicOverposterLayerProperties asIBasicOverposterLayerProperties4;
    //blp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriAroundPoint;
    blp.NumLabelsOption = esriBasicNumLabelsOption.esriOneLabelPerShape; ////每个图形只标注一个  label properties--palcement properties--duplicate labels
    blp.PolygonPlacementMethod = esriOverposterPolygonPlacementMethod.esriAlwaysHorizontal; //// label properties--palcement properties--polygon settings
    // blp.PlaceOnlyInsidePolygon = true;  ////保证在图形内部  label properties--palcement properties--only place label inside polygon
    string annoExpression = GetAnnoExpression(注记文件存储路径);
    if (annoExpression.ToUpper().IndexOf("FUNCTION") >= 0)
    pAnnoLayerProps.IsExpressionSimple = false;
    else
    pAnnoLayerProps.IsExpressionSimple = true; //对应aArcMap的advanced选项
    pAnnoLayerProps.Expression = annoExpression;
    pAnnoLayerProps.Symbol = CreateTextSymbol();
    pGeoFeaLayer.DisplayAnnotation = true;
    }
    /// <summary>
    /// 根据注记文件存储路径获取标注表达式
    /// </summary>
    /// <param name="tcname">The tcname.</param>
    /// <returns></returns>
    public static string GetAnnoExpression(string注记文件存储路径)
    {
    StreamReader sr = new StreamReader(注记文件存储路径);
    string annoExpression = string.Empty;
    while (!sr.EndOfStream)
    {
    string text = sr.ReadLine();
    if (annoExpression == string.Empty)
    annoExpression = text;
    else
    annoExpression = annoExpression + "
    " + text;
    }
    return annoExpression;
    }
    4.注记表达式转图层要素
    这段代码参见帮助文档,无需多解释,根据需要使用。
    public static void ConvertLabelsToGDBAnnotationSingleLayer(IMap pMap, int layerIndex, bool featureLinked, stringlogpath)
    {
    string tcmc = string.Empty;
    try
    {
    IConvertLabelsToAnnotation pConvertLabelsToAnnotation = new ConvertLabelsToAnnotationClass();
    ITrackCancel pTrackCancel = new CancelTrackerClass();
    //Change global level options for the conversion by sending in different parameters to the next line.
    pConvertLabelsToAnnotation.Initialize(pMap,
    esriAnnotationStorageType.esriDatabaseAnnotation,
    esriLabelWhichFeatures.esriAllFeatures, true, pTrackCancel, null);
    ILayer pLayer = pMap.get_Layer(layerIndex);
    IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer;
    if (pGeoFeatureLayer != null)
    {
    IFeatureClass pFeatureClass = pGeoFeatureLayer.FeatureClass;
    IDataset pDataset = pFeatureClass as IDataset;
    tcmc = GtMap.JNCommon.Engine.GetPureName(pDataset.Name);
    IFeatureWorkspace pFeatureWorkspace = pDataset.Workspace as
    IFeatureWorkspace;
    //Add the layer information to the converter object. Specify the parameters of the output annotation feature class here as well.
    pConvertLabelsToAnnotation.AddFeatureLayer(pGeoFeatureLayer, tcmc + "ZJ", pFeatureWorkspace,
    pFeatureClass.FeatureDataset, featureLinked, true, true, true, true, "");
    //Do the conversion.
    pConvertLabelsToAnnotation.ConvertLabels();
    string errorInfo = pConvertLabelsToAnnotation.ErrorInfo;
    if (!string.IsNullOrEmpty(errorInfo))
    LogWrite(logpath, errorInfo);
    //IEnumLayer pEnumLayer = pConvertLabelsToAnnotation.AnnoLayers;
    //Turn off labeling for the layer converted.
    pGeoFeatureLayer.DisplayAnnotation = false;
    //Add the result annotation layer to the map.
    //pMap.AddLayers(pEnumLayer, true);
    //Refresh the map to update the display.
    IActiveView pActiveView = pMap as IActiveView;
    pActiveView.Refresh();
    iConvertCnt++;
    if (iConvertCnt < 6)
    {   
    IFeatureClass cls = pFeatureWorkspace.OpenFeatureClass(tcmc + "ZJ");
    if (cls != null)
    {
    if ((cls.FeatureCount(null) == 0) && (pFeatureClass.FeatureCount(null) > 0))
    {
    pGeoFeatureLayer.DisplayAnnotation = true;
    ConvertLabelsToGDBAnnotationSingleLayer(pMap, layerIndex, featureLinked, logpath);
    }
    }
    }
    }
    }
    catch (System.Exception ex)
    {
    }
    }
    5.创建注记图层要素
    创建完文本注记TextElement后,可以选择以屏幕注记的形式加到屏幕上,也可以通过下面的方式转为注记图层要素:
    IFeatureClass annocls = 获取注记图层
    IDataset pDataset = annocls as IDataset;
    ITransactions pTransactions = pDataset.Workspace as ITransactions;
    pTransactions.StartTransaction();
    IFDOGraphicsLayerFactory pFDOGLFactory = new FDOGraphicsLayerFactoryClass();
    ILayer tmpLayer = pFDOGLFactory.OpenGraphicsLayer(pDataset.Workspace as IFeatureWorkspace, annocls.FeatureDataset, pDataset.Name);
    IFDOGraphicsLayer pFDOGLayer = tmpLayer as IFDOGraphicsLayer;
    IElementCollection pElementColl = new ElementCollectionClass();
    pFDOGLayer.BeginAddElements();
    ……………………………… //创建text element
    pElementColl.Add(element, 0);
    …………………………….
    ////每新增100个提交下,最后再提交下。防止过多转换失败
    if ((pElementColl != null) && (pElementColl.Count == 100))
    {
    pFDOGLayer.DoAddElements(pElementColl, 0);
    pFDOGLayer.EndAddElements();
    pElementColl.Clear();
    pTransactions.CommitTransaction();
    pTransactions.StartTransaction();
    pFDOGLayer.BeginAddElements();
    }
    if (pElementColl.Count > 0)
    pFDOGLayer.DoAddElements(pElementColl, 0);
    pFDOGLayer.EndAddElements();
    pElementColl.Clear();
    pTransactions.CommitTransaction();
    6.创建文本注记TextElement
    6.1创建一个字体
    /// <summary>
    /// 字体设置
    /// </summary>
    /// <param name="size">The size.</param>
    /// <param name="fontname">The fontname.</param>
    /// <returns>
    /// IFontDisp
    /// </returns>
    public static stdole.IFontDisp GetIFontDisp(float size, string fontname)
    {
    string fontFamilyName = fontname;
    FontStyle fontStyle = FontStyle.Regular;
    Font font = new Font(fontFamilyName, size, fontStyle);
    return OLE.GetIFontDispFromFont(font) as stdole.IFontDisp;
    }
    6.2创建文本注记样式
    /// <summary>
    ///文本注记样式
    /// </summary>
    /// <param name="geometry">标注点,一个点即可</param>
    /// <param name="text">标注内容</param>
    /// <returns>
    /// IElement
    /// </returns>
    public static ITextSymbol GetTextElement(IGeometry geometry, string text)
    {
    ITextSymbol textSymbol = new TextSymbolClass();
    textSymbol.Color = ColorCustom(0, 0, 0);
    ////不可以直接修改textSymbol.Font.Bold等属性,无效
    stdole.IFontDisp font =  GetIFontDisp(9F, "宋体");
    font .Bold = false;
    font .Italic = false;
    font .Strikethrough = false;
    font .Underline = false;
    textSymbol.Font = font;
    textSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft; ////水平
    textSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVATop; ; ////垂直
    return textSymbol ;
    }
    6.3.创建文本注记
    ITextElement textElement = new TextElementClass();
    textElement.ScaleText = true;
    textElement.Symbol = GetTextElement();
    textElement.Text = text;
    IElement element = textElement as IElement;
    element.Geometry = geometry;
    7.创建面注记PolygonElement
    7.1根据4点创建一个面
    /// <summary>
    /// 根据4个点创建图形,点序要顺时针
    /// </summary>
    /// <param name="pnt1">点1</param>
    /// <param name="pnt2">点2</param>
    /// <param name="pnt3">点3</param>
    /// <param name="pnt4">点4</param>
    /// <returns>IPolygon</returns>
    public static IPolygon CreatePolygonBy4Points(IPoint pnt1, IPoint pnt2, IPoint pnt3, IPoint pnt4)
    {
    IPointCollection pPntCol = new PolygonClass();
    object missing = Type.Missing; ////顺时针添加 
    pPntCol.AddPoint(pnt1, ref missing, ref missing);
    pPntCol.AddPoint(pnt2, ref missing, ref missing);
    pPntCol.AddPoint(pnt3, ref missing, ref missing);
    pPntCol.AddPoint(pnt4, ref missing, ref missing);
    pPntCol.AddPoint(pnt1, ref missing, ref missing); //// 为保持首尾相联,故将第一个点再添加一次
    return pPntCol as IPolygon;
    }
    7.2.创建面符号
    /// <summary>
    /// 创建 面 符号
    /// </summary>
    /// <param name="r">The r.</param>
    /// <param name="g">The g.</param>
    /// <param name="b">The b.</param>
    /// <returns>ISimpleFillSymbol</returns>
    public static ISimpleFillSymbol CreateGeoSymbol(int r, int g, int b)
    {
    ISimpleFillSymbol psymbol = new SimpleFillSymbolClass() as ISimpleFillSymbol;
    psymbol.Color = ColorCustom(r, g, b);
    psymbol.Outline.Color = ColorCustom(r, g, b);
    return psymbol;
    }
    7.3.创建PolygonElement
    IElement pele = new PolygonElementClass();
    pele.Geometry = pGeoCol as IGeometry;
    (pele as IFillShapeElement).Symbol = CreateGeoSymbol(r, gD, b);
    (pmap as IGraphicsContainer).AddElement(pele, 0);
    8.创建线注记LineElement
    8.1根据2点创建一条线
    /// <summary>
    /// 创建线
    /// </summary>
    /// <param name="pnt1">The PNT1.</param>
    /// <param name="pnt2">The PNT2.</param>
    public static void CreateLine( IPoint pnt1, IPoint pnt2)
    {
    IPolyline pline = new PolylineClass();
    pline.FromPoint = pnt1;
    pline.ToPoint = pnt2;
    }
    8.2.创建线符号
    /// <summary>
    /// 创建 线 符号
    /// </summary>
    /// <param name="r">The r.</param>
    /// <param name="g">The g.</param>
    /// <param name="b">The b.</param>
    /// <returns>ILineSymbol</returns>
    /// <remarks></remarks>
    private static ILineSymbol CreateLineSymbol(int r, int g, int b)
    {
    ILineSymbol psymbol = new SimpleLineSymbolClass() as ILineSymbol;
    psymbol.Color = ColorCustom(r, g, b);
    psymbol.Width = 1;
    return psymbol;
    }
    8.3.创建线注记
    IElement pele = new LineElementClass();
    pele.Geometry = pPolyline as IGeometry;
    (pele as ILineElement).Symbol = CreateLineSymbol(r, g, b);
    (pmap as IGraphicsContainer).AddElement(pele, 0);
    9创建一个点状注记(MarkerElement)
    9.1根据XY创建一个点
    /// <summary>
    /// 根据x y创建新点
    /// </summary>
    /// <param name="dX">x坐标值</param>
    /// <param name="dY">y坐标值</param>
    /// <returns>返回点要素</returns>
    /// <remarks></remarks>
    public static IPoint GetPntFromXY(double dX, double dY)
    {
    IPoint pPnt = new PointClass();
    pPnt.PutCoords(dX, dY);
    return pPnt;
    }
    9.2.创建MarkerElement
    IElement pele = new MarkerElementClass();
    pele.Geometry = GetPntFromXY(x, y);
    IMarkerSymbol sym = new SimpleMarkerSymbolClass();
    sym.Color = ColorCustom(rDefault, gDefault, bDefault);
    sym.Size = 4;
    (pele as IMarkerElement).Symbol = sym;
    10.符号
    Element创建好后可以赋个符号。这一块主要是符号化相关的东西,不做详细介绍,只简单创建一个。
    ISimpleFillSymbol pSFillSym = new SimpleFillSymbolClass();
               pSFillSym.Style = esriSimpleFillStyle.esriSFSHollow;
               ISimpleLineSymbol pLineSymbol = new SimpleLineSymbolClass();
               pLineSymbol.Style=esriSimpleLineStyle.esriSLSNull;            pSFillSym.Outline = pLineSymbol;
            
               ISimpleMarkerSymbol Symbol = new SimpleMarkerSymbolClass();
               (pSymbol as IMarkerSymbol).Size = 3;
  • 相关阅读:
    九个PHP有用功能
    ajax的上拉功能
    jquery 插件
    任务08(全体)——第一次半月学习总结
    任务02——安装 Intellj IDEA,编写一个简易四则运算小程序,并将代码提交到 GitHub
    任务01——谈谈对参与工作室的预期
    任务08
    任务03
    任务02
    任务01
  • 原文地址:https://www.cnblogs.com/jhlong/p/5394385.html
Copyright © 2020-2023  润新知