liutingxiang的个人博客分享 http://blog.sciencenet.cn/u/liutingxiang

博文

ArcGIS Engine二次开发学习(8)根据属性查询

已有 11163 次阅读 2018-4-25 13:26 |个人分类:地理信息系统二次开发|系统分类:教学心得

 功能要求:

选择图层,选择属性字段,根据属性字段构建查询语句,查询并高亮显示选择数据集。


1、新建一个属性查询窗体,命名为frmQureyByAttribute.cs

设计如下:


2、在主窗体上新建一个菜单项,命名为“根据属性查询”,其中运行代码如下:

private void 根据属性查询ToolStripMenuItem_Click(object sender, EventArgs e)
{
     frmQureyByAttribute newQueryByAttribute = new frmQureyByAttribute(axMapControl1.Map);
     newQueryByAttribute.Show();
}


3、在frmQureyByAttribute.cs中添加引用,然后新建几个变量,并修改frmQureyByAttribute的构造函数:

public IMap currentMap;
IFeatureLayer currentFeatureLayer;
string currentFieldName;
public frmQureyByAttribute(IMap pMap)
{
   InitializeComponent();
   currentMap = pMap;
}


这样当在主窗体中点击“根据属性查询”菜单时,就可以弹出这个属性查询窗体。

4、在frmQureyByAttribute.cs中,运行时就应该在“图层名称:”右侧的“comboBoxLayerName”中显示当前地图中的所有图层。


因此,首先需要在frmQureyByAttribute.cs的load事件中添加一段代码,让“comboBoxLayerName”显示当前地图中的所有图层。

private void frmQureyByAttribute_Load(object sender, EventArgs e)
{
    string layerName;//设置临时变量存储图层名称
    for (int i = 0; i < currentMap.LayerCount; i++)
    {
       layerName = currentMap.get_Layer(i).Name;
       comboBoxLayerName.Items.Add(layerName);
    }
    //将comboxLayerName控件的默认选项设置为第一个图层名称
        comboBoxLayerName.SelectedIndex = 0;
        //将comboxselectMethod控件的默认选项设置为第一种选择方式
        comBoxSelectMethod.SelectedIndex = 0;
    
}

当选择其中一个图层的时候,“listBoxFields”控件中就应该列出这个图层的所有属性字段。因此,需要在“comboBoxLayerName”的SelectedIndexChanged事件中添加如下代码。

private void comboBoxLayerName_SelectedIndexChanged(object sender, EventArgs e)
{
    listBoxFields.Items.Clear();
        listBoxValue.Items.Clear();
        IField field;//设置临时变量存储使用IField接口的对象
        for (int i = 0; i < currentMap.LayerCount; i++)
        {
           if (currentMap.get_Layer(i) is GroupLayer)
           {
               ICompositeLayer compositeLayer = currentMap.get_Layer(i) as ICompositeLayer;
               for (int j = 0; i < compositeLayer.Count; j++)
               {
                  //判断图层的名称是否与comBoxLayerName控件中选择的图层名称相同
                  if (compositeLayer.get_Layer(j).Name == comboBoxLayerName.SelectedItem.ToString())
                  {
                      //如果相同则设置为整个窗体使用的IFeatureLayer接口对象
                       currentFeatureLayer = compositeLayer.get_Layer(j) as IFeatureLayer;
                       break;
                   }
                }
            }
             else
             {
               //判断图层的名称是否与comboxLayerName控件中选择的图层名称相同
                  if (currentMap.get_Layer(i).Name == comboBoxLayerName.SelectedItem.ToString())
                  {
                     //如果相同则设置为整个窗体所使用的IFeatureLayer接口对象
                     currentFeatureLayer = currentMap.get_Layer(i) as IFeatureLayer;
                       break;
                   }
              }
        }
             //使用IFeatureClass接口对该图层的所有属性字段进行遍历,并填充listboxField控件
        for (int i = 0; i < currentFeatureLayer.FeatureClass.Fields.FieldCount; i++)
        {
            //根据索引值获取图层的字段
            field = currentFeatureLayer.FeatureClass.Fields.get_Field(i);
            //排除SHAPE字段,并在其他字段名称前后添加字符“\”
            if (field.Name.ToUpper() != "SHAPE")
                listBoxFields.Items.Add("\"" + field.Name + "\"");
         }
             //更新labelSelectResult控件中的图层名称信息
             labSelectResult.Text = currentFeatureLayer.Name + "WHERE:";
             //将显示where语句的文本内容清除
             txtSelectResult.Clear();
}


SelectedIndexChanged事件在选择不同图层时激发。


在“选择方式:”右侧,需要列出几种不同的选择方式,包括新建选择集、添加到当前选择集、从当前选择集中删除、从当前选择集中选择。属性查询的时候,要根据选择方式的不同分别运行不同的代码。

需要在comBoxSelectMethod控件的items集合中添加如下字符:

创建新选择集
添加到当前选择集
从当前选择集中删除
从当前选择集中选择


5、在“listBoxFields”控件中选择了一个属性字段,我们想要在listBoxValue中能够显示这个属性字段的所有唯一值,该功能需要在点击“获取唯一属性值”按钮后实现。

首先,在listBoxFields的选择事件中添加代码,实现当前字段currentFieldsname的赋值

private void listBoxFields_SelectedIndexChanged(object sender, EventArgs e)
        {
            string str = listBoxFields.SelectedItem.ToString();
            str = str.Substring(1);
            str = str.Substring(0, str.Length - 1);
            currentFieldName = str;
        }

然后,需要在“获取唯一属性值”按钮的click事件中添加如下代码:

private void but_unique_Click(object sender, EventArgs e)
        {
            listBoxValue.Items.Clear();
            IQueryFilter pQueryfilter = new QueryFilterClass();
            IFeatureCursor pFeatureCursor = null;

            pQueryfilter.SubFields = currentFieldName;
            pFeatureCursor = currentFeatureLayer.FeatureClass.Search(pQueryfilter, true);
            IDataStatistics pDataStati = new DataStatisticsClass();
            pDataStati.Field = currentFieldName;
            pDataStati.Cursor = (ICursor)pFeatureCursor;

            IFields fields = currentFeatureLayer.FeatureClass.Fields;
            IField field = fields.get_Field(fields.FindField(currentFieldName));

            System.Collections.IEnumerator pEnumertaor = pDataStati.UniqueValues;
            pEnumertaor.Reset();
            while (pEnumertaor.MoveNext())
            {
                if (field.Type == esriFieldType.esriFieldTypeString)
                {
                    object obj = pEnumertaor.Current;
                    listBoxValue.Items.Add("\'" + obj.ToString() + "\'");

                }
                else
                {
                    object obj = pEnumertaor.Current;
                    listBoxValue.Items.Add(obj.ToString()); 
                }
                
            }
        }


6、在窗体的中部,我们设计了一些运算符,这里包括等号、小于、大于等。其他符号另行添加。其作用是和listBoxFields、listBoxValue里的信息共同组成一个sql查询语句,显示在下方的“txtSelectResult”控件中。


在listBoxFields中双击一个属性字段,就会在下方的“txtSelectResult”控件中添加这个字段的字符串,需要在listBoxFields的双击事件中添加如下代码:

private void listBoxFields_DoubleClick(object sender, EventArgs e)
{
    txtSelectResult.Text += listBoxFields.SelectedItem.ToString();        
}

对于中间的一个按钮,如“=”,双击之,就会在下方的“txtSelectResult”控件中添加这个按钮的Text属性,即“=”,需要在listBoxFields的双击事件中添加如下代码:

private void bnt_equal_Click(object sender, EventArgs e)
{
    txtSelectResult.Text += "" + bnt_equal.Text + "";
}

其他符号类似。


在listBoxValue中双击一个属性唯一值,就会在下方的“txtSelectResult”控件中添加这个值的字符串,需要在listBoxValue的双击事件中添加如下代码:

private void listBoxValue_MouseDoubleClick(object sender, MouseEventArgs e)
{
    txtSelectResult.Text += listBoxValue.SelectedItem.ToString();
}


这样就构建了一各sql查询语句,显示在“txtSelectResult”控件中。


7、最后需要运行这个查询语句。



首先需要定义一下查询的方法。

private void SelectFeatureByAttribute()
{
    IFeatureSelection featureSelection = currentFeatureLayer as IFeatureSelection;
    IQueryFilter queryFilter = new QueryFilterClass();
    queryFilter.WhereClause = txtSelectResult.Text;
    IActiveView activeView = currentMap as IActiveView;
    switch (comBoxSelectMethod.SelectedIndex)
    {
        case 0:
           currentMap.ClearSelection();
           featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
           break;
        case 1:
           featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
           break;
        case 2:
           featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultXOR, false);
           break;
        case 3:
            featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
            break;
        default:
            currentMap.ClearSelection();
            featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
            break;
      }
     activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, activeView.Extent);
}

这个查询的方法中有三个关键参数,一个是当前所选的图层,一个是当前构建的sql语句,一个是选择方式。


然后在“应用”按钮的clik事件中添加代码,运行这个查询语句。

private void button3_Click(object sender, EventArgs e)
{
     SelectFeatureByAttribute();
}

点击“应用”按钮后,程序运行查询语句,就会查询到相应的数据。查询窗口不会关闭。


如果点击“确定”按钮,程序运行查询语句,然后查询窗口关闭。因此需要在其click事件中添加如下代码:

private void button2_Click(object sender, EventArgs e)
{
    try
    {
         SelectFeatureByAttribute();
         this.Close();

     }
        catch {}
}



如果只点击“取消”按钮,窗口直接退出。

private void button4_Click(object sender, EventArgs e)
{
            this.Dispose();
}


点击“清除”按钮,清除之前是sql语句。

private void button1_Click(object sender, EventArgs e)
        {
            txtSelectResult.Clear();
        }


运行结果如下:




https://blog.sciencenet.cn/blog-3373120-1110830.html

上一篇:ArcGIS Engine二次开发学习(7)自定义命令
下一篇:ArcGIS Engine二次开发学习(9)MapControl、TOCControl右键菜单
收藏 IP: 121.69.12.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-9-20 04:48

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部