如有插件定制需求或技術交流,歡迎聯系QQ 975601416
寫完了自己瞅了一眼都不想看,希望有需要的你能看懂。
先擺一張效果圖:
下面進入主題,本篇先講一下地圖布局中的對象,正文中會對一些關鍵詞用英文補充說明一下,這可不是作者在顯擺,了解下功能的英文表述對查詢幫助是很有幫助的。
直達鏈接:
PageLayout 頁面布局視圖,元素的容器
Page 版面,用於控制打印紙張
IElement接口 頁面元素
IFrameElement接口 框架元素,圖框、外圖框即此
MapFrame 地圖(map)的容器
FrameElement 地圖外框
MapSurroundFrame 用於管理地圖周邊元素(MapSurround,比例尺、指北針、圖例等)
ITextElement 標題等文字元素
先介紹一下主要對象類型——容器PageLayout與存放在容器中的Element元素。
ArcGis數據框有兩個視圖,“數據視圖”(DataView)與“布局視圖”(LayoutView)。制圖是在“布局視圖”里操作,在ArcObject里進行圖框整飾就是操作“PageLayout”對象。
“PageLayout”對象實現了IGraphicsContainer接口,顧名思義,該接口提供了容器,用以存放、管理graphic elements。通過AddElement方法可以將元素(IElement)放入PageLayout,通過DeleteElement方法可以刪除元素。
1 //PageLayout作為容器 2 IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer; 3 //IElement類型元素放入PageLayout,注意第二參zeorder固定為0(10.1,作者沒有研究高版本API是否有改動)。 4 pGraphicsContainer.AddElement(element,0); 5 //刪除元素,注意這個element是程序運行已經存在內存中的,放入PageLayout的對象 6 pGraphicsContainer.DeleteElement(element);
打印紙張的版面控制。
//單位,一般用厘米 pPageLayout.Page.Units = esriUnits.esriCentimeters; //傳入double類型值,設置頁面長、寬 pPageLayout.Page.PutCustomSize(width, height); //讀取當前版面的長寬值 double width; double height; pPageLayout.Page.QuerySize(out width, out height);
在 ArcGIS 中顯示在視圖上的數據有兩類:一類是地理要素數據,包括矢量要素數據、柵格數據、 Tin 等表面數據等,存儲在 Geodatabase 或數據文件(如shapefile)中,它們是用於 GIS 分析制圖的源數據;另一類是元素(Element),元素是一個地圖除去要素數據外的部分,即在一幅地圖中,除了地理數據外,其余的對象全部都是元素。
Element對象是一個龐大復雜的對象集合,它分為圖形元素(GraphicElement)和框架元素(Frame Element)。圖形元素主要包括 TextElement、 MarkerElement、 LineElement、 FillShapeElement、GroupElement 、 PictureElement 等 。 框 架 元 素 主 要 包 括 MapFrame 、MapSurroundFrame、 Table Frames 等。 這些元素都實現了IElement接口。
地圖圖框整飾的幾個基本元素有圖框(Frame)、標題(Title)、比例尺(Scale)、圖例(Legend)、指北針(NorthArrow)、其他輔助要素(底部文字等)。
pageLayout中用於存放地圖的MapFrame實現了IMapFrame接口,該接口繼承自IFrameElement接口,外框線可以使用FrameElement對象實現。
圖框細分應該會有內圖框、外圖框。
MapFrame是一個展示、存放Map圖層要素(layers)的地方,直接切換到“布局視圖”就可以看到它,內圖框是MapFrame的邊框。
內框MapFrame與PageLayout.Page的距離(上、下、側)需要給定。圖框肯定要從紙張邊緣往里縮一定距離才是。
//根據與Page邊的距離確定一個Envelpoe,通過它設置地圖框架MapFrame的位置 IFrameElement pFrameElement = pGraphicsContainer.FindFrame(pActiveView.FocusMap);//pGraphicsContainer容器是什么?
IMapFrame pMapFrame = pFrameElement as IMapFrame;
IEnvelope pEnvelopeMapFrame = new EnvelopeClass();
pEnvelopeMapFrame.PutCoords(xmin, ymin, xmax, ymax);
IElement pElement = pFrameElement as IElement;
pElement.Geometry = pEnvelopeMapFrame;
外圖框只用來展示一個粗線框,其幾何圖形可以是MapFrame的Envelpoe外擴一定距離形成的一個Envelpoe(這里稱作pEnvelpoeOuter),將FrameElement的Geometry屬性設置為pEnvelpoeOuter,將FrameElement對象的邊框(Boder)的線型、寬度設置一下就做出來了。
//set Outer-border frame FrameElement frameElementOuter = new FrameElementClass(); IFrameElement pFrameElementOuter = frameElementOuter as IFrameElement; IElementProperties3 pElementProperties = pFrameElementOuter as IElementProperties3; pElementProperties.Name = "OuterBorder"; IEnvelope pEnvelpoeOuter = new EnvelopeClass(); pEnvelpoeOuter.PutCoords(xmin - 0.2, ymin - 0.2, xmax + 0.2, ymax + 0.2); frameElementOuter.Geometry = pEnvelpoeOuter; //set Outer-border line style ILineSymbol pLineSymbol = DisplayUtils.CartoLineSymbol(3.0, DisplayUtils.RGBColor(0, 0, 0)); ISymbolBorder pSymbolBorder = new SymbolBorderClass(); pSymbolBorder.LineSymbol = pLineSymbol; IFrameProperties pFramePropertiesOuter = pFrameElementOuter as IFrameProperties; pFramePropertiesOuter.Border = pSymbolBorder; return frameElementOuter;
MapSurroundFrame 地圖周邊元素,實現了IMapSurroundFrame接口,該接口同樣繼承自IFrameElement接口。
比例尺、圖例、指北針是MapFrame的MapSurround對象,比例尺、圖例是明顯的與MapFrame相關,是隨圖層信息動態變化的。
比例尺:采用文本型比例尺,uid.Value = "esriCarto.ScaleText"。根據MapFrame的Envelpoe與PageLayout的Page的相對位置確定其放置的。
圖例:uid.Value = "esriCarto.Legend"。根據MapFrame的Envelpoe確定其位置。
指北針: uid.Value = "esriCarto.MarkerNorthArrow"。根據MapFrame的Envelpoe確定其位置。其實質是一個字符,“運行”——輸入“charmap”可以打開“字符映射表”,選擇ESRI North字體,選擇對應的字形可以看到其16進制的CharacterIndex,使用科學計算器計算出10進制的值就可以在程序中使用了。
public IElement AddNorthArrow(IPageLayout pPageLayout, double distanceToInnerBorder, double size, int characterIndex) { IUID uid = new UIDClass(); uid.Value = "esriCarto.MarkerNorthArrow"; IActiveView pActiveView = pPageLayout as IActiveView; IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pActiveView.FocusMap) as IMapFrame; IMapSurroundFrame pMapSurroundFrame = pMapFrame.CreateSurroundFrame(uid as UID, null); pMapSurroundFrame.MapSurround.Name = "NorthArrow"; IMarkerNorthArrow pMarkerNorthArrow = pMapSurroundFrame.MapSurround as IMarkerNorthArrow; IMarkerSymbol pMarkerSymbol = pMarkerNorthArrow.MarkerSymbol; ICharacterMarkerSymbol pCharacterMarkerSymbol = pMarkerSymbol as ICharacterMarkerSymbol; pCharacterMarkerSymbol.CharacterIndex = characterIndex ; pCharacterMarkerSymbol.Size = size; pMarkerNorthArrow.MarkerSymbol = pCharacterMarkerSymbol; double xmin = pEnvelopeMapFrame.XMax - distanceToInnerBorder; double ymin = pEnvelopeMapFrame.YMax - distanceToInnerBorder; double xmax = pEnvelopeMapFrame.XMax - 1; double ymax = pEnvelopeMapFrame.YMax - 1; IEnvelope pEnvelope = new EnvelopeClass(); pEnvelope.PutCoords(xmin, ymin, xmax, ymax); IFillSymbol pFillSymbol = DisplayUtils.SimpleFillSymbol(esriSimpleFillStyle.esriSFSSolid, DisplayUtils.CartoLineSymbol(0, DisplayUtils.RGBColor()), DisplayUtils.RGBColor(255, 255, 255)); pMapSurroundFrame.Background = DisplayUtils.SymbolBackGRound(pFillSymbol ); IElement pNorthArrowElement = pMapSurroundFrame as IElement; pNorthArrowElement.Geometry = pEnvelope; return pNorthArrowElement; }
ITextElement 文字元素,用來設置標題與其他文字元素
標題:
根據MapFrame的Envelpoe與PageLayout.Page 的寬度(width)、高度(height)確定一個位於MapFrame上方且居中的Envelpoe(這里稱作TitleEnvelpoe)。創建一個TextElementClass,設置其樣式,然后將其Geometry屬性設置為TitleEnvelpoe就可以了。
public IElement AddTitle(IPageLayout pPageLayout, string title,string font,double size) { ITextElement pTextElement = new TextElementClass(); pTextElement.Text = title; pTextElement.Symbol = DisplayUtils.TextSymbol(font, size,esriTextHorizontalAlignment.esriTHACenter,esriTextVerticalAlignment.esriTVACenter); double width; double height; pPageLayout.Page.QuerySize(out width, out height); double xmin = 0; double ymin = pEnvelopeMapFrame.YMax; double xmax = width; double ymax = height; IEnvelope pEnvelope = new EnvelopeClass(); pEnvelope.PutCoords(xmin, ymin, xmax, ymax); IElement pElement = pTextElement as IElement; IElementProperties3 pElementProperties3 = pElement as IElementProperties3; pElementProperties3.Name = "Title"; pElement.Geometry = pEnvelope; return pElement; }
底部文字:
也是是根據MapFrame的Envelpoe與PageLayout.Page的相對位置,分別確定出位於MapFrame左下角、右下角的兩個Envelpoe,然后創建兩個TextElementClass,設置其樣式,分別塞到Envelpoe。