ArcEngine符号相关

  • Post author:
  • Post category:其他




1.图层符号设置



1.1.通过图层属性面板设置符号

/// <summary>
/// 配置目录控件右键菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TocControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
    if (e.button == 2)
    {
        esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
        IBasicMap map = new MapClass();
        ILayer pLayer = null;
        object other = new object();
        object index = new object();
        TocControl.HitTest(e.x, e.y, ref item, ref map, ref pLayer, ref other, ref index);
        if (pLayer is ILayer)
        {
        	//菜单内容配置,可根据需要自行添加,如查看属性表、缩放图层等
       	    var tocContextMenuStrip = new ContextMenuStrip();
       	    tocContextMenuStrip.Items.Add("属性", Image.FromFile(path + "属性.png"), Properties_Click);
            TocControl.ContextMenuStrip = tocContextMenuStrip;
        }
        TocControl.ContextMenuStrip.Show(TocControl, e.x, e.y);
    }
}
/// <summary>
/// 配置图层属性table页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Properties_Click(object sender, EventArgs e)
{
    var pItem = esriTOCControlItem.esriTOCControlItemNone;
    ILayer pLayer = null;
    IBasicMap pMap = null;
    object pIndex = null;
    object pOther = null;
    TocControl.GetSelectedItem(ref pItem, ref pMap, ref pLayer, ref pIndex, ref pOther);
    if (pLayer != null)
    {
        IComPropertySheet pComPropSheet;
        pComPropSheet = new ComPropertySheet();
        pComPropSheet.Title = pLayer.Name + $" - {Localization.GetString("PropertiesString")}";
        UID pPPUID = new UIDClass();
        pComPropSheet.AddCategoryID(pPPUID);
        // General
        IPropertyPage pGenPage = new GeneralLayerPropPageClass();
        pComPropSheet.AddPage(pGenPage);
        // Source
        IPropertyPage pSrcPage = new FeatureLayerSourcePropertyPageClass();
        pComPropSheet.AddPage(pSrcPage);
         Selection
        //IPropertyPage pSelectPage = new FeatureLayerSelectionPropertyPageClass();
        //pComPropSheet.AddPage(pSelectPage);
        // Display
        //IPropertyPage pDispPage = new FeatureLayerDisplayPropertyPageClass();
        //pComPropSheet.AddPage(pDispPage);
        // Symbology
        IPropertyPage pDrawPage = new LayerDrawingPropertyPageClass();
        pComPropSheet.AddPage(pDrawPage);
        // Fields
        IPropertyPage pFieldsPage = new LayerFieldsPropertyPageClass();
        pComPropSheet.AddPage(pFieldsPage);
         Definition Query... 
        //IPropertyPage pQueryPage = new LayerDefinitionQueryPropertyPageClass();
        //pComPropSheet.AddPage(pQueryPage);
        //Labels
        IPropertyPage pSelPage = new LayerLabelsPropertyPageClass();
        pComPropSheet.AddPage(pSelPage);
        ISet pMySet = new SetClass();
        pMySet.Add(pLayer);
        pMySet.Reset();
        pComPropSheet.EditProperties(pMySet, 0);
        //更新图层目录和地图控件,使设置修改生效
        TocControl.Update();
        //CurrentMapControl指当前地图控件
        CurrentMapControl.Update();
        CurrentMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
    }

}



1.2.设置自定义符号

符号类型及具体属性设置可通过arcmap双击符号,点击编辑符号进行查看(建议使用英文版):

在这里插入图片描述

上述线图层符号Type对应CartographicLineSymbolClass,Color对应symbol.Color(可点开查看rgb),Width对应symbol.Width ,其余设置由于是默认,故不修改,若有需要也可根据上述页面进行修改。点图层和面图层同理。

故线图层符号设置如下所示:

/// <summary>
/// 设置线图层符号
/// </summary>
/// <param name="layer"></param>
private void SetLineSymbol(ILayer layer)
{
    ICartographicLineSymbol symbol = new CartographicLineSymbolClass();
    symbol.Color = new RgbColorClass() { Red = 255, Green = 97, Blue = 0 };
    symbol.Width = 4;
    var geoTrackLineLayer = layer as IGeoFeatureLayer;
    ISimpleRenderer render3 = new SimpleRendererClass();
    render3.Symbol = (ISymbol)symbol;
    geoTrackLineLayer.Renderer = render3 as IFeatureRenderer;
}

若遇到组合符号,如下图所示:

在这里插入图片描述

其中Unicode对应CharacterIndex 属性

IMultiLayerMarkerSymbol symbol3 = new MultiLayerMarkerSymbolClass();
ICharacterMarkerSymbol symbol31 = new CharacterMarkerSymbolClass();
symbol31.Size = 15.5;
symbol31.Angle = 90;
symbol31.Color = white;
symbol31.CharacterIndex = 60;
symbol31.XOffset = -0.25;
symbol31.YOffset = 0.25;
ICharacterMarkerSymbol symbol32 = new CharacterMarkerSymbolClass();
symbol32.Size = 18;
symbol32.Color = black;
symbol32.CharacterIndex = 33;
symbol3.AddLayer(symbol32);
symbol3.AddLayer(symbol31);
LoadingDistributionSymbol = (ISymbol)symbol3;



1.3.读取lyr图层文件设置符号

lyr图层文件可通过arcmap设置好图层符号之后右键导出

 /// <summary>
/// 通过lyr设置符号
/// </summary>
public static void SetSymbolLyr(ILayer layer)
{
    var lyrPath = @"F:\test.lyr";
    if (File.Exists(lyrPath))
    {
        ILayerFile layerFile = new LayerFileClass();
        layerFile.Open(lyrPath);
        //矢量数据
        if (layer is IGeoFeatureLayer geoFeatureLayer)
        {
            geoFeatureLayer.Renderer = geoFeatureLayer.Renderer;
        }
        else if (layer is IRasterLayer raster)
        {
            raster.Renderer = raster.Renderer;
        }
        layer.Visible = layerFile.Layer.Visible;
        layerFile.Close();
        Marshal.ReleaseComObject(layerFile);
    }
}



1.4.读取style样式文件设置符号

有时符号较复杂,直接通过自定义符号的方式可能转成图片预览时会有细微差别,或者项目所需符号较多,解析每个符号的属性工作量过大,此时则可以通过style样式文件来解决。

通过armap设置好所需的符号,点击保存,保存至style样式文件中

在这里插入图片描述

void LoadingStyle()
{
    读取符号文件的符号
    IStyleGallery styleGalley = new ESRI.ArcGIS.Framework.StyleGalleryClass();
    IStyleGalleryStorage styleGalleryStorage = styleGalley as IStyleGalleryStorage;
    //判断所选择的文件是否已经装载,若尚未加载,则加载之  
    bool styleExit = false;
    var path = SmartZn.Utility.Common.PathHelper.GetCurrentRootPath() + "Styles\\10020.style";
    if (!File.Exists(path))
    {
        MessageService.ShowError("无法找到样式文件");
        return;
    }
    for (int i = 0; i < styleGalleryStorage.FileCount; i++)
    {
        if (styleGalleryStorage.get_File(i) == path)
            styleExit = true;
    }
    if (System.IO.File.Exists(path))
    {
        if (styleExit == false)
            styleGalleryStorage.AddFile(path);
        //目标符号在Marker Symbols模块,具体解释见后面备注,如果不想麻烦也可以自己遍历调试代码找到自己需要的符号,自行灵活变通
        var enumStyleGalleryItem = styleGalley.get_Items("Marker Symbols", path, "");
        enumStyleGalleryItem.Reset();
        var styleGalleryItem = enumStyleGalleryItem.Next();
        while (styleGalleryItem != null)
        {
        	var symbol= (ISymbol)styleGalleryItem.Item;
        	//可通过符号名称获取指定的符号
            //if (styleGalleryItem.Name == "test")
            styleGalleryItem = enumStyleGalleryItem.Next();
        }
    }
}

备注:

目标符号所在的模块名称可通过armap的样式管理器查看:菜单栏——customize——style manager(中文为:自定义——样式管理器)

在这里插入图片描述

(灰色为无符号,黄色会有符号的模块。)



1.5.添加图层标注

/// <summary>
/// 标注图层
/// </summary>
/// <param name="layer"></param>
public void LabelLayer(IFeatureLayer layer, double size)
{
   //判断图层是否为空
   if (layer == null)
       return;
   IGeoFeatureLayer geoFeatureLayer = (IGeoFeatureLayer)layer;
   IAnnotateLayerPropertiesCollection pAnnoLayerPropsCollection;
   pAnnoLayerPropsCollection = geoFeatureLayer.AnnotationProperties;
   pAnnoLayerPropsCollection.Clear();
   IBasicOverposterLayerProperties4 basicOverposterLayer = new BasicOverposterLayerPropertiesClass();
   switch (layer.FeatureClass.ShapeType)//判断图层类型
   {
       case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
           basicOverposterLayer.FeatureType = esriBasicOverposterFeatureType.esriOverposterPolygon;
           break;
       case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
           basicOverposterLayer.FeatureType = esriBasicOverposterFeatureType.esriOverposterPoint;
           break;
       case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
           basicOverposterLayer.FeatureType = esriBasicOverposterFeatureType.esriOverposterPolyline;
           break;
   }
   basicOverposterLayer.PointPlacementMethod = esriOverposterPointPlacementMethod.esriAroundPoint;
   ILabelEngineLayerProperties labelEngineLayer = new LabelEngineLayerPropertiesClass();
   //标注字段
   labelEngineLayer.Expression = "[Sid]";
   text.ScaleText = true;

   ITextSymbol symbol = text.Symbol;
   symbol.Size = size;
   text.Symbol = symbol;
   labelEngineLayer.Symbol = text.Symbol;
   labelEngineLayer.BasicOverposterLayerProperties = basicOverposterLayer as IBasicOverposterLayerProperties;
   pAnnoLayerPropsCollection.Add((IAnnotateLayerProperties)labelEngineLayer);
   geoFeatureLayer.DisplayAnnotation = true;
}



2.几何符号设置

public static void DrawGeo(AxMapControl mapControl, IGeometry pubGeometry)
 {
     if (pubGeometry != null)
     {
         var g = mapControl.ActiveView as IGraphicsContainer;
         g.DeleteAllElements();
         switch (pubGeometry.GeometryType)
         {
             case esriGeometryType.esriGeometryPolygon:
                 //简单填充样式和颜色
                 ISimpleFillSymbol pFillSymbol = new SimpleFillSymbol();
                 pFillSymbol.Color = TransColorToAEColor(geoColor);
                 pFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
                 PolygonElement pPolygonEle = new PolygonElement();
                 pPolygonEle.Opacity = Opatity;
                 pPolygonEle.Symbol = pFillSymbol;
                 IElement pEle = pPolygonEle as IElement;
                 pEle.Geometry = pubGeometry;
                 g.AddElement(pEle, 0);
                 break;
             case esriGeometryType.esriGeometryPolyline:
                 ILineElement pLineElement;
                 IElement pLElement;
                 ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbolClass();
                 pSimpleLineSymbol.Color = TransColorToAEColor(geoColor);
                 pSimpleLineSymbol.Width = 2;
                 pLineElement = new LineElementClass();
                 pLineElement.Symbol = pSimpleLineSymbol;
                 pLElement = pLineElement as IElement;
                 IRubberBand pRubberBand;
                 pRubberBand = new RubberLineClass();
                 pLElement.Geometry = pubGeometry;
                 g.AddElement(pLElement, 0);
                 break;
             case esriGeometryType.esriGeometryPoint:
                 IMarkerElement pMarkerElement = new MarkerElementClass();
                 pMarkerElement.Symbol.Color = TransColorToAEColor(geoColor);
                 var pElement = pMarkerElement as IElement;
                 pElement.Geometry = pubGeometry;
                 g.AddElement(pElement, 0);
                 break;
         }
         mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, mapControl.Extent);
     }
 }

由于arcengine没有支持透明度的设置,故重写了一个Polygon类

public class PolygonElement : PolygonElementClass, IElement
{
    /// <summary>
    ///     透明度,0为完全透明,100为不透明
    /// </summary>
    public int Opacity { get; set; }

    void IElement.Activate(IDisplay Display)
    {
        base.Activate(Display);
    }

    void IElement.Deactivate()
    {
        base.Deactivate();
    }

    void IElement.Draw(IDisplay Display, ITrackCancel TrackCancel)
    {
        ITransparencyDisplayFilter filter = new TransparencyDisplayFilterClass
        {
            Transparency = (short) (Opacity * 0xff / 100)
        };
        IDisplayFilter filter2 = null;
        if (Display.Filter != null) filter2 = (Display.Filter as IClone).Clone() as IDisplayFilter;
        Display.Filter = filter;
        base.Draw(Display, TrackCancel);
        Display.Filter = filter2;
    }

    bool IElement.HitTest(double x, double y, double Tolerance)
    {
        return base.HitTest(x, y, Tolerance);
    }

    void IElement.QueryBounds(IDisplay Display, IEnvelope Bounds)
    {
        base.QueryBounds(Display, Bounds);
    }

    void IElement.QueryOutline(IDisplay Display, IPolygon Outline)
    {
        base.QueryOutline(Display, Outline);
    }

    IGeometry IElement.Geometry
    {
        get => base.Geometry;
        set => base.Geometry = value;
    }

    bool IElement.Locked
    {
        get => base.Locked;
        set => base.Locked = value;
    }

    ISelectionTracker IElement.SelectionTracker => base.SelectionTracker;
}



3.符号转图片进行预览

/// <summary>
/// 读取图层符号进行预览
/// </summary>
/// <param name="layer"></param>
/// <returns></returns>
public static ObservableCollection<ImageInfo> GetSysmbolOfLayer(ILayer layer)
{
    var result = new ObservableCollection<ImageInfo>();
    var render = (layer as IGeoFeatureLayer).Renderer;
    if (render is ISimpleRenderer sr)
    {
        result.Add(new ImageInfo()
        {
            Image = ImageUtility.GetImageFromSymbol(sr.Symbol, 20, 20),
            Info = "所有值"
        });
    }
    else if (render is IUniqueValueRenderer ur)
    {
        for(int i = 0; i < ur.ValueCount; i++)
        {
            var value = ur.Value[i];
            result.Add(new ImageInfo()
            {
                Image = ImageUtility.GetImageFromSymbol(ur.Symbol[value], 20, 20),
                Info = ur.Label[value]
            });
        }
    }
    else if (render is IClassBreaksRenderer cr)
    {
        for (int i = 0; i < cr.BreakCount; i++)
        {
            result.Add(new ImageInfo()
            {
                Image = ImageUtility.GetImageFromSymbol(cr.Symbol[i], 20, 20),
                Info = cr.Label[i]
            });
        }
    }
    else if (render is IChartRenderer chart)
    {
        result.Add(new ImageInfo()
        {
            Image = ImageUtility.GetImageFromSymbol(chart.ChartSymbol as ISymbol, 20, 20),
            Info = chart.Label
        });
    }
    return result;
}
/// <summary>
/// 符号转图片(ImageUtility.GetImageFromSymbol)
/// </summary>
/// <param name="pSymbol">符号</param>
/// <param name="width">图片宽度</param>
/// <param name="height">图片高度</param>
/// <returns></returns>
public static System.Drawing.Image GetImageFromSymbol(ISymbol pSymbol, int width, int height)
{
    IStyleGalleryClass styleGalleryClass = null;
    if (pSymbol is IMarkerSymbol)
    {
        styleGalleryClass = new MarkerSymbolStyleGalleryClass();
    }
    else if (pSymbol is ILineSymbol)
    {
        styleGalleryClass = new LineSymbolStyleGalleryClass();
    }
    else if (pSymbol is IFillSymbol)
    {
        styleGalleryClass = new FillSymbolStyleGalleryClassClass();
    }

    if (styleGalleryClass != null)
    {
         System.Drawing.Image img = new Bitmap(width, height);
	     Graphics gc = Graphics.FromImage(img);
	     IntPtr hdc = gc.GetHdc();
	     var rect = new tagRECT();
	     rect.left = 0;
	     rect.top = 0;
	     rect.right = width;
	     rect.bottom = height;
	     styleGalleryClass.Preview(pSymbol, hdc.ToInt32(), ref rect);
	     gc.ReleaseHdc(hdc);
	     gc.Dispose();
	     return img;
    }
    return null;
}



版权声明:本文为qq_36047595原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。