1、GIS应用开发 Developing GIS Applications with ArcObjects using C#.NET 江西省研究生优质课程主讲:兰小机 GIS博士、教授Email : QQ :305333315课件: ftp:/218.87.136.94/,兰小机简历,主要经历 1988年7月毕业于南方冶金学院工程测量专业,获学士学位,并留校任教 1994年6月毕业于武汉测绘科技大学工程测量专业,获硕士学位,回校任教 2005年6月毕业于南京师范大学地图学与地理信息系统专业,获理学博士学位,回校任教 主要研究方向 GML空间数据挖掘 GML空间数据库理论与GMLGIS 空间数据集
2、成与共享 GIS应用开发,科研项目,国家自然科学基金项目-面向GML的时空关联规则及序列模式挖掘研究(编号:40971234) ,35万元,主持 国家自然科学基金项目-本原GML空间数据库理论及GMLGIS与传统GIS集成研究(编号:40761017) ,16万元,主持 国家自然科学基金项目 - GML空间数据存储索引机制研究(编号:40401045) ,26万元,排名第二 地理信息科学江苏省重点实验室开发基金项目 -面向对象的GML空间数据库及其应用研究(编号:JK20050302) ,5万元主持 江西省教育厅科技项目GML空间数据库理论及GMLGIS研究,1万元,主持 萍乡市基础地理信息系
3、统研究与开发,22万元,主持 城市公众地理信息服务系统研究与开发,10万元,主持,教材及参考材料,教材: 基于ArcObjects与C#.NET的GIS应用开发,兰小机等编著,冶金工业出版社,2011年12月 最新课件 参考材料: ArcObjects SDK 10 Microsoft .NET Framework http:/ http:/ ArcGIS 开发工具包中的文档,包括ArcGIS开发帮助、组件帮助、对象模型图和示例,Chap.6 空间数据的可视化表达 (5学时),本章内容: Color对象 Symbol对象 使用Style/ServerStyle对象与符号化控件 制作专题图 制图
4、表现 地图标注,ArcMap中空间数据符号化方法,普通的符号化方法 单一符号(Single Symbol) 分类符号(Category Symbol)Unique Values Renderer 分级符号(Graduated Symbol) 分级色彩(Graduated Color) 比例符号(Proportional Symbol) 点值符号(Dot density) 组合符号(Multivariate Symbol) 统计图形(Statistical Charts) 制图表现(Representarion) (9.2新增功能),空间数据符号化主要元素 符号(对象) 色彩(对象) 着色(对象
5、) 符号(对象)着色(对象) IGeoFeatureLayer.Renderer 用于要素图层的符号化,符号化信息保存在要素图层中。,6.1 颜色对象,颜色(Color)是所有符号和地图元素的基本属性之一。ArcObjects提供了多种颜色模型: RGB(红色、绿色、蓝色)颜色模型:RGBColor HSV(色调、饱和度、亮度)颜色模型:HSVColor CMYK(青色、洋红色、黄色、黑色)颜色模型:CmykColor 灰度颜色:GrayColor CIELAB颜色(在ArcObjects中使用,与设备无关) 色带(ColorRamp),RGB模型,CMYK模型,HSV模型,hue : 0-3
6、60 saturation : 0-100 value :0-100,6.1.1 Color对象,Color对象是一个抽象类,它有5个颜色子类,即CmykColor、RGBColor、HSVColor、HLSColor和GrayColor,它们可以使用IColor接口定义的方法设置颜色对象的基本属性。 IColor.RGB属性会返回一个LONG数值,而不是RGB模型需要的R、G、B上的三个值,如白色的 RGB属性返回值为16777215,而不是用户需要的255、255、255三个值。如果采用ArcObjects的颜色选择对话框选取一个颜色后使用,程序员就必须使用 RGB值的写法。,下面是两种数
7、值方式互相转换的函数。 RGB值转换为LONG值 private long RGBToLong(int Red, int Green ,int Blue ) return Red + (0x100 * Green) + (0x10000 * Blue); LONG值转换为RGB值 private short LongtoRGB(long RGBlong) short pbyte = new short3 ;pbyte0 = (short) (RGBlong % 0x100) ;pbyte1 = (short) (RGBlong / 0x100) % 0x100);pbyte2 = (short
8、) (RGBlong / 0x10000) % 0x100);return pbyte; ,在ArcObjects中最常使用的两种颜色模型是RGB和HSV,RGB类实现IRgbColor接口,而HSV类则实现IHsvColor接口,两个接口分别定义了设置一个RGB对象和HSV对象需传递的值。,HSV模型颜色构造器,private IHsvColor HSVColor(int hue , int saturation , int val ) /定义一个IHSVColor类型对象IHsvColor pHsvColor = new HsvColorClass();/设置它的值pHsvColor.Hu
9、e = hue;pHsvColor.Saturation = saturation;pHsvColor.Value = val;return pHsvColor; ,RGB颜色构造器,private IRgbColor getRGB(int r,int g,int b) IRgbColor pColor = new RgbColorClass();pColor.Red = r;pColor.Green = g;pColor.Blue = b;return pColor; ,6.1.2 颜色对话框,ArcObjects中提供了几种颜色对话框供程序员使用:颜色板对象 、颜色选择器对象和颜色浏览器对
10、象。,颜色板对象 Colorpalatte,如图所示。ColorPalette颜色板对象一共排列了120种颜色供用户使用。ColorPalette类实现了两个接口:IColorPalette和 ICustomColorPalette。,IColorPalette接口定义了 Color属性和 TrackPopupMenu方法,使用这个接口可以从对话框中获得一个颜色对象。下面是使用调色板对象取出一个颜色的例子: IColor pColor = new RgbColorClass();pColor.RGB = 255 ;/新建一个颜色板对象IColorPalette pPalette = new C
11、olorPaletteClass();/定义一个范围结构tagRECT pRect = new tagRECT() ; pRect.left =10;pRect.top =10; pPalette.TrackPopupMenu(ref pRect, pColor, false, 0);/获得新的颜色pColor = pPalette.Color;,颜色选择器对象,颜色选择器(ColorSelector)对象提供了另一种选择颜色的方法,不过这种选择方式在精确度上更高,用户可以点击对话框上方右边的小箭头,选择使用RGB或CMYK等多种模型,通过拖曳颜色带或者直接输入具体颜色值的方法返回颜色对象,如
12、图所示。,下面是一个使用颜色选择器对象获取颜色对象的代码段: /Set the initial color to be diaplyed when the dialog opensIColor pColor = new RgbColorClass();pColor.RGB = 255;IColorSelector pSelector = new ColorSelectorClass();pSelector.Color = pColor; / Display the dialogif ( pSelector.DoModal(0) )IColor pOutColor = pSelector.Col
13、or;,颜色浏览器对象,和颜色选择器,颜色浏览器(ColorBrowser)对象提供了更灵活的方法来获取颜色对象,即通过简单的鼠标点击,就可以获得颜色对象,如图所示。,下面是一个使用颜色浏览器对象对象获取颜色对象的代码段: IRgbColor pNewColor; IRgbColor pInitColor = new RgbColorClass();/ the dialog will open with red as a default.pInitColor.Red = 255;IColorBrowser pColorBrowser = new ColorBrowserClass();pCol
14、orBrowser.Color = pInitColor;bool bColorSet = pColorBrowser.DoModal(0);if (bColorSet) pNewColor = (IRgbColor) pColorBrowser.Color;,6.1.3 ColorRamp对象,制作地图专题图的过程中,需要的颜色常常不是一种,而是随机或有序产生的一个颜色带。如果某个着色对象需要100种颜色,程序员肯定不能逐个产生出来,而是可以使用ArcObjects提供的颜色带(ColorRamp)对象。 ColorRamp类的对象可以产生颜色带,这个类实现了IColorRamp,定义了一系
15、列颜色带的公共方法,如 Size(产生多少种颜色),Colors(颜色带 IEnumColor)。,下表是四种颜色带模型的例子。,AlgorithmicColorRamp颜色带,AlgorithmicColorRamp是通过起止颜色来确定多个在这两个颜色之间的色带。AlgorithmicColorRamp类实现了两个接口:IColorRamp和IAlgorithmicColorRamp,两个接口之间是接口继承关系,后者包含了前者所有的方法和属性。,RandomColorRamp颜色带,RandomColorRamp对象供程序员产生随机颜色带,RandomColorRamp也需要设定一个范围,但
16、是这个范围是HSV颜色模型的,颜色将在这个范围内随机出现。,6.2 Symbol对象,ArcObjects使用三种符号MarkerSymbol、 LineSymbol和FillSymbol来绘制地理要素或图形元素的几何形状。 此外还有两种特殊的符号:一种是TextSymbol用于文字标注;另一种是3D ChartSymbol,用于显示饼图等三维对象。 所有的符号类都实现了ISymbol和IMapLevel接口,前者定义了一个符号对象的基本属性和方法;后者定义的MapLevel属性可以确定符号的显示顺序。,6.2.1 MarkerSymbol对象,MarkerSymbol对象是用于修饰点对象的符
17、号,它拥有五个子类,其中不同的子类可以产生不同类型的点符号。所有的MarkerSymbol类都实现了IMarkerSymbol接口,这个接口定义了点状符号的公共方法和属性,如角度、颜色、大小和XY偏移量等。 点状符号还可以用于构建线、面符号。,SimpleMarkerSymbol实例,ISimpleMarkerSymbol pMarkerSymbol = new SimpleMarkerSymbolClass(); pMarkerSymbol.Style = esriSimpleMarkerStyle. esriSMSCross; pMarkerSymbol.Color = getRGB(60
18、,100,50); pMarkerSymbol.Angle = 60; pMarkerSymbol.Size = 6; pMarkerSymbol.Outline = true; pMarkerSymbol.OutlineSize = 2; pMarkerSymbol.OutlineColor = getRGB(166, 122, 166); IPoint pPoint = pMapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); object oMarkerSymbol = pMarkerSymb
19、ol; pMapControl.DrawShape(pPoint, ref oMarkerSymbol);,CharacterMarkerSymbol实例 MultiLayerMarkerSymbol实例,6.2.2 LineSymbol对象,LineSymbol对象是用于修饰线型几何对象的符号,ILineSymbol定义了两个公共属性,即Color和Width。 LineSymbol的子类有:,MarkerLineSymbol实例,private void DrawSelectedFeature(IPolyline polyline) IArrowMarkerSymbol arrowMark
20、er = new ArrowMarkerSymbolClass();arrowMarker.Color = getRGB(255, 255, 255); arrowMarker.Length = 10;arrowMarker.Width = 8;arrowMarker.Style = esriArrowMarkerStyle.esriAMSPlain;IMarkerLineSymbol markerLine = new MarkerLineSymbolClass();markerLine.MarkerSymbol = arrowMarker;markerLine.Color = getRGB(
21、0, 255, 255);,ILineProperties lineProperties = markerLine as ILineProperties;ITemplate template = new TemplateClass();template.AddPatternElement(30, 10);/A pattern element is a mark and a gap value, which is specified in points (approx 1/72 inch). template.Interval = 10;/Interval is the multiplier t
22、hat determines the width of the marks and gaps in a pattern element. Each mark and gap value is multiplied by the Interval when the line symbol is drawn. lineProperties.Template = template;DrawSymbol(markerLine as ISymbol, polyline, 5, 30);,private void DrawSymbol( ISymbol symbol, IGeometry geometry
23、, int flashCount, int interval) IScreenDisplay display = m_activeView.ScreenDisplay;display.StartDrawing (0, (short)esriScreenCache.esriNoScreenCache);display.SetSymbol(symbol); for (int i = 0; i flashCount; i+) switch (geometry.GeometryType) case esriGeometryType.esriGeometryPoint:display.DrawPoint
24、(geometry); break;,case esriGeometryType.esriGeometryMultipoint:display.DrawMultipoint(geometry); break;case esriGeometryType.esriGeometryPolyline:display.DrawPolyline(geometry); break;case esriGeometryType.esriGeometryPolygon:display.DrawPolygon(geometry); break;default: break;System.Threading.Thre
25、ad.Sleep(interval);display.FinishDrawing();,SimpleLineSymbol实例 HashLineSymbol实例 MarkerLineSymbol实例,6.2.3 FillSymbol对象,FillSymbol是用来修饰如多边形等具有面积的几何形体的符号对象,它实现了IFillSymbol,这个接口定义了两个属性Color和OutLine,以满足所有类型的FillSymbol对象的公共属性设置。 IFillSymbol:Color可以设置填充符号的基本颜色,当然如果不设置这个属性,填充对象也是有默认颜色的,如GradientFillSymbol是蓝
26、色,LineFillSymbol是中度灰色,其他的填充对象都是黑色。 IFillSymbol:OutLine属性可以设置填充符号的外边框,这个外边框是一个线对象,因此使用ILineSymbol对象修饰,在默认情况下它是一个Solid类型的简单线符号。,6.2.4 TextSymbol对象,TextSymbol对象是用于修饰文字元素的,文字元素在要素标注等方面很有用处。 TextSymbol符号最重要的设置对象是它的字符,它实现了三个主要的接口来设置字符:ITextSymbol 、 ISimpleTextSymbol 和 IFormattedTextSymbol 。,ITextSymbol接口,
27、ITextSymbol接口是定义文本字符样式的主要接口,它定义的ITextSymbol:Font属性是产生一个TextSymbol符号的关键。程序员可以使用IFontDisp接口来设置字体的大小和是否是粗体、倾斜等属性。 使用ITextSymbol接口还可以定义TextSymbol对象的颜色、角度、水平排列方式、垂直排列方式和文本等内容。,ISimpleTextSymbol接口,TextSymbol类实现ISimpleTextSymbol接口来设置它的一些简单属性,如XOffset和YOffset可以用于设置字符的偏移量,它还定义了一个重要的属性TextPath,这个属性要传入一个ITextP
28、ath对象。,IFormattedTextSymbol接口,IFormattedTextSymbol.ShallowColor设置阴影颜色 IFormattedTextSymbol.ShapeXOffset和ShapeYOffset用于设置字体在X方向和Y方向上的偏移值。 IFormattedTextSymbol.CharacterSpacing和IFormattedTextSymbol.CharterWidth用于设置文本符号中单个字符之间的空隙和字符的宽度等属性。,6.2.5 3DChartSymbol对象,3DChartSymbol是一个抽象类,它拥有三个子类:BarChartSymbo
29、l、PieChartSymbol和StackedChartSymbol,都实现了IChartSymbol;它们本质上是一种Marker符号。 IChartSymbol接口定义了2个属性:IChartSymbol:MaxValue值是新建一个3DChartSymbol对象后必须设置的属性,其取值为多个字段值中的最大值。IChartSymbol:Value属性-The value at the index position.,ISymbolArray :用于管理ChartSymbol中的多个符号。,BarChartSymbol是最常用的三维着色符号,它使用不同类型的柱子来代表一个要素类中不同的属性
30、,而柱子的高度取决于属性值的大小。这个对象支持的是IBarChartSymbol接口。 IBarChartSymbol:VerticalBars属性用于确定使用的柱子(Bar)是水平排列还是垂直排列;柱的宽度和柱之间的空隙可以通过Width和Spacing属性来调节,当然,它们也可以使用IMarkerSymbol:Size方法进行设置。,ArcObjects可以使用IBarChartSymbol:Axes属性来设置每根Bar的轴线,轴线是一个ILineSymbol对象,当然如果要这个轴线能够显示,还必须设置ShowAxes为True才行。,PieChartSymbol符号进行着色的方法是使用一
31、个饼图来显示要素类的不同属性,不同的属性按照它们的数值大小占有一个饼图中的不同比例的扇形区域。 它默认实现的是IPieChartSymbol接口,这个接口定义了3个属性,用于设置Pie的外观。 IPieChartSymbol:ClockWise属性用于确定饼图中颜色的方向。如果ClockWise为True的时候,饼图中的颜色块呈顺时针方向分布。当IPieChartSymbol:UseOutline为True的时候,饼图的外框可以设置外框线;外框线使用IPieChartSymbol:Outline设置,它是一个ILineSymbol对象。,StackedChartSymbol也是ChartRen
32、derer对象进行着色时最常用的符号,它使用的柱 (StackedBar)是堆垒而成的。这个对象支持的接口是IStackedChartSymbol,用于设置StackedChartSymbol的外观。 IStackedChartSymbol:Width属性用于设置柱的宽度,而Outline和UseOutline用于设置符号的外框线。 当Fixed属性为False时,ChartRenderer对象的每一个stackedbar的尺寸会依据每个要素的属性来计算。如果它为True的时候,则StackedBar的长度是一样的。,6.3 使用Style/ServerStyle对象与符号化控件,样式文件中保
33、存了用于空间数据符号化的符号和地图元素,在ArcGIS安装目录Styles文件夹中寻找到ESRI带的所有Style/ServerStyle文件。 ArcMap程序最常使用的符号和地图元素都保存在ESRI.style文件中。 Styles文件夹中也有其他的 style文件,如 Weather.style、Petrolenum.style等,这些样式是为了满足不同行业的需求而制作的,使用时它们都需要被引入到ArcMap中。,ArcGIS桌面的安装目录 C:Program FilesArcGISDesktop10.0Styles下包含了内置的Style/ServerStyle的文件。 ArcGIS
34、Engine的安装目录 C:Program FilesArcGISEngine10.0Styles下包含了内置的ServerStyle的文件。 样式文件中对象组织层次: style gallery class (22个) Categories style gallery item,StyleGallery(仅适用于ArcGIS Desktop )或ServerStyleGallery (适用于ArcGIS Engine, ArcGIS Desktop 和ArcGIS Server ) -样式库,通过这个对象程序员可以将Style(或ServerStyle)文件中的样式取出来供系统使用。 Sty
35、leGallery/ ServerStyleGallery类默认实现IStyleGallery接口 StyleGallery/ ServerStyleGallery对象还实现了IStyleGalleryStorage接口,这个接口提供了在Stylegallery对象中获得一个Style文件引用的方法,它也提供了方法让程序员能够添加或删除Style文件。,6.3.1 StyleGallery与ServerStyleGallery对象,public IEnumStyleGalleryItem get_Items ( string className, string styleSet, string
36、 Category ); IEnumStyleGalleryItem pEnumStyleGalleryItem = pStyleGallery.get_Items(“Scale Bars“, “C:Program FilesArcGISStylesesri.style“, “hollowscalebar“); 如果要获得className下所有Category 中的样式条目,将Category 设置为”,引号中间没空格。 StyleGalleryltem对象代表了一个具体的样式条目,它包含着一个地图元素或符号以及一些相关信息,其类实现了IStyleGalleryltem接口。IStyleGa
37、lleryItem:Category属性确定条目在样式类中的类别,而Item属性是一个object类型对象,它要么是一个符号,要么是一个元素。,应用实例-字段值与符号匹配符号化,问题背景: 地形图图式规定:不同类型的地理要素需要用不同的符号进行可视化 地图符号库:符号编码对应 地理要素:有编码 实现功能:地理要素根据编码字段的取值,使用符号库中对应的符号进行可视化,地理要素编码规则:,符号按中类管理,实现界面,初始化工作: 从缺省目录中,将所有*.style、*.ServerStyle文件加入到样式下拉列表框中; 加载图层到图层下拉列表框中; 主要事件响应: 样式下拉列表框 图层下拉列表框 符
38、号化字段下拉列表框,主窗体“字段值与符号匹配符号化”菜单的Click事件 private void menuMatchFieldValue2Symbol_Click(object sender, EventArgs e)IHookHelper hookhelper = new HookHelperClass();hookhelper.Hook = m_mapControl.Object;MatchFieldValue2Symbol symForm = new MatchFieldValue2Symbol(hookhelper); symForm.Show( this as System.Win
39、dows.Forms.IWin32Window);,或 private void menuMatchFieldValue2Symbol_Click(object sender, EventArgs e) ICommand command = new Symbology.MatchFieldValue2SymbolCmd();command.OnCreate(axMapControl1.Object);command.OnClick(); MatchFieldValue2SymbolCmd命令的Click事件 public override void OnCreate(object hook)
40、if (hook = null) return; m_hookHelper = new HookHelperClass();m_hookHelper.Hook = hook; public override void OnClick() if (m_hookHelper = null) return;if (m_hookHelper.FocusMap.LayerCount 0) MatchFieldValue2Symbol symbol = new MatchFieldValue2Symbol (m_hookHelper);symbol.Show (m_hookHelper as System
41、.Windows.Forms.IWin32Window); ,MatchFieldValue2Symbol,namespace Symbology public partial class MatchFieldValue2Symbol : Formpublic MatchFieldValue2Symbol (IHookHelper hookHelper) InitializeComponent();m_hookHelper = hookHelper;m_activeView = m_hookHelper.ActiveView;m_map = m_hookHelper.FocusMap;,pri
42、vate void MatchFieldValue2Symbol_Load(object sender, EventArgs e) /Get the ArcGIS install locationstring sInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path;stylesPath = sInstall + “Styles“;cbxStyles.Items.Clear();cbxStylesAddItems(stylesPath);cbxStyles.Text = defaultStyle;if (m_map.LayerCount
43、!= 0)layer2Symbolize = m_map.get_Layer(0) as IFeatureLayer;cbxLayersAddItems();rdoAllLayers.Checked = true;,private void cbxStylesAddItems (string path) string serverstyleFiles = System.IO.Directory.GetFiles(stylesPath, “*.serverstyle“, SearchOption.AllDirectories);/ string styleFiles = System.IO.Di
44、rectory.GetFiles(stylesPath, “*.style“, SearchOption.AllDirectories);cbxStylesAddItems (serverstyleFiles);cbxStylesAddItems (styleFiles); private void cbxStylesAddItems( string files) if (files.GetLength(0) = 0) return;foreach (string file in files) cbxStyles.Items.Add(file);if (file.ToLower().Conta
45、ins(“PXFGIS.ServerStyle“.ToLower() defaultStyle = file; ,IStyleGallery styleGallery = null; private void cbxStyles_SelectedIndexChanged(object sender, EventArgs e) if (cbxStyles.SelectedItem = null) return;stylesPath = cbxStyles.SelectedItem.ToString();styleFileExt = System.IO.Path.GetExtension(styl
46、esPath).ToLower();if (styleFileExt = “.serverstyle“) styleGallery = new ServerStyleGalleryClass();styleGallery.ImportStyle(stylesPath); if (styleFileExt = “.style“) styleGallery = new StyleGalleryClass();styleGallery.LoadStyle(stylesPath, “); IStyleGalleryStorage styleStorage = styleGallery as IStyl
47、eGalleryStorage;styleStorage.TargetFile = stylesPath;,private void btnSymbolize_Click(object sender, EventArgs e)if (processMode = “AllLayers“)RendererAllLayers();if (processMode = “OneLayer“)RendererOneLayer(layer2Symbolize);m_activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, m_a
48、ctiveView.Extent);,private void RendererOneLayer(IFeatureLayer featureLayer) if (featureLayer = null) return;IGeoFeatureLayer pGeoFeatureL = (IGeoFeatureLayer)featureLayer;IFeatureClass featureClass = pGeoFeatureL.FeatureClass;/找出rendererField在字段中的编号int lfieldNumber = featureClass.FindField(strRendererField);if (lfieldNumber = -1) MessageBox.Show(“Cant find field called “ + strRendererField); return; IUniqueValueRenderer pUniqueValueR = CreateRenderer(featureClass);if (pUniqueValueR = null) return;pGeoFeatureL.Renderer = (IFeatureRenderer)pUniqueValueR; ,