在很多的ArcEngine教程和博客中都会提到使用IMapBookmarks、ISpatialBookmark和IAOIBookmark三个接口实现书签功能。但这种实现方式存在一个很大的问题,那就是重新运行窗体时,之前创建的书签无法保存,导致每次都得重新创建。为解决这个问题,我在这里介绍一种利用XML实现书签功能的方法。本文的示例代码已分享至云盘:
链接:https://pan.baidu.com/s/1ehUMX6JJskwB0xrCENCg_g
提取码:agbl
1、搭建主窗体
主窗体的搭建就不多介绍了,我这里搭建的主窗体如下图所示:
主窗体代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;
namespace WindowsFormsApplication1
{
public partial class FrmMain : Form
{
private FrmCreateBookmark frmCreateBookmark;
private FrmManageBookmarks frmManageBookmarks;
// 构造函数
public FrmMain()
{
InitializeComponent();
axMapControl1.AddShapeFile(Application.StartupPath + "\\数据", "data.shp");
}
// 创建书签
private void btnCreateBookmark_Click(object sender, EventArgs e)
{
frmCreateBookmark = new FrmCreateBookmark();
frmCreateBookmark.XMin = axMapControl1.ActiveView.Extent.XMin;
frmCreateBookmark.YMin = axMapControl1.ActiveView.Extent.YMin;
frmCreateBookmark.XMax = axMapControl1.ActiveView.Extent.XMax;
frmCreateBookmark.YMax = axMapControl1.ActiveView.Extent.YMax;
frmCreateBookmark.MapScale = axMapControl1.Map.MapScale;
frmCreateBookmark.ShowDialog();
}
// 管理书签
private void btnManageBookmarks_Click(object sender, EventArgs e)
{
if (frmManageBookmarks == null || frmManageBookmarks.IsDisposed)
{
frmManageBookmarks = new FrmManageBookmarks();
frmManageBookmarks.CurrentMapControl = axMapControl1.Object as IMapControlDefault;
frmManageBookmarks.Show();
}
else
{
frmManageBookmarks.Focus();
}
}
}
}
2、创建XML文件
在Debug目录下新建一个XML文件,我们待会儿把所有的书签信息都存到里面去,XML文件主要保存书签名称、左下角X、左下角Y、右上角X、右上角Y、地图比例尺等信息,其结构如下图所示:
3、创建书签
新建一个窗体文件,命名为FrmCreateBookmark,该窗体主要是让用户创建书签,如下图所示:
创建书签代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
namespace WindowsFormsApplication1
{
public partial class FrmCreateBookmark : Form
{
/// <summary>
/// 左下角X
/// </summary>
public double XMin { get; set; }
/// <summary>
/// 左下角Y
/// </summary>
public double YMin { get; set; }
/// <summary>
/// 右上角X
/// </summary>
public double XMax { get; set; }
/// <summary>
/// 右上角Y
/// </summary>
public double YMax { get; set; }
/// <summary>
/// 比例尺
/// </summary>
public double MapScale { get; set; }
// 构造函数
public FrmCreateBookmark()
{
InitializeComponent();
}
// 确定
private void btnOk_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtBookmarkName.Text))
{
MessageBox.Show("请输入书签名称", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// 加载XML
XmlDocument document = new XmlDocument();
document.Load(Application.StartupPath + "\\Bookmarks.xml");
// 获取节点
XmlNode root = document.SelectSingleNode("Bookmarks");
XmlNodeList childs = root.ChildNodes;
// 遍历节点
foreach (XmlNode child in childs)
{
if (child.Attributes["Name"].Value == txtBookmarkName.Text)
{
MessageBox.Show("该书签已经存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
// 左下角X
XmlElement xmin = document.CreateElement("XMin");
xmin.InnerText = XMin.ToString();
// 左下角Y
XmlElement ymin = document.CreateElement("YMin");
ymin.InnerText = YMin.ToString();
// 右上角X
XmlElement xmax = document.CreateElement("XMax");
xmax.InnerText = XMax.ToString();
// 右上角Y
XmlElement ymax = document.CreateElement("YMax");
ymax.InnerText = YMax.ToString();
// 比例尺
XmlElement scale = document.CreateElement("MapScale");
scale.InnerText = MapScale.ToString();
// 创建节点
XmlElement element = document.CreateElement("Bookmark");
element.SetAttribute("Name", txtBookmarkName.Text);
element.AppendChild(xmin);
element.AppendChild(ymin);
element.AppendChild(xmax);
element.AppendChild(ymax);
element.AppendChild(scale);
root.AppendChild(element);
// 保存XML
document.Save(Application.StartupPath + "\\Bookmarks.xml");
this.Close();
}
}
}
4、管理书签
新建一个窗体文件,命名为FrmManageBookmarks,该窗体主要是让用户选择书签进行地图定位,如下图所示:
管理书签代码如下所示:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;
namespace WindowsFormsApplication1
{
public partial class FrmManageBookmarks : Form
{
public IMapControlDefault CurrentMapControl { get; set; }
// 构造函数
public FrmManageBookmarks()
{
InitializeComponent();
}
// Load事件
private void FrmManageBookmarks_Load(object sender, EventArgs e)
{
// 加载XML
XmlDocument document = new XmlDocument();
document.Load(Application.StartupPath + "\\Bookmarks.xml");
// 获取节点
XmlNode root = document.SelectSingleNode("Bookmarks");
XmlNodeList childs = root.ChildNodes;
// 加载书签名称
foreach (XmlNode child in childs)
{
lstBookmarks.Items.Add(child.Attributes["Name"].Value);
}
}
// 定位
private void btnLocate_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(lstBookmarks.SelectedItem.ToString()))
{
MessageBox.Show("请选择书签", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// 加载XML
XmlDocument document = new XmlDocument();
document.Load(Application.StartupPath + "\\Bookmarks.xml");
// 获取节点
XmlNode root = document.SelectSingleNode("Bookmarks");
XmlNode node = null;
// 查找书签
foreach (XmlNode child in root.ChildNodes)
{
if (child.Attributes["Name"].Value == lstBookmarks.SelectedItem.ToString())
{
node = child;
break;
}
}
// 创建包络框
IEnvelope pEnvelope = new Envelope() as IEnvelope;
pEnvelope.XMin = double.Parse(node.SelectSingleNode("XMin").InnerText);
pEnvelope.YMin = double.Parse(node.SelectSingleNode("YMin").InnerText);
pEnvelope.XMax = double.Parse(node.SelectSingleNode("XMax").InnerText);
pEnvelope.YMax = double.Parse(node.SelectSingleNode("YMax").InnerText);
pEnvelope.SpatialReference = CurrentMapControl.SpatialReference;
// 刷新地图
CurrentMapControl.ActiveView.Extent = pEnvelope;
CurrentMapControl.ActiveView.Refresh();
}
}
}
利用XML实现书签的好处就在于:当用户每次加载窗体时都能读取到之前创建的书签,避免每次都重复创建书签。