ArcEngine之地图制图
说明
在地图联动开发中,运行时会遇到这样一个问题,也没具体细致去看是为什么,不过能够**“继续”运行;对于插入制图要素部分,列出的代码是实现固定类型的制图要素(除文字标题外)和固定的位置**,你也可以丰富其功能,使制图要素能够在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";
}
结果图