在地图符号化的时候经常要预览与选择Color Ramp Symbol,像ArcMap那样将ColorRamp符号放在Combobox现实既方便也实用,下面是实现原理与方法。
1、首先解决的是如何将图片放在Combobox中,要知道vs2005乃至vs2008的Combobox都不可以加载图片的,所以需要重写一个Combobox控件;
2、我们实现了将图片加载到Combobox中,下一步是如何将ColorRamp Symbol 这样的符号文件转换成图片,在查找ArcEngine实例代码中给我以启发,看下面一段代码:
//Get and set the style class
ISymbologyStyleClass symbologyStyleClass = axSymbologyControl1.GetStyleClass(axSymbologyControl1.StyleClass);
//Preview an image of the symbol
stdole.IPictureDisp picture = symbologyStyleClass.PreviewItem(m_styleGalleryItem, pictureBox1.Width, pictureBox1.Height);
System.Drawing.Image image = System.Drawing.Image.FromHbitmap(new System.IntPtr(picture.Handle));
pictureBox1.Image = image;
这样实现起来相对简单,我在网上看到好多自己写的直接是将ISymbol转换成Bmp的图片,代码如下:
private System.Drawing.Bitmap SymbolToBitmp(ESRI.ArcGIS.Display.ISymbol pSymbol, int iwidth, int iheight, int lGap)
{
///根据高宽创建图象
Bitmap bmp = new Bitmap(iwidth, iheight);
Graphics gImage = Graphics.FromImage(bmp);//转化成Graphics
gImage.Clear(Color.White); //清除底色,设置为白色
double dpi = gImage.DpiX; //
IEnvelope pEnvelope = new EnvelopeClass();//创建矩形范围
pEnvelope.PutCoords(0, 0, (double)bmp.Width, (double)bmp.Height);
//设置边界值
tagRECT deviceRect;
deviceRect.left = lGap;
deviceRect.right = bmp.Width - lGap;
deviceRect.top = lGap;
deviceRect.bottom = bmp.Height - lGap;
IDisplayTransformation pDisplayTransformation = new DisplayTransformationClass();
pDisplayTransformation.VisibleBounds = pEnvelope;
pDisplayTransformation.Bounds = pEnvelope;
pDisplayTransformation.set_DeviceFrame(ref deviceRect);
pDisplayTransformation.Resolution = dpi;
//IGeometry pGeo = CreateSymShape(pSymbol, pEnvelope);
IGeometry pGeo = CreateGeometryFromSymbol(pSymbol, pEnvelope);
System.IntPtr hdc = new IntPtr();
hdc = gImage.GetHdc();
pSymbol.SetupDC((int)hdc, pDisplayTransformation);
pSymbol.Draw(pGeo);
pSymbol.ResetDC();
gImage.ReleaseHdc(hdc);
gImage.Dispose();
return bmp;
}
private ESRI.ArcGIS.Geometry.IGeometry CreateGeometryFromSymbol(ISymbol sym, IEnvelope env)
{
if (sym is IMarkerSymbol)
{
IArea area = env as IArea;
return area.Centroid as IGeometry;
}
else if (sym is ILineSymbol || sym is ITextSymbol)
{
IPolyline line = new PolylineClass();
IPoint pt = new PointClass();
pt.PutCoords(env.LowerLeft.X, (env.LowerLeft.Y + env.UpperRight.Y) / 2);
line.FromPoint = pt;
pt = new PointClass();
pt.PutCoords(env.UpperRight.X, (env.LowerLeft.Y + env.UpperRight.Y) / 2);
line.ToPoint = pt;
return line as IGeometry;
}
else if (sym is IFillSymbol)
{
IPolygon polygon = new PolygonClass();
IPointCollection ptCol = (IPointCollection)polygon;
IPoint pt = new PointClass();
pt.PutCoords(env.LowerLeft.X, env.LowerLeft.Y);
ptCol.AddPoints(1, ref pt);
pt.PutCoords(env.UpperLeft.X, env.UpperLeft.Y);
ptCol.AddPoints(1, ref pt);
pt.PutCoords(env.UpperRight.X, env.UpperRight.Y);
ptCol.AddPoints(1, ref pt);
pt.PutCoords(env.LowerRight.X, env.LowerRight.Y);
ptCol.AddPoints(1, ref pt);
pt.PutCoords(env.LowerLeft.X, env.LowerLeft.Y);
ptCol.AddPoints(1, ref pt);
return polygon as IGeometry;
}
else
{
System.Windows.Forms.MessageBox.Show("找到一种特殊的符号!");
return null;
}
}
不能说这种方法不好,但是我是没试验成功,个人感觉太繁琐,它需要将每一个符号转化成图片,速度堪忧啊。
3、我们已经实现了imag加载到Combobox 又可以将Isymbol to Image,下面是如何获取 ColorRamp的符号了。获取符号无非是从符号库中读取符号,这里我使用了Engine提供的一个符号控件axSymbologyControl(这么好东东为啥不用),代码如下:
axSymbologyControl1.LoadStyleFile(Application.StartupPath + "//制图符号//底图符号.ServerStyle");
axSymbologyControl1.StyleClass = esriSymbologyStyleClass.esriStyleClassColorRamps;
这样所有符号库中的ColorRamp都被加载到axSymbologyControl1中了;我们可以从中获取我们想要的符号,好了说那么多了看一下全部代码和效果吧:
private void Form_SetRasterColor_Load(object sender, EventArgs e)
{
LoadSymbolProperty(mRLayer);
}
private void LoadSymbolProperty(IRasterLayer mRasterLayer)
{
IRasterStretchColorRampRenderer pStretchRen = (IRasterStretchColorRampRenderer)mRasterLayer.Renderer;
try
{
axSymbologyControl1.LoadStyleFile(Application.StartupPath + "//制图符号//底图符号.ServerStyle");
axSymbologyControl1.StyleClass = esriSymbologyStyleClass.esriStyleClassColorRamps;
ISymbologyStyleClass symbologyStyleClass = axSymbologyControl1.GetStyleClass(esriSymbologyStyleClass.esriStyleClassColorRamps);
//Create a new server style gallery item with its style set
IStyleGalleryItem styleGalleryItem = new ServerStyleGalleryItem();
styleGalleryItem.Item = pStretchRen.ColorRamp;
styleGalleryItem.Name = "mySymbol";
//Add the item to the style class and select it
symbologyStyleClass.AddItem(styleGalleryItem, 0);
symbologyStyleClass.SelectItem(0);
for (int i = 0; i < symbologyStyleClass.get_ItemCount(symbologyStyleClass.StyleCategory); i++)
{
stdole.IPictureDisp picture = symbologyStyleClass.PreviewItem(symbologyStyleClass.GetItem(i), cmb_symbol.Width, cmb_symbol.Height);
System.Drawing.Image image = System.Drawing.Image.FromHbitmap(newSystem.IntPtr(picture.Handle));
cmb_symbol.Items.Add(image);
}
if (cmb_symbol.Items.Count>0)
cmb_symbol.SelectedIndex = 0;
// pictureBox1.Image = SymbolToBitmp(axSymbologyControl1, pictureBox1.Width, pictureBox1.Height, 0);
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
------------------------------以上是符号加载-------------------------------------
private void btn_ssubmit_Click(object sender, EventArgs e)
{
SetRasterSymbol(mRLayer);
this.DialogResult = DialogResult.OK;
this.Close();
}
private void SetRasterSymbol(IRasterLayer mRasterLayer)
{
try
{
int symbol_index = cmb_symbol.SelectedIndex;//获取选择的序号
ISymbologyStyleClass symbologyStyleClass = axSymbologyControl1.GetStyleClass(esriSymbologyStyleClass.esriStyleClassColorRamps);
IStyleGalleryItem mStyleGalleryItem = symbologyStyleClass.GetItem(symbol_index);
IColorRamp colorramp_select = (IColorRamp)mStyleGalleryItem.Item;//获取选择的符号
//IColorRampSymbol mColorRampSymbol = new ColorRampSymbolClass();
//mColorRampSymbol = (IColorRampSymbol)symbol_select;
IRasterStretchColorRampRenderer pStretchRen = (IRasterStretchColorRampRenderer)mRasterLayer.Renderer;
pStretchRen.ColorRamp = colorramp_select;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}------------------------------以上是选择符号并实例化-----------------------------
Combobox 重载:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace EngineClass_ToolBoxs
{
// <summary>
/// 重写了Combobox类,使其在下拉框中显示Symbol颜色带的图片
/// </summary>
/// <remarks>
/// </remarks>
public partial class ComboboxSymbol : ComboBox
{
public ComboboxSymbol()
{
//以下两句是关键的;
DrawMode = DrawMode.OwnerDrawFixed;
DropDownStyle = ComboBoxStyle.DropDownList;
}
//重写函数
protected override void OnDrawItem(DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
try
{
//显示图片
Image image = (Image)Items[e.Index];
System.Drawing.Rectangle rect = e.Bounds;
e.Graphics.DrawImage(image, rect);
}
catch
{
}
finally
{
base.OnDrawItem(e);
}
}
}
}