ArcEngine 二次开发实习初级讲义
MessageBox.Show(pFeature.Value(n), \, MessageBoxButtons.OK)
这两句代码是找出“STATE_NAME”所在的列数,并将其显示出来。
3.3.4 进一步完善空间查询
在本节中我们完成更多的空间查询功能,其中有点查询、线查询、矩形查询、圆查询 新建一个VB.Net工程,向工程中添加控件,如下图所示:
其中包括MapControl,4个Button,一个TextBox 通过在控件属性中添加地图的方法,向Mapcontrol中添加例子数据。(例子数据是位于World文件夹下的Continents.lyr)如下图所示:
添加完毕后我们向工程中添加一个公共的代码模块。在下图所示的菜单中选择添加模块菜单项。
- 31 -
ArcEngine 二次开发实习初级讲义
在弹出的菜单中选择模块完成添加。
在模块中添加公共代码。(模块中的代码可以同时被多个类进行使用,属于公共模块)
Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.Geodatabase Module Module1
Public Function ConvertPixelsToMapUnits(ByVal pActiveView As IActiveView, ByVal pixelUnits As Double) As Double
Dim realWorldDisplayExtent As Double Dim pixelExtent As Integer Dim sizeOfOnePixel As Double
pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.right - pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.left realWorldDisplayExtent =
pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width sizeOfOnePixel = realWorldDisplayExtent / pixelExtent ConvertPixelsToMapUnits = pixelUnits * sizeOfOnePixel End Function
- 32 -
ArcEngine 二次开发实习初级讲义
Public Sub SelectRectangle(ByVal pGeometry As IGeometry)
Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pSpatialFilter As ISpatialFilter Dim pFilter As IQueryFilter Dim pActiveView As IActiveView Dim pCursor As IFeatureCursor Dim pFeature As IFeature
form1.AxMapControl1.Map.ClearSelection() Try
pFeatureLayer = form1.AxMapControl1.Map.Layer(0) pFeatureClass = pFeatureLayer.FeatureClass If pFeatureClass Is Nothing Then Exit Sub pActiveView = form1.AxMapControl1.Map
pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pGeometry Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains Case esriGeometryType.esriGeometryPolyline
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses Case esriGeometryType.esriGeometryPolygon
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects End Select
pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter
pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature
Dim str As String = \您选中的国家有:\ form1.AxMapControl1.Map.ClearSelection() '获取查询得到的要素总数 While Not pFeature Is Nothing
Dim n As Integer = pFeature.Fields.FindField(\ form1.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) str = str & pFeature.Value(n) & \ pFeature = pCursor.NextFeature End While
form1.TextBox1.Text = str
form1.AxMapControl1.MousePointer =
ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerArrow
- 33 -
ArcEngine 二次开发实习初级讲义
form1.AxMapControl1.Refresh() Catch ex As Exception
MessageBox.Show(Err.Description, \ End Try
form1.AxMapControl1.Refresh() End Sub End Module
在Form1的代码界面添加如下引用和全局变量
在设计页面双击点查询按钮,进入点击按钮响应事件填写如下代码。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click '点查询
nMouseFlag = 1
Me.AxMapControl1.MousePointer =
ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerCrosshair End Sub
相应的线查询、矩形查询、圆查询添加同样的代码,但nMouseFlag得值要有所改变。 线查询:nMouseFlag=2 矩形查询:nMouseFlag=3 圆查询:nMouseFlag=4
为MapControl控件添加OnMouseDown事件,填入以下代码
If nMouseFlag = 1 Then
Dim pActiveView As IActiveView Dim pPoint As IPoint Dim pBuffer As IGeometry Dim length As Double
Dim pTopo As ITopologicalOperator pActiveView = Me.AxMapControl1.Map
pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y) length = ConvertPixelsToMapUnits(pActiveView, 2)
pTopo = pPoint
pBuffer = pTopo.Buffer(length) SelectRectangle(pBuffer) End If
If nMouseFlag = 2 Then
SelectRectangle(Me.AxMapControl1.TrackLine) End If
If nMouseFlag = 3 Then
SelectRectangle(Me.AxMapControl1.TrackRectangle)
- 34 -
ArcEngine 二次开发实习初级讲义
End If
If nMouseFlag = 4 Then
SelectRectangle(Me.AxMapControl1.TrackCircle) End If
点击运行,运行效果如下图所示:
仔细研读代码,您会发现,在这部分中我们并没有用到什么新的知识,只是在结构上做了调整,应为空间查询都是需要使用一个IGeometry对象进行空间求交进行查询的。所以我们将公共的代码放在公共的模块中进行调用。有心的同学可能发现,我们为了判断用户在MapControl上的操作,我们引入了一个全局变量nMouseFlag,程序中多一个全局变量,对程序的结构的封闭性就有所破坏,能不能去掉这个全局变量而是Mapcontrol自主判断是哪个功能进行操作呢?答案是肯定的,我们可以使用BaseCommand和BaseTool来完成这个工作,详细的用法在3.4和3.5小节将会介绍。 3.3.5小结
在这一小节中,我们学习了如何进行简单的空间查询。空间查询不仅包括点查询,还包括线查询,矩形查询,多边形查询等(为了实现这些功能,可以参考MapControl中的TrackRectangle等方法)。对于这一小节的代码,强烈建议您参看帮助系统中对相关接口的解释和定义,以进一步熟悉接口的使用,这对后面的学习以及掌握ArcGIS Engine二次开发是极有好处的。如果您对这一部分比较熟悉了,可以进入下一小节。在第四章中,我们介绍了控件命令(Control Commands),并提到ArcGIS Engine允许用户自定义开发一些控件命令,在下两小节中,我们将具体学习如何开发。
- 35 -