ArcEngine之地图制图(从窗体创建、功能完善到界面美化)

    技术2022-08-31  78

    ArcEngine之地图制图

    说明窗体界面搭建MapControl与PageLayoutControl地图数据联动插入制图要素(标题文字、比例尺、指北针、图例)标题文字比例尺指北针图例保持ToolBarControl中的工具在数据和布局视图中均能够使用 窗体美化结果图

    说明

    在地图联动开发中,运行时会遇到这样一个问题,也没具体细致去看是为什么,不过能够**“继续”运行;对于插入制图要素部分,列出的代码是实现固定类型的制图要素(除文字标题外)和固定的位置**,你也可以丰富其功能,使制图要素能够在SymbolControl控件中选择;但有一个方法使得对MapControl有作用的ToolBarControl内的工具,也对PageLayoutControl控件有作用,能够调整制图要素的位置和其内地图的显示。对于打印输出功能,类型也有很多,最简单的是直接输出MapControl视口范围的图像;也可以是只输出整个地图范围的(应用较广,更符合实际的需求),这里我不做具体介绍。

    窗体界面搭建

    对于窗体界面的搭建,最基本的控件包括MenuStrip、ToolBarControl、TOCControl、TabControl容器、MapControl、PageLayoutControl、LicenseControl;可能刚接触的会遇到下面的问题,当仅仅把控件放到某个位置,运行后“最大化”会发现,控件位置不会随窗体界面的增大而布局合理,因为它属于绝对布局;解决方法有两种:①使用SplitContainer容器,将对应控件放到里面,再设置它们其“Dock”属性为Fill;②使用相对布局,对添加的某些必要控件其“Anchor”属性进行设置。其实Visual Studio中每个控件它都有自己的使用方法,控件类型也非常多,属性也很全,可以作为一个专题学习,充分掌握这些能够让你做出更加“炫”的窗体程序,也会显得你与众不同。

    MapControl与PageLayoutControl地图数据联动

    #region 地图联动 //地图复制函数 private void CopyToPageLayout() { IObjectCopy pObjectCopy = new ObjectCopyClass(); object copyFromMap = axMapControl1.Map; object copiedMap = pObjectCopy.Copy(copyFromMap);//复制地图到copiedMap中 object copyToMap = axPageLayoutControl1.ActiveView.FocusMap; pObjectCopy.Overwrite(copiedMap, ref copyToMap); //复制地图 axPageLayoutControl1.ActiveView.Refresh(); } //axMapControl 加载的数据发生变化时,需要联动 private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e) { CopyToPageLayout(); } //axMapControl 加载的数据发生重绘时,需要联动 private void axMapControl1_OnAfterScreenDraw(object sender, IMapControlEvents2_OnAfterScreenDrawEvent e) { IActiveView pActiveView = (IActiveView)axPageLayoutControl1.ActiveView.FocusMap; IDisplayTransformation displayTransformation = pActiveView.ScreenDisplay.DisplayTransformation; displayTransformation.VisibleBounds = axMapControl1.Extent; axPageLayoutControl1.ActiveView.Refresh(); CopyToPageLayout(); } //axMapControl 中的数据显示状况发生变化时,需要联动 private void axMapControl1_OnViewRefreshed(object sender, IMapControlEvents2_OnViewRefreshedEvent e) { axTOCControl1.Update(); CopyToPageLayout(); } #endregion

    插入制图要素(标题文字、比例尺、指北针、图例)

    标题文字

    再添加一个窗体,主要包括一个txtbox和botton控件,用于让用户填写地图图名,然后窗体间传参即可。

    #region 文字标题 private void 文字标题_Click(object sender, EventArgs e) { AddTitle addTitle = new AddTitle(); addTitle.ShowDialog(); string Title = addTitle.title; ITextElement textElement; ITextSymbol textSymbol; IColor color; IActiveView activeView = axPageLayoutControl1.PageLayout as IActiveView; IEnvelope envelope = new Envelope() as IEnvelope; envelope.PutCoords(7, 20, 15, 30); textElement = new TextElement() as ITextElement; IElement element = textElement as IElement; element.Geometry = envelope; textElement.Text = Title; textSymbol = new TextSymbol(); IRgbColor pColor = new RgbColor(); pColor.Red = 0; pColor.Green = 0; pColor.Blue = 0; color = pColor; textSymbol.Color = color; textSymbol.Size = 30; textElement.Symbol = textSymbol; IGraphicsContainer graphicsContainer = activeView as IGraphicsContainer; graphicsContainer.AddElement(element, 0); axPageLayoutControl1.ActiveView.Refresh(); } #endregion

    比例尺

    #region 比例尺 private void 比例尺ToolStripMenuItem_Click(object sender, EventArgs e) { IActiveView pActiveView = axPageLayoutControl1.PageLayout as IActiveView; IMap pMap = pActiveView.FocusMap as IMap; IGraphicsContainer pGraphicsContainer = pActiveView as IGraphicsContainer; IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pMap) as IMapFrame; pActiveView = axPageLayoutControl1.PageLayout as IActiveView; pMap = pActiveView.FocusMap as IMap; pGraphicsContainer = pActiveView as IGraphicsContainer; pMapFrame = pGraphicsContainer.FindFrame(pMap) as IMapFrame;//设置比例尺样式 IMapSurround pMapSurround; IScaleBar pScaleBar; pScaleBar = new ScaleLineClass(); pScaleBar.Units = pMap.MapUnits; pScaleBar.Divisions = 2; pScaleBar.Subdivisions = 4; pScaleBar.DivisionsBeforeZero = 0; pScaleBar.LabelPosition = esriVertPosEnum.esriBelow; pScaleBar.LabelGap = 3.6; pScaleBar.LabelFrequency = esriScaleBarFrequency.esriScaleBarDivisionsAndFirstMidpoint; pMapSurround = pScaleBar; pMapSurround.Name = "ScaleBar"; //定义UID UID uid = new UID(); uid.Value = "esriCarto.ScaleLine"; //定义MapSurroundFrame对象 IMapSurroundFrame pMapSurroundFrame = pMapFrame.CreateSurroundFrame(uid, null); pMapSurroundFrame.MapSurround = pMapSurround; //定义Envelope设置Element摆放的位置 IEnvelope pEnvelope = new EnvelopeClass(); //设置元素在pagelayout中的坐标位置,个人可调整 pEnvelope.PutCoords(2, 1.5, 10, 2.5); IElement pElement = pMapSurroundFrame as IElement; pElement.Geometry = pEnvelope; pGraphicsContainer.AddElement(pElement, 0); } #endregion

    指北针

    #region 指北针 private void 指北针ToolStripMenuItem_Click(object sender, EventArgs e) { InsertNorth(axPageLayoutControl1); } public static void InsertNorth(AxPageLayoutControl axPageLayout) { IElement pElement = axPageLayout.FindElementByName("MarkerNorthArrow"); if (pElement != null) { axPageLayout.ActiveView.GraphicsContainer.DeleteElement(pElement); //删除已经存在的图例 } IPageLayout pPageLayout = axPageLayout.PageLayout; IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer; IActiveView pActiveView = pPageLayout as IActiveView; UID pID = new UIDClass(); pID.Value = "esriCore.MarkerNorthArrow"; IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pActiveView.FocusMap) as IMapFrame; if (pMapFrame == null) return; IMapSurroundFrame pMapSurroundFrame = pMapFrame.CreateSurroundFrame(pID, null); if (pMapSurroundFrame == null) return; IEnvelope pEnv = new EnvelopeClass(); pEnv.PutCoords(16, 25, 31, 40); pElement = (IElement)pMapSurroundFrame; pElement.Geometry = pEnv; pMapSurroundFrame.MapSurround.Name = "MarkerNorthArrow"; INorthArrow pNorthArrow = pMapSurroundFrame.MapSurround as INorthArrow; pGraphicsContainer.AddElement(pElement, 0); axPageLayout.ActiveView.Refresh(); } #endregion

    图例

    private void 图例ToolStripMenuItem_Click(object sender, EventArgs e) { InsertLegend(axPageLayoutControl1); } public void InsertLegend(AxPageLayoutControl axPageLayout) { //Get the GraphicsContainer IGraphicsContainer graphicsContainer = axPageLayoutControl1.GraphicsContainer; //Get the MapFrame IMapFrame mapFrame = (IMapFrame)graphicsContainer.FindFrame(axPageLayoutControl1.ActiveView.FocusMap); if (mapFrame == null) return; //Create a legend UID uID = new UIDClass(); uID.Value = "esriCarto.Legend"; //Create a MapSurroundFrame from the MapFrame IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame(uID, null); if (mapSurroundFrame == null) return; if (mapSurroundFrame.MapSurround == null) return; //Set the name mapSurroundFrame.MapSurround.Name = "Legend"; //Envelope for the legend IEnvelope envelope = new EnvelopeClass(); envelope.PutCoords(16, 2, 19.4, 3.4); //Set the geometry of the MapSurroundFrame IElement element = (IElement)mapSurroundFrame; element.Geometry = envelope; //Add the legend to the PageLayout axPageLayoutControl1.AddElement(element, Type.Missing, Type.Missing, "Legend", 0); //Refresh the PageLayoutControl axPageLayoutControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } #endregion

    保持ToolBarControl中的工具在数据和布局视图中均能够使用

    所仅做上面那些,会发现使用起来用户体验感很差,首先是ToobarControl中的工具在PageLayout中已经失效,且pagelayout中数据的显示和制图要素的位置都无法移动。因此;在这里,在TabControl_SelectedIndexChanged事件中添加如下代码,实现ToolBarControl的**“伙伴”**改变

    private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { switch (tabControl1.SelectedIndex) { case 0: axToolbarControl1.SetBuddyControl(axMapControl1); break; case 1: axToolbarControl1.SetBuddyControl(axPageLayoutControl1); break; } }

    窗体美化

    做完了功能一定要记得给窗体化个妆、美个颜 通过将皮肤文件(.ssk),放置到工程文件中bin》debug文件,添加引用lrisSkin4,在窗体中添加skinEngine控件,然后在窗体初始化时将文件名添加进来即可(皮肤文件和引用可以网上下载)

    public Form1() { InitializeComponent(); this.skinEngine1 = new Sunisoft.IrisSkin.SkinEngine(((System.ComponentModel.Component)(this))); this.skinEngine1.SkinFile = Application.StartupPath + @"OneGreen.ssk"; }

    结果图

    Processed: 0.015, SQL: 9