发布时间 : 星期六 文章ArcGIS Engine二次开发 - 基础篇更新完毕开始阅读c1826921192e45361066f5ac
ArcGIS Engine二次开发——基础篇
放大”,将base.m_name 更改为“ZoomIn”。
我们简单分析一下拉框放大的执行过程,点击“拉框放大”按钮后,鼠标在MapControl的视图中的拉框过程可以分解为三个事件,鼠标在视图上的按下(MouseDown),鼠标按下在视图上的移动(MouseMove),鼠标放开(MouseUp),我们需要在鼠标按下时刻和放开时刻记录鼠标点击的坐标,然后可以得到一个新的视图范围,完成放大操作。
下面添加代码,首先我们需要在这个类中定义三个成员变量,三个成员变量的功能如注释所示。
//记录鼠标位置 private IPoint m_point; //标记MouseDown是否发生 private Boolean m_isMouseDown; //追踪鼠标移动产生新的Envelope
private INewEnvelopeFeedback m_feedBack;
在ZoomIn.cs类中的OnMouseDown函数中添加如下代码:
public override void OnMouseDown(int Button, int Shift, int X, int Y) {
//当前地图视图为空时返回
if (m_hookHelper.ActiveView == null) return; //获取鼠标点击位置
m_point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
m_isMouseDown = true;
}
在ZoomIn.cs类中的OnMouseMove函数中添加如下代码:
public override void OnMouseMove(int Button, int Shift, int X, int Y) {
//MouseDown为发生时返回 if (!m_isMouseDown) return;
IActiveView pActiveView = m_hookHelper.ActiveView; //m_feedBack追踪鼠标移动 if (m_feedBack == null) {
m_feedBack = new NewEnvelopeFeedbackClass(); m_feedBack.Display = pActiveView.ScreenDisplay; //开始追踪
m_feedBack.Start(m_point);
ArcGIS Engine二次开发——基础篇
}
//追踪鼠标移动位置
m_feedBack.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y));
}
在ZoomIn.cs类中的OnMouseUp函数中添加如下代码:
public override void OnMouseUp(int Button, int Shift, int X, int Y) {
//MouseDown为发生时返回 if (!m_isMouseDown) return;
IActiveView pActiveView = m_hookHelper.ActiveView;
//获取MouseUp发生时的范围并放大 IEnvelope pEnvelope;
if (m_feedBack == null)//鼠标未拉框时进行固定比例尺放大 {
pEnvelope = pActiveView.Extent; pEnvelope.Expand(0.5, 0.5, true); pEnvelope.CenterAt(m_point); } else {
//停止追踪
pEnvelope = m_feedBack.Stop();
//判断新的范围的高度和宽度是否为零
if (pEnvelope.Width == 0 || pEnvelope.Height == 0) {
m_feedBack = null; m_isMouseDown = false; } }
//获取新的范围
pActiveView.Extent = pEnvelope; //刷新视图
pActiveView.Refresh(); m_feedBack = null; m_isMouseDown = false;
}
ArcGIS Engine二次开发——基础篇
再进入MapViewForm窗体的代码界面,定义成员变量
private ZoomIn mZoomIn = null;
双击MapViewForm窗体上的“拉框放大”按钮,进入Click事件响应函数,将其中的代码删除,用下列代码替代:
private void btnZoomIn_Click(object sender, EventArgs e) {
//初始化
mZoomIn = new ZoomIn(); //与MapControl的关联
mZoomIn.OnCreate(this.axMapControl1.Object); //设置鼠标形状
this.axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
}
将MapControl控件的OnMouseDown响应函数中的内容全部删除,添加代码如下:
if (mZoomIn != null)
mZoomIn.OnMouseDown(e.button, e.shift, e.x, e.y);
在MapControl控件的OnMouseMove响应函数中添加代码如下:
if (mZoomIn != null)
mZoomIn.OnMouseMove(e.button, e.shift, e.x, e.y);
在MapControl控件的OnMouseUp响应函数中添加代码如下:
if (mZoomIn != null)
mZoomIn.OnMouseUp(e.button, e.shift, e.x, e.y);
1.5.3 运行
图 39程序运行结果
ArcGIS Engine二次开发——基础篇
如上图所示,首先点击“拉框放大”按钮,然后在MapControl中按下鼠标拉框,即可完成放大,点击不拖动鼠标情况下为居中放大。
1.5.4 小结
在这一小节中,我们学习了如何制作BaseTool,正如同前一小节的小结中写到的那样,当有许多功能(例如漫游,点查询等)时,由于BaseTool在生成的时候会自动和MapControl控件关联起来。在这个例子中,我们通过重载自定义了OnMouseDown、OnMouseMove和OnMouseUp三个函数,实现Tool类型功能的响应。当然,这里的拉框放大功能在ArcEngine中也进行了封装。利用封装类来实现Tool类型的工具时,同样需要定义ICommand接口,通过ICommand接口来实现与MapControl的关联。通过查询帮助文档我们可以发现,本节中我们所自定义的BaseTool工具也是从接口ICommand和ITool同时继承得到的。以“拉框放大”为例,利用ArcEngine封装的类库实现基本的Tool类型功能的代码如下(注意,在这个示例中需要添加“ESRI.ArcGIS.SystemUI”和“ESRI.ArcGIS.Controls”的引用),感兴趣的同学可以将这段代码拷贝到“拉框放大”按钮的Click事件中,删除原来的代码,运行程序可以看到一致的效果。
//Tool的定义和初始化
ITool tool = new ControlsMapZoomInToolClass();
//查询接口获取ICommand
ICommand command = tool as ICommand; //Tool通过ICommand与MapControl的关联 command.OnCreate(this.axMapControl1.Object); command.OnClick();
//MapControl的当前工具设定为tool this.axMapControl1.CurrentTool = tool;
如果您对这一小节的内容比较熟悉了,就可以开始学习本章最后一小节的内容了。在下一小节中,我们将尝试构建一个小型GIS应用。
1.6 通过代码添加图层
为了使得程序更加灵活,我们需要在程序运行后动态的向MapControl中添加图层。如何通过代码来添加地图是在本小节需要学习的。 首先我们创建一个新的Windows应用程序,名称为“AddData”,然后在窗体上添加MapControl、LicenceControl和四个Button控件,窗体及控件属性设置如下:
表 1窗体及控件属性设置
类型 Form Button Button Button Button
界面效果如下图:
Name MainForm btnClear btnMxd btnShp btnGdbVector Text 添加数据 清空图层 打开MXD 添加Shp 添加GDB矢量 用途 主窗体 清空图层 打开MXD文档 添加Shp图层 添加GDB矢量数据