1、前言
前面的博客介绍了在ArcEngine
中如何创建各类符号,但是回顾一下ArcMap
中的操作,你肯定会想:一个一个创建符号实在是太过麻烦,如果有一个符号选择器供我们使用就好了。这篇博客就来介绍一下如何创建一个如下图所示的点符号选择器。
2、符号样式文件
对于ArcEngine
来说,它是不能直接使用ArcMap
中的符号库的,它能使用的是一种后缀名为*.ServerStyle
的文件。以我的电脑为例,我将ArcGIS
安装在了C:\Program Files (x86)\
目录下,则ServerStyle
文件就在C:\Program Files (x86)\ArcGIS\Desktop10.2\Styles\
目录下,找到"C:\Program Files (x86)\ArcGIS\Desktop10.2\Styles\zh-CN\ESRI.ServerStyle"
,把它复制到工程的Debug目录下即可。
3、实现代码
3.1、主界面代码
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
namespace Win
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
axMapControl1.LoadMxFile(@"C:\Users\DSF\Desktop\data\无标题.mxd");
}
// axTOCControl1_OnMouseDown
private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e)
{
esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
IBasicMap pBasicMap = null;
ILayer pLayer = null;
object unk = null;
object data = null;
axTOCControl1.HitTest(e.x, e.y, ref item, ref pBasicMap, ref pLayer, ref unk, ref data);
// 弹出符号选择器
if (e.button == 1)
{
if (item == esriTOCControlItem.esriTOCControlItemLegendClass)
{
if (pLayer is IFeatureLayer)
{
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
if (pFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
{
ILegendGroup pLegendGroup = unk as ILegendGroup;
ILegendClass pLegendClass = pLegendGroup.get_Class((int)data);
frmMarkerSymbol frm = new frmMarkerSymbol(axMapControl1.Object as IMapControlDefault, pLayer, pLegendClass);
frm.ShowDialog();
}
}
}
}
}
}
}
3.2、符号选择器代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using stdole;
namespace Win
{
public partial class frmMarkerSymbol : Form
{
/// <summary>
/// 地图符号对象
/// </summary>
private IMapControlDefault m_mapControl;
private ILayer m_Layer;
private ILegendClass m_LegendClass;
private ISymbologyStyleClass m_SymbologyStyleClass;
/// <summary>
/// 符号属性集合
/// </summary>
private Dictionary<int, double> sizes;
private Dictionary<int, double> angles;
private Dictionary<int, Color> colors;
/// <summary>
/// 构造函数
/// </summary>
public frmMarkerSymbol(IMapControlDefault m_mapControl, ILayer m_Layer, ILegendClass m_LegendClass)
{
InitializeComponent();
// 初始化地图符号对象
this.m_mapControl = m_mapControl;
this.m_Layer = m_Layer;
this.m_LegendClass = m_LegendClass;
// 初始化符号属性集合
this.sizes = new Dictionary<int, double>();
this.angles = new Dictionary<int, double>();
this.colors = new Dictionary<int, Color>();
// 初始化符号控件
Init();
}
/// <summary>
/// 初始化控件
/// </summary>
private void Init()
{
axSymbologyControl1.LoadStyleFile(AppDomain.CurrentDomain.BaseDirectory + "ESRI.ServerStyle");
axSymbologyControl1.StyleClass = esriSymbologyStyleClass.esriStyleClassMarkerSymbols;
m_SymbologyStyleClass = axSymbologyControl1.GetStyleClass(axSymbologyControl1.StyleClass);
// 添加当前符号
IStyleGalleryItem pStyleGalleryItem = new ServerStyleGalleryItem();
pStyleGalleryItem.Name = "当前符号";
pStyleGalleryItem.Item = m_LegendClass.Symbol;
m_SymbologyStyleClass.AddItem(pStyleGalleryItem, 0);
// 符号属性集合
for (int i = 0; i < m_SymbologyStyleClass.get_ItemCount(); i++)
{
IStyleGalleryItem item = m_SymbologyStyleClass.GetItem(i);
IMarkerSymbol pMarkerSymbol = item.Item as IMarkerSymbol;
if (!sizes.ContainsKey(item.ID))
{
sizes.Add(item.ID, pMarkerSymbol.Size);
}
if (!angles.ContainsKey(item.ID))
{
angles.Add(item.ID, pMarkerSymbol.Angle);
}
if (!colors.ContainsKey(item.ID))
{
colors.Add(item.ID, ConvertToColor(pMarkerSymbol.Color));
}
}
m_SymbologyStyleClass.SelectItem(0);
}
/// <summary>
/// 双击选中符号
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axSymbologyControl1_OnDoubleClick(object sender, ISymbologyControlEvents_OnDoubleClickEvent e)
{
btnOk.PerformClick();
}
/// <summary>
/// 切换符号
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axSymbologyControl1_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e)
{
IStyleGalleryItem pStyleGalleryItem = e.styleGalleryItem as IStyleGalleryItem;
nudSize.Value = (decimal)sizes[pStyleGalleryItem.ID];
nudAngle.Value = (decimal)angles[pStyleGalleryItem.ID];
btnColor.BackColor = colors[pStyleGalleryItem.ID];
// 预览
IMarkerSymbol pMarkerSymbol = pStyleGalleryItem.Item as IMarkerSymbol;
pMarkerSymbol.Size = sizes[pStyleGalleryItem.ID];
pMarkerSymbol.Angle = angles[pStyleGalleryItem.ID];
pMarkerSymbol.Color = ConvertToRgbColor(colors[pStyleGalleryItem.ID]);
PriviewSymbol(pStyleGalleryItem);
}
/// <summary>
/// 切换颜色
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnColor_Click(object sender, EventArgs e)
{
ColorDialog colorDialog = new ColorDialog();
if (colorDialog.ShowDialog() == DialogResult.OK)
{
btnColor.BackColor = colorDialog.Color;
// 预览
IStyleGalleryItem pStyleGalleryItem = m_SymbologyStyleClass.GetSelectedItem();
IMarkerSymbol pMarkerSymbol = pStyleGalleryItem.Item as IMarkerSymbol;
pMarkerSymbol.Size = (double)nudSize.Value;
pMarkerSymbol.Angle = (double)nudAngle.Value;
pMarkerSymbol.Color = ConvertToRgbColor(btnColor.BackColor);
PriviewSymbol(pStyleGalleryItem);
}
}
/// <summary>
/// 切换尺寸
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nudSize_ValueChanged(object sender, EventArgs e)
{
// 预览
IStyleGalleryItem pStyleGalleryItem = m_SymbologyStyleClass.GetSelectedItem();
IMarkerSymbol pMarkerSymbol = pStyleGalleryItem.Item as IMarkerSymbol;
pMarkerSymbol.Size = (double)nudSize.Value;
pMarkerSymbol.Angle = (double)nudAngle.Value;
pMarkerSymbol.Color = ConvertToRgbColor(btnColor.BackColor);
PriviewSymbol(pStyleGalleryItem);
}
/// <summary>
/// 切换角度
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nudAngle_ValueChanged(object sender, EventArgs e)
{
// 预览
IStyleGalleryItem pStyleGalleryItem = m_SymbologyStyleClass.GetSelectedItem();
IMarkerSymbol pMarkerSymbol = pStyleGalleryItem.Item as IMarkerSymbol;
pMarkerSymbol.Size = (double)nudSize.Value;
pMarkerSymbol.Angle = (double)nudAngle.Value;
pMarkerSymbol.Color = ConvertToRgbColor(btnColor.BackColor);
PriviewSymbol(pStyleGalleryItem);
}
/// <summary>
/// 确定
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOk_Click(object sender, EventArgs e)
{
IGeoFeatureLayer pGeoFeatureLayer = m_Layer as IGeoFeatureLayer;
IFeatureRenderer pFeatureRenderer = pGeoFeatureLayer.Renderer;
ISimpleRenderer pSimpleRenderer = pFeatureRenderer as ISimpleRenderer;
pSimpleRenderer.Symbol = m_SymbologyStyleClass.GetSelectedItem().Item as ISymbol;
m_mapControl.Refresh();
this.Close();
}
/// <summary>
/// 取消
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
/// <summary>
/// Color转换为IColor
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
private IColor ConvertToRgbColor(Color color)
{
IColor pColor = new RgbColor();
pColor.RGB = color.R + color.G * 256 + color.B * 65536;
return pColor;
}
/// <summary>
/// IColor转换为Color
/// </summary>
/// <param name="pColor"></param>
/// <returns></returns>
private Color ConvertToColor(IColor pColor)
{
return ColorTranslator.FromOle(pColor.RGB);
}
/// <summary>
/// 预览符号
/// </summary>
private void PriviewSymbol(IStyleGalleryItem pStyleGalleryItem)
{
IPictureDisp pPictureDisp = m_SymbologyStyleClass.PreviewItem(pStyleGalleryItem, picMarkerSymbol.Width, picMarkerSymbol.Height);
Image priviewImage = Image.FromHbitmap(new IntPtr(pPictureDisp.Handle));
picMarkerSymbol.Image = priviewImage;
}
}
}
运行结果如下图所示: