AE学习笔记之空间查询

        ArcGIS Engine 的空间查询功能是其最大的一个特色,本文主要介绍一下空间查询的流程。

首先,新建一个对话框用于选择查询的图层与查询方式。

添加三个Label控件,两个ComboBox,两个Button和一个TextBox。各控件属性设置如下:

名称(Name

Text属性

描述

lblLayer

选择图层:

标签

lblField

字段名称:

标签

lblFind

查找内容:

标签

cboLayer

 

MapControl中的图层名称

cboField

 

cboLayer选中图层的所有字段名称

txtValue

 

输入的查询对象名称

btnOk

查找

查询按钮

btnCancel

取消

取消查询按钮

对话框界面如下:

AE学习笔记之空间查询_第1张图片

进入窗体的代码编辑界面。

1、添加成员变量,重写构造函数,用于在函数构造时获取主窗体的mapControl 控件对象。代码如下:

    public SpatialQueryForm(ESRI.ArcGIS.Controls.AxMapControl mapControl)
        {
            InitializeComponent();
            this.m_mapControl = mapControl;
        }
        #region Class Numble
        //获取主窗体mapControl对象
        private ESRI.ArcGIS.Controls.AxMapControl m_mapControl;
        //查询方式
        public int mQueryModel;
        //图层索引
        public int mLayerIndex;

        #endregion 

定义两个变量,用于存储查询方式与图层索引。

2、在窗体的Load消息响应函数中初始化当前的图层信息和查询方式,代码如下:

   private void SpatialQueryForm_Load(object sender, EventArgs e)
        {
            //MapControl没有图层返回
            if (m_mapControl.LayerCount <= 0)
                return;
            //获取MapControl中的全部图层名称,并加入ComboBox
            for (int i = 0; i < m_mapControl.LayerCount; ++i)
            {
                cobLayer.Items.Add(m_mapControl.get_Layer(i).Name);
            }
            //加载查询方式
            this.cobSearchStyle.Items.Add("矩形查询");
            this.cobSearchStyle.Items.Add("线查询");
            this.cobSearchStyle.Items.Add("点查询");
            this.cobSearchStyle.Items.Add("圆查询");
            //初始化ComboBox默认值
            cobLayer.SelectedIndex = 0;
            cobSearchStyle.SelectedIndex = 0;
        }

3、查询按钮的响应函数,用于获取所选择的图层与查询方式。代码如下:

private void btnOK_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            //判断图层数量
            if (this.cobLayer.Items.Count <= 0)
            {
                MessageBox.Show("当前MapControl没有添加图层!", "提示");
                return;
            }
            //获取选中的查询方式和图层索引
            this.mLayerIndex = cobLayer.SelectedIndex;
            this.mQueryModel = cobSearchStyle.SelectedIndex;

        }

4、在主窗体的菜单栏里建立一个空间分析项,在按钮的响应函数中调用空间查询对话框。并且新建两个成员变量,用于在主窗体中记录查询方式与状态代码如下:

  #region 空间查询变量
        //查询方式
        public int mQueryModel;
        //图层索引
        public int mLayerIndex;
        #endregion

private void menuSpatialQuery_Click(object sender, EventArgs e)
        {
           //初始化空间查询窗体
            SpatialQueryForm pspatialQueryForm = new SpatialQueryForm(axMapControl1);
            if (pspatialQueryForm.ShowDialog() == DialogResult.OK)
            {
                this.mTool = "SpatialQuery";
                //获取查询方式和图层信息
                this.mQueryModel = pspatialQueryForm.mQueryModel;
                this.mLayerIndex = pspatialQueryForm.mLayerIndex;
                //设置鼠标形状
                this.axMapControl1.MousePointer = ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerCrosshair;

            }
        }

在该函数中是通过string 类型的mTool变量记录函数状态。然后在鼠标按下(OnMouseDown)的消息响应中实现查询。

5、在Form的窗口设计中添加一个Panel控件,设置控件的visible属性为false。在Panel控件中添加一个datagridview 控件用于显示查询结果,以表单的形式显示,和一个取消按钮。如下图:

AE学习笔记之空间查询_第2张图片



6、在主窗体中建立一个独立函数,用于实现查询结果。代码如下:

   private DataTable LoadQueryResult(ESRI.ArcGIS.Controls.AxMapControl mapControl, ESRI.ArcGIS.Carto.IFeatureLayer featureLayer, ESRI.ArcGIS.Geometry.IGeometry geometry)
        {
            ESRI.ArcGIS.Geodatabase.IFeatureClass pFeatureClass = featureLayer.FeatureClass;
            //根据图层属性字段初始化DataTable
            ESRI.ArcGIS.Geodatabase.IFields pFields = pFeatureClass.Fields;
            DataTable pDataTable = new DataTable();
            for (int i = 0; i < pFields.FieldCount; ++i)
            {
                pDataTable.Columns.Add(pFields.get_Field(i).AliasName);
            }
            //空间过滤器
            ESRI.ArcGIS.Geodatabase.ISpatialFilter pSpatialFilter = new ESRI.ArcGIS.Geodatabase.SpatialFilterClass();
            pSpatialFilter.Geometry = geometry;
            //根据图层类型选择缓冲方式
            switch (pFeatureClass.ShapeType)
            {
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint:
                    pSpatialFilter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelContains;
                    break;
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
                    pSpatialFilter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelCrosses;
                    break;
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
                    pSpatialFilter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelIntersects;
                    break;
            }
            //定义空间过滤器的空间字段
            pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
            ESRI.ArcGIS.Geodatabase.IQueryFilter pQueryFilter;
            ESRI.ArcGIS.Geodatabase.IFeatureCursor pFeatureCursor;
            ESRI.ArcGIS.Geodatabase.IFeature pFeature;
            //利用要素过滤器查询要素
            pQueryFilter = pSpatialFilter as ESRI.ArcGIS.Geodatabase.IQueryFilter;
            pFeatureCursor = featureLayer.Search(pQueryFilter, true);
            pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                string strFldValue = null;
                DataRow dr = pDataTable.NewRow();
                //遍历图层属性表字段值,并加入pDataTable
                for (int i = 0; i < pFields.FieldCount; i++)
                {
                    string strFldName = pFields.get_Field(i).Name;
                    if (strFldName == "Shape")
                    {
                        strFldValue = Convert.ToString(pFeature.Shape.GeometryType);
                    }
                    else
                        strFldValue = Convert.ToString(pFeature.get_Value(i));
                    dr[i] = strFldValue;
                }
                pDataTable.Rows.Add(dr);
                //高亮选择要素
                mapControl.Map.SelectFeature((ESRI.ArcGIS.Carto.ILayer)featureLayer, pFeature);
                mapControl.ActiveView.Refresh();
                pFeature = pFeatureCursor.NextFeature();
            }
            
            return pDataTable;

        }


代码注释:该函数中根据输入的mapcontrol 、FeatureLayer和Geometry三个参数返回DataTable类型的查询结果。

注意,其中需要根据图层类型选择,点类型为包含、线类型为Cross、面类型为intersect。

7、在鼠标按下的响应函数中获取选择的区域,并进行查询。代码如下:

  private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            //清空上次选择的结果
            this.axMapControl1.Map.ClearSelection();
           
            switch (mTool)
            {
                case"SpatialQuery":
                    //获取当前视图
                    ESRI.ArcGIS.Carto.IActiveView pActiveView = this.axMapControl1.ActiveView;
                    //获取鼠标点
                    ESRI.ArcGIS.Geometry.IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                    panel1.Visible = true;
                    ESRI.ArcGIS.Geometry.IGeometry pGeometry = null;
                    switch (this.mQueryModel)
                    {
                        case 0:         //矩形查询
                            pGeometry = this.axMapControl1.TrackRectangle();
                            break;
                        case 1:         //线查询
                            pGeometry = this.axMapControl1.TrackLine();
                            break;
                        case 2:         //点查询
                            ESRI.ArcGIS.Geometry.ITopologicalOperator pTopo;
                            ESRI.ArcGIS.Geometry.IGeometry pBuffer;
                            pGeometry = pPoint;
                            pTopo = pGeometry as ESRI.ArcGIS.Geometry.ITopologicalOperator;
                            //根据点位创建缓冲区,缓冲半径设为0.1,可自行修改
                            pBuffer = pTopo.Buffer(0.1);
                            pGeometry = pBuffer.Envelope;
                            break;
                        case 3:         //圆查询
                            pGeometry = this.axMapControl1.TrackCircle();
                            break;
                    }
                    ESRI.ArcGIS.Carto.IFeatureLayer pFeatureLayer = this.axMapControl1.Map.get_Layer(this.mLayerIndex) as ESRI.ArcGIS.Carto.IFeatureLayer;
                    DataTable pDataTable = this.LoadQueryResult(axMapControl1, pFeatureLayer, pGeometry);
                    this.dataGridView1.DataSource = pDataTable.DefaultView;
                    this.dataGridView1.Refresh();
                    break;
                default :
                    break;
 
            }
        }

8、最后编辑Panel中取消按钮的代码,用于实现清空查询结果。panel窗口的关闭是通过设置其Visible属性实现的。代码如下:

  private void btnCancel_Click(object sender, EventArgs e)
        {
            this.panel1.Visible = false;
            this.axMapControl1.ActiveView.FocusMap.ClearSelection();
            this.axMapControl1.Refresh();
        }


最终结果如下图:

AE学习笔记之空间查询_第3张图片

----------------------------------------------------------------------------------end-----------------------------------------------------------------------------





你可能感兴趣的:(AE开发)