ESRI BBS GIS大讲堂首发,转载请注明出处http://bbs.esrichina-bj.cn/ESRI/thread-46577-1-1.html
本章是ArcGIS Engine基础开发教程的第三章,主要给大家大致讲解了,地图和地图布局的相关对象。这些对象非常重要,如果这些基本对象都不熟悉就开始搞ArcGIS Engine开发是不科学的也走不远的。
3地图和地图布局
3.1地图
3.1.1Map对象
Map对象是ArcGIS Engine的主要对象,本章将给大家介绍地图组成结构,如何创建地图,如何对组成地图的对象进行操作,在介绍这些内容时尽量结合ArcMap学习效果会更好。
图1
图2
/// <summary> ///添加临时元素到地图窗口上 ///</summary> ///<param name="pMapCtrl">地图控件</param> ///<param name="pEle">单个元素</param> ///<param name="pEleColl">元素集合</param> public static void AddTempElement(AxMapControl pMapCtrl, IElement pEle, IElementCollection pEleColl) { try { IMap pMap = pMapCtrl.Map; IGraphicsContainer pGCs = pMap as IGraphicsContainer; if (pEle != null) pGCs.AddElement(pEle, 0); if (pEleColl != null) if (pEleColl.Count > 0) pGCs.AddElements(pEleColl, 0); IActiveView pAV = (IActiveView)pMap; //需要刷新才能即时显示 pAV.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pAV.Extent); } catch (Exception Err) { MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
图3
/// /// <summary> /// 获取要素图层符合条件获取选择集 /// </summary> /// <param name="pFeatureLayer">要素图层</param> /// <param name="WhereClause">过滤条件</param> /// <returns>返回选择集</returns> private IFeatureSelection SelectLayersFeatures(IFeatureLayer pFeatureLayer, string WhereClause) { IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection; if (pFeatureSelection == null) return null; IQueryFilter pQueryFilter = new QueryFilterClass(); pQueryFilter.WhereClause = WhereClause; pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false); return pFeatureSelection; }
IFeatureLayerDefinition接口定义了CreateSelectionLayer方法,可以将一个图层选择集中的要素转换为一个单独的要素图层。
3.1.4矢量图层操作实例
以下代码片段演示按行政区加载图层数据的功能,以此理解IFeatureLayerDefinition的CreateSelectionLayer方法的使用。
比方说整个国土资源部有某一类型专题数据有若干图层,每个图层数据的范围是整个中国,这时国土资源部开发一套系统可能有这个需求,每个省只能加载本省的数据。以下函数即为按按行政区范围创建行政区范围的图层。
比方说我想获取河南省的数据只需传入行政区图层中河南省图元的Geometry即可。另外如果如果遇到行政区层必须用esriSpatialRelEnum. esriSpatialRelContains这个参数,否则行政区这个图层就不能只获取河南这个省份,它会把河南省的周围省份,河北,湖北,安徽,陕西,山东,山西等省份的图元也添加创建到新图层。
/// <summary> /// 按行政区范围创建行政区范围的图层 /// </summary> /// <param name="pFeatureLayer">源数据图层</param> /// <param name="pGeometry">行政区范围</param> /// <param name="bXZQ">图层是否为行政区</param> /// <returns>新创建的图层</returns> private IFeatureLayer GetSelectionLayer(IFeatureLayer pFeatureLayer, IGeometry pGeometry,bool bXZQ) { try { if (pFeatureLayer != null && pGeometry != null) { IQueryFilter pQueryFilter; ISpatialFilter pSpatialFilter = new SpatialFilterClass(); IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection; pSpatialFilter.GeometryField = pFeatureLayer.FeatureClass.ShapeFieldName; pFeatureSelection.Clear(); if (!bXZQ) { pSpatialFilter.Geometry = pGeometry; pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pQueryFilter = pSpatialFilter; pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false); } else { pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; pQueryFilter = pSpatialFilter; if(pGeometry is IGeometryCollection) { for (int i = 0; i < (pGeometry as IGeometryCollection).GeometryCount; i++) { pSpatialFilter.Geometry = (pGeometry as IGeometryCollection).get_Geometry(i); pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false); } } } IFeatureLayerDefinition pFLDefinition = pFeatureLayer as IFeatureLayerDefinition; IFeatureLayer pNewFeatureLayer = pFLDefinition.CreateSelectionLayer(pFeatureLayer.Name ,true, null, null); pNewFeatureLayer.MaximumScale = pFeatureLayer.MaximumScale; pNewFeatureLayer.MinimumScale = pFeatureLayer.MinimumScale; pNewFeatureLayer.Selectable = pFeatureLayer.Selectable; pNewFeatureLayer.Visible = pFeatureLayer.Visible; pNewFeatureLayer.ScaleSymbols = pFeatureLayer.ScaleSymbols; return pNewFeatureLayer; } else { return null; } } catch (Exception Err) { MessageBox.Show(Err.Message, "获取SelectionLayer", MessageBoxButtons.OK, MessageBoxIcon.Information); return null; } }
IIdentify接口定义了获得要素图层单个要素的属性的
ILayerFields接口可以直接获取一个要素图层的要素类字段集合
ILayerEffects接口用来设置一个要素图层的透明度,对比度,对比度。以下代码片段演示如何设置要素图层特效:
/// <summary> /// 设置图层特效 /// </summary> /// <param name="pFeatureLayer">要素图层</param> /// <param name="brightness">亮度</param> /// <param name="contrast">对比度</param> /// <param name="transparency">透明度</param> private static void SetLayerEffects(IFeatureLayer pFeatureLayer, short brightness, short contrast, short transparency) { ILayerEffects pLayerEffect = pFeatureLayer as ILayerEffects; pLayerEffect.Brightness = brightness; pLayerEffect.Contrast = contrast; pLayerEffect.Transparency = transparency; }
3.2地图布局
3.2.1PageLayout对象
PageLayout用以显示地图数据,并通过对地图数据进行整饰以便对地图打印输出满足不同行业对GIS出图功能的需求。PageLayout和Map这两个对象看起来非常相似,它们都是视图对象,可以显示地图;也都是图形元素的容器,可以容纳图形元素(Graphics Element)。但是所能够保存的图形类型却是有差别的。PageLayout除了保存图形元素外,还可以保存诸如MapFrame的框架元素(Frame Element)。PageLayout控件上的Map对象被PageLayout的MapFrame对象所管理的。
PageLayout类主要实现了IPageLayout接口,它定义了用于修改页面版式(layout)的方法和属性。
IPageLayout的方法ZoomToWhole方法可以让PageLayout以最大尺寸显示;
IPageLayout的ZoomToPercent方法可以按照输入的比例显示;
IPageLayout的ZoomToWidth方法可以让视图显示的范围匹配控件对象的宽度。
IPageLayout的Page属性用以获取Page对象
IPageLayout的RulerSettings属性用以获取RulerSettings对象
IPageLayout的HorizontalSnapGuides和VerticalSnapGuides属性用以获取SnapGuides对象
如下图所示:
图4
/// <summary> /// 设置PageLayout上SnapGrid /// </summary> /// <param name="pPageLayout">PangeLayout对象</param> private void SetwSnapGridOnPageLayout(IPageLayout pPageLayout) { if(pPageLayout !=null) { ISnapGrid pSnapGrid=pPageLayout.SnapGrid; pSnapGrid.VerticalSpacing =2; pSnapGrid.HorizontalSpacing =2; pSnapGrid.IsVisible =true; IActiveView pActiveView=pPageLayout as IActiveView; pActiveView.Refresh(); } }
/// <summary> /// 向PageLayout上指定位置添加辅助线 /// </summary> /// <param name="pPageLayout">PageLayout对象</param> /// <param name="pPoistion">位置</param> /// <param name="bHorizontal">true为水平方向辅助线,False为垂直方向辅助线</param> private void AddGuideOnPageLayout(IPageLayout pPageLayout,double pPoistion,bool bHorizontal) { try { if(pPageLayout !=null) { ISnapGuides pSnapGuides=null; //如果是水平辅助线 if(bHorizontal) { pSnapGuides=pPageLayout.HorizontalSnapGuides; } //如果是垂直辅助线 else { pSnapGuides=pPageLayout.VerticalSnapGuides; } if(pSnapGuides!=null) { //向PageLayout上添加辅助线 pSnapGuides.AddGuide(pPoistion); } } } catch(Exception Err) { MessageBox.Show(Err.Message,"提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
图5
3.2.7MapGrid对象
MapGrid是布局视图中的一系列参考线和参考点用来帮助地图使用者快速地确定地图要素的位置如图7中的公里格网,MapGridBorder,MapGridLabel。MapGrid等。MapGrid对象由MapGrids来管理,一个MapGrids可以包含多个MapGrid对象。
图7
图8
图9
/// <summary> /// 为PageLayout对象添加格网对象 /// </summary> /// <param name="pPageLayout"></param> private void AddMeasuredGridToPageLayout(IPageLayout pPageLayout) { try { //获取MapFrame对象 IActiveView pAcitiveView= pPageLayout as IActiveView; IMap pMap = pAcitiveView.FocusMap; IGraphicsContainer pGraphicsContainer=pAcitiveView as IGraphicsContainer; IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pMap) as IMapFrame; IMapGrids pMapGrids = pMapFrame as IMapGrids; //创建一个MeasuredGrid对象 IMeasuredGrid pMeasureGrid = new MeasuredGridClass(); IMapGrid pMapGrid = pMeasureGrid as IMapGrid; pMeasureGrid.FixedOrigin = true; pMeasureGrid.Units = pMap.MapUnits; pMeasureGrid.XIntervalSize = 1000; pMeasureGrid.YIntervalSize = 1000; pMeasureGrid.XOrigin = -180; pMeasureGrid.YOrigin = -90; //设置MeasuredGride投影属性 IProjectedGrid pProGrid = pMeasureGrid as IProjectedGrid; pProGrid.SpatialReference = pMap.SpatialReference; pMapGrid.Name = "Measured Grid"; //创建一个CalibratedMapGridBorder对象并设置为pMapGrid的Border属性 ICalibratedMapGridBorder pCalibratedBorder = new CalibratedMapGridBorderClass(); pCalibratedBorder.BackgroundColor = GetRgbColor(255, 255, 255); pCalibratedBorder.ForegroundColor = GetRgbColor(0, 0, 0); pCalibratedBorder.BorderWidth = 0.1; pCalibratedBorder.Interval = 72; pCalibratedBorder.Alternating = true; pMapGrid.Border = pCalibratedBorder as IMapGridBorder; //创建一个FormattedGridLabel对象 IFormattedGridLabel pFormattedGridLabel = new FormattedGridLabelClass(); IGridLabel pGridLabel = pFormattedGridLabel as IGridLabel; stdole.StdFont pFont = new stdole.StdFont(); pFont.Name = "Arial"; pFont.Size = 6; pGridLabel.Font = pFont as stdole.IFontDisp; ; pGridLabel.Color = GetRgbColor(0, 0, 0); pGridLabel.LabelOffset = 4; pGridLabel.set_LabelAlignment(esriGridAxisEnum.esriGridAxisLeft, false); pGridLabel.set_LabelAlignment(esriGridAxisEnum.esriGridAxisRight, false); INumericFormat pNumericFormat = new NumericFormatClass(); pNumericFormat.AlignmentOption = esriNumericAlignmentEnum.esriAlignRight; pNumericFormat.RoundingOption = esriRoundingOptionEnum.esriRoundNumberOfSignificantDigits; pNumericFormat.RoundingValue = 0; pNumericFormat.ShowPlusSign = false; pNumericFormat.ZeroPad = true; pFormattedGridLabel.Format = pNumericFormat as INumberFormat; //设置pMapGrid的LabelFormat属性 pMapGrid.LabelFormat = pGridLabel; //添加格网 pMapGrids.AddMapGrid(pMapGrid); } catch(Exception Err) { MessageBox.Show(Err.Message,"提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
3.2.8MapSurround对象
MapSurround对象是与一个地图对象关联的用于修饰地图的辅助图形元素对象如图所示。它的形状或内容会随着Map属性的变化而自动改变。如Map视图范围改变后比例尺(ScaleBar)也会自动调整比例,比例尺文本(ScaleBarText)也会相应改变它的比例值。
MapSurround对象由MapSurroundFrame 对象管理,所有的MapSurround对象添加在布局视图上,每一个MapSurround对象可以通过IMap接口的MapSurrounds属性的索引值所获取。也可以通过IMap接口的MapSurroundCount来遍历布局视图上的所有MapSurround对象。
所有的MapSurround对象都实现IMapSurround接口,使用IMapSurround接口的Name属性可以获得MapSurround对象的名称,通过IMapSurround的FitToBound方法可以设置一个MapSurround对象的大小。
同时MapSurround类也实现了IMapSurroundEvents接口,可以用来触发MapSounrround相关事件如:AfterDraw,BeforeDraw,ContensChanged。
图10
下图是MapSurround对象模型
/// <summary> /// 为PageLayout对象添加图例对象 /// </summary> /// <param name="pPageLayout">PageLayout对象</param> /// <param name="pEnvelope">图例添加的位置</param> private void AddLegendToPageLayout(IPageLayout pPageLayout,IEnvelope pEnvelope) { try { IActiveView pActiveView=pPageLayout as IActiveView; IMap pMap = pActiveView.FocusMap; IGraphicsContainer pGraphicsContainer=pActiveView as IGraphicsContainer; IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pMap) as IMapFrame; UID pUID = new UID(); pUID.Value = "{7A3F91E4-B9E3-11d1-8756-0000F8751720}"; ISymbolBackground pSymbolBackground = new SymbolBackgroundClass(); IFillSymbol pFillSymbol = new SimpleFillSymbolClass(); ILineSymbol pLineSymbol = new SimpleLineSymbolClass(); pFillSymbol.Color = GetRgbColor(255, 255, 255); pLineSymbol.Color = GetRgbColor(255, 255, 255); pFillSymbol.Outline = pLineSymbol; pSymbolBackground.FillSymbol = pFillSymbol; IMapSurroundFrame pMapSurroundFrame = pMapFrame.CreateSurroundFrame(pUID, null); pMapSurroundFrame.Background = pSymbolBackground; IElement pElement = pMapSurroundFrame as IElement; pElement.Geometry = pEnvelope; IMapSurround pMapSurround = pMapSurroundFrame.MapSurround; ILegend pLegend = pMapSurround as ILegend; pLegend.ClearItems(); pLegend.Title = "图例"; ITextSymbol pTextSymbol = new TextSymbolClass(); pTextSymbol.Size = 10; pTextSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft; ILegendItem pLegendItem = null; for (int i = 0; i < pActiveView.FocusMap.LayerCount; i++) { ILayer pLayer = pActiveView.FocusMap.get_Layer(i); if (pLayer is IFeatureLayer) { IFeatureLayer pFLayer = pLayer as IFeatureLayer; IFeatureClass pFeatureClass = pFLayer.FeatureClass; if (pFeatureClass.FeatureType == esriFeatureType.esriFTAnnotation) { continue; } else { pLegendItem = new HorizontalLegendItemClass(); pLegendItem.Layer = pLayer; pLegendItem.Columns = 1; pLegendItem.ShowDescriptions = false; pLegendItem.ShowHeading = false; pLegendItem.ShowLabels = true; pLegendItem.LayerNameSymbol = pTextSymbol; pLegend.AddItem(pLegendItem); } } } } catch(Exception Err) { } }
结果如下图所示: