图层符号选择器的实现.docx
《图层符号选择器的实现.docx》由会员分享,可在线阅读,更多相关《图层符号选择器的实现.docx(19页珍藏版)》请在冰豆网上搜索。
图层符号选择器的实现
《ArcGISEngine+C#实例开发教程》第七讲图层符号选择器的实现1
时间:
2009-04-1803:
58:
46来源:
3SDN.Net作者:
3SDN原创点击量:
869
u版权声明:
《ArcGISEngine+C#实例开发教程》为3SDN()原创教程,作者闲云野鹤,版权所有。
禁止商业用途转载(如需请联系作者),非商业用途转载请注明出处并完整保留本声明。
u读者对象:
使用C#开发ArcGISEngine(以下简称AE)的初学者。
u预备知识:
了解AE基本体系,了解C#基本语法,了解VS2005的基本使用方法。
u预期学习效果:
进一步理解AE的体系结构与开发方法,掌握基本的GIS桌面应用程序的开发。
在上一讲中,我们实现了右键菜单(ContextMenu)的添加与实现,在最后我预留给下一讲的问题是TOCControl控件图层拖拽的实现。
后来发现此功能的实现异常简单,只要在TOCControl的属性页中,勾选“EnableLayerDragandDrop”即可。
教程Bug及优化方案1查看这里。
这一讲,我们要实现的是图层符号选择器,与ArcMap中的SymbolSelector的类似。
本讲较前几讲而言,些许有些复杂,不过只要仔细琢磨,认真操作,你就很容易实现如下所示的符号选择器。
因为本讲篇幅较长,故我将其分成两个阶段,本文是第一阶段。
图1
在AE开发中,符号选择器有两种实现方式。
一是在程序中直接调用ArcMap中的符号选择器,如下所示:
图2
二是自定义符号选择器,如图1所示。
由于第一种方式前提是必须安装ArcGISDesktop,其界面还是英文的,而对二次开发来说,大部分用户希望应该是中文界面。
因此开发人员通常选择第二种方式,本讲也着重讲解第二种方式。
通过对《ArcGISEngine+C#实例开发教程》前六讲的学习,我已经假定你已经基本熟悉C#语言和VS2005的操作,故在下面的教程中,我不准备说明每一步骤的具体操作方法,而只是说明操作步骤,以节省时间和篇幅。
本篇文章来源于3SDN转载请以链接形式注明出处网址:
1.直接调用ArcMap中的符号选择器
(1)添加ESRI.ArcGIS.DisplayUI的引用。
分别在解决方案管理器和代码中添加引用。
(2)添加TOCControl的Double_Click事件。
(3)实现TOCControl的Double_Click事件。
因为种方法不是本讲的重点,故不对代码进行分析,有兴趣的读者请自行理解或结合后面的内容理解。
代码如下:
privatevoidaxTOCControl1_OnDoubleClick(objectsender,ITOCControlEvents_OnDoubleClickEvente)
{
esriTOCControlItemtoccItem=esriTOCControlItem.esriTOCControlItemNone;
ILayeriLayer=null;
IBasicMapiBasicMap=null;
objectunk=null;
objectdata=null;
if(e.button==1)
{
axTOCControl1.HitTest(e.x,e.y,reftoccItem,refiBasicMap,refiLayer,refunk,
refdata);
System.Drawing.Pointpos=newSystem.Drawing.Point(e.x,e.y);
if(toccItem==esriTOCControlItem.esriTOCControlItemLegendClass)
{
ESRI.ArcGIS.Carto.ILegendClasspLC=newLegendClassClass();
ESRI.ArcGIS.Carto.ILegendGrouppLG=newLegendGroupClass();
if(unkisILegendGroup)
{
pLG=(ILegendGroup)unk;
}
pLC=pLG.get_Class((int)data);
ISymbolpSym;
pSym=pLC.Symbol;
ESRI.ArcGIS.DisplayUI.ISymbolSelectorpSS=new
ESRI.ArcGIS.DisplayUI.SymbolSelectorClass();
boolbOK=false;
pSS.AddSymbol(pSym);
bOK=pSS.SelectSymbol(0);
if(bOK)
{
pLC.Symbol=pSS.GetSymbolAt(0);
}
this.axMapControl1.ActiveView.Refresh();
this.axTOCControl1.Refresh();
}
}
}
(4)编译运行即可。
本篇文章来源于3SDN转载请以链接形式注明出处网址:
2.自定义符号选择器
AE9.2提供了SymbologyControl控件,极大的方便了图层符号选择器的制作。
本讲实现的符号选择器有如下功能。
用户双击TOCControl控件中图层的符号时,弹出选择符号对话框,对话框能够根据图层类型自动加载相应的符号,如点、线、面。
用户可以调整符号的颜色、线宽、角度等参数。
还可以打开自定义的符号文件(*.ServerStyle),加载更多的符号。
2.1新建符号选择器窗体
新建Winodws窗体,命名为SymbolSelectorFrm,修改窗体的Text属性为“选择符号”。
并添加SymboloryControl、PictureBox、Button、Label、NumericUpDown、GroupBox、ColorDialog、OpenFileDialog、ContextMenuStrip控件。
控件布局如下所示:
图3
2.2设置控件属性
设置相应控件的相关属性,如下表所示(空则不用修改):
控件Name属性Text属性其它
SymbologyControlaxSymbologyControl
PictureBoxptbPreview
LabellblColor颜色
LabellblSize大小
LabellblWidth线宽
LabellblAngle角度
LabellblOutlineColor外框颜色
NumericUpDownnudSize
NumericUpDownnudWidth
NumericUpDownnudAngle
ButtonbtnColor(设置为空)
ButtonbtnOutlineColor(设置为空)
ButtonbtnMoreSymbols更多符号
ButtonbtnOK确定DialogResult属性设为OK
ButtonbtnCancel取消
GroupBoxgroupBox1预览
GroupBoxgroupBox2设置
ColorDialogcolorDialog
OpenFileDialogopenFileDialog
Filter属性设置为:
Styles文件|*.ServerStyle
ContextMenuStripcontextMenuStripMoreSymbol
2.3添加引用
在解决方案资源管理器中添加ArcGISEngine的ESRI.ArcGIS.Geodatabase引用,在SymbolSelectorFrm.cs文件中添加如下引用代码:
usingESRI.ArcGIS.Carto;
usingESRI.ArcGIS.Display;
usingESRI.ArcGIS.esriSystem;
usingESRI.ArcGIS.SystemUI;
usingESRI.ArcGIS.Controls;
usingESRI.ArcGIS.Geodatabase;
本篇文章来源于3SDN转载请以链接形式注明出处网址:
2.4初始化
(1)添加SymbolSelectorFrm的全局变量,代码如下:
privateIStyleGalleryItempStyleGalleryItem;
privateILegendClasspLegendClass;
privateILayerpLayer;
publicISymbolpSymbol;
publicImagepSymbolImage;
(2)修改SymbolSelectorFrm的构造函数,传入图层和图例接口。
代码如下:
///
///构造函数,初始化全局变量
///
///TOC图例
///图层
publicSymbolSelectorFrm(ILegendClasstempLegendClass,ILayertempLayer)
{
InitializeComponent();
this.pLegendClass=tempLegendClass;
this.pLayer=tempLayer;
}
(3)添加SymbolControl的SymbologyStyleClass设置函数SetFeatureClassStyle(),代码如下:
///
///初始化SymbologyControl的StyleClass,图层如果已有符号,则把符号添加到SymbologyControl中的第一个符号,并选中
///
///
privatevoidSetFeatureClassStyle(esriSymbologyStyleClasssymbologyStyleClass)
{
this.axSymbologyControl.StyleClass=symbologyStyleClass;
ISymbologyStyleClasspSymbologyStyleClass=this.axSymbologyControl.GetStyleClass(symbologyStyleClass);
if(this.pLegendClass!
=null)
{
IStyleGalleryItemcurrentStyleGalleryItem=newServerStyleGalleryItem();
currentStyleGalleryItem.Name="当前符号";
currentStyleGalleryItem.Item=pLegendClass.Symbol;
pSymbologyStyleClass.AddItem(currentStyleGalleryItem,0);
this.pStyleGalleryItem=currentStyleGalleryItem;
}
pSymbologyStyleClass.SelectItem(0);
}
(4)添加注册表读取函数ReadRegistry(),此函数从注册表中读取ArcGIS的安装路径,代码如下:
///
///从注册表中取得指定软件的路径
///
///
///
privatestringReadRegistry(stringsKey)
{
//Openthesubkeyforreading
Microsoft.Win32.RegistryKeyrk=Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey,true);
if(rk==null)return"";
//Getthedatafromaspecifiediteminthekey.
return(string)rk.GetValue("InstallDir");
}
(5)添加SymbolSelectorFrm的Load事件。
根据图层类型为SymbologyControl导入相应的符号样式文件,如点、线、面,并设置控件的可视性。
代码如下:
privatevoidSymbolSelectorFrm_Load(objectsender,EventArgse)
{
//取得ArcGIS安装路径
stringsInstall=ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
//载入ESRI.ServerStyle文件到SymbologyControl
this.axSymbologyControl.LoadStyleFile(sInstall+"\\Styles\\ESRI.ServerStyle");
//确定图层的类型(点线面),设置好SymbologyControl的StyleClass,设置好各控件的可见性(visible)
IGeoFeatureLayerpGeoFeatureLayer=(IGeoFeatureLayer)pLayer;
switch(((IFeatureLayer)pLayer).FeatureClass.ShapeType)
{
caseESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols);
this.lblAngle.Visible=true;
this.nudAngle.Visible=true;
this.lblSize.Visible=true;
this.nudSize.Visible=true;
this.lblWidth.Visible=false;
this.nudWidth.Visible=false;
this.lblOutlineColor.Visible=false;
this.btnOutlineColor.Visible=false;
break;
caseESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);
this.lblAngle.Visible=false;
this.nudAngle.Visible=false;
this.lblSize.Visible=false;
this.nudSize.Visible=false;
this.lblWidth.Visible=true;
this.nudWidth.Visible=true;
this.lblOutlineColor.Visible=false;
this.btnOutlineColor.Visible=false;
break;
caseESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
this.lblAngle.Visible=false;
this.nudAngle.Visible=false;
this.lblSize.Visible=false;
this.nudSize.Visible=false;
this.lblWidth.Visible=true;
this.nudWidth.Visible=true;
this.lblOutlineColor.Visible=true;
this.btnOutlineColor.Visible=true;
break;
caseESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
this.lblAngle.Visible=false;
this.nudAngle.Visible=false;
this.lblSize.Visible=false;
this.nudSize.Visible=false;
this.lblWidth.Visible=true;
this.nudWidth.Visible=true;
this.lblOutlineColor.Visible=true;
this.btnOutlineColor.Visible=true;
break;
default:
this.Close();
break;
}
}
(6)双击确定按钮和取消按钮,分别添加如下代码:
///
///确定按钮
///
///
///
privatevoidbtnOK_Click(objectsender,EventArgse)
{
//取得选定的符号
this.pSymbol=(ISymbol)pStyleGalleryItem.Item;
//更新预览图像
this.pSymbolImage=this.ptbPreview.Image;
//关闭窗体
this.Close();
}
///
///取消按钮
///
///
///
privatevoidbtnCancel_Click(objectsender,EventArgse)
{
this.Close();
}
(7)为了操作上的方便,我们添加SymbologyControl的DoubleClick事件,当双击符号时同按下确定按钮一样,选定符号并关闭符号选择器窗体。
代码如下:
///
///双击符号同单击确定按钮,关闭符号选择器。
///
///
///
privatevoidaxSymbologyControl_OnDoubleClick(objectsender,ESRI.ArcGIS.Controls.ISymbologyControlEvents_OnDoubleClickEvente)
{
this.btnOK.PerformClick();
}
(8)再添加符号预览函数,当用户选定某一符号时,符号可以显示在PictureBox控件中,方便预览,函数代码如下:
///
///把选中并设置好的符号在picturebox控件中预览
///
privatevoidPreviewImage()
{
stdole.IPictureDisppicture=this.axSymbologyControl.GetStyleClass(this.axSymbologyControl.StyleClass).PreviewItem(pStyleGalleryItem,this.ptbPreview.Width,this.ptbPreview.Height);
System.Drawing.Imageimage=System.Drawing.Image.FromHbitmap(newSystem.IntPtr(picture.Handle));
this.ptbPreview.Image=image;
}
(9)当SymbologyControl的样式改变时,需要重新设置符号参数调整控件的可视性,故要添加SymbologyControl的OnStyleClassChanged事件,事件代码与Load事件类似,如下:
///
///当样式(Style)改变时,重新设置符号类型和控件的可视性
///
///
///
privatevoidaxSymbologyControl_OnStyleClassChanged(objectsender,ESRI.ArcGIS.Controls.ISymbologyControlEvents_OnStyleClassChangedEvente)
{
switch((esriSymbologyStyleClass)(e.symbologyStyleClass))
{
caseesriSymbologyStyleClass.esriStyleClassMarkerSymbols:
this.lblAngle.Visible=true;
this.nudAngle.Visible=true;
this.lblSize.Visible=true;
this.nudSize.Visible=true;
t