组件GIS 2 查询统计

2.1 纲要

查询统计

2.2 属性查询

本质上是SQL的Where(条件)查询,通过对话框获取条件语句,然后调用相关接口实现。

2.2.1 对话框布局

属性查询

其中,选择方式如下:

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

2.2.2 核心代码

明确对话框的职位:获取参数、展示数据,所以核心功能实现应该单独封装成方法。

/// <summary>
/// 属性查询
/// </summary>
/// <param name="pFeaLyr">查询图层</param>
/// <param name="Method">选择方式</param>
/// <param name="WhereClause">查询语句</param>
/// <param name="pActiveView">活动视图</param>
static public bool SelectFeatures(IFeatureLayer pFeaLyr, esriSelectionResultEnum Method,
                                  string WhereClause, IActiveView pActiveView)
{
    IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaLyr;
    IQueryFilter pQF = new QueryFilterClass();
    pQF.WhereClause = WhereClause;
    pFeaSelection.SelectFeatures(pQF, Method, false);
    if (pFeaSelection.SelectionSet.Count == 0)
        return false;
    pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
    return true;
}

在对话框类内再封装:

private void SelectFeaturesByAttribute()
{
    //获取参数
    IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(comboBoxLayerName.SelectedIndex);
    esriSelectionResultEnum selectMethod;
    switch (comboBoxSelectMethod.SelectedItem.ToString())
    {
        case "创建新选择集":
            pMap.ClearSelection();
            selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
            break;
        case "添加到当前选择集":
            selectMethod = esriSelectionResultEnum.esriSelectionResultAdd;
            break;
        case "从当前选择集中删除":
            selectMethod = esriSelectionResultEnum.esriSelectionResultXOR;
            break;
        case "从当前选择集中选择":
            selectMethod = esriSelectionResultEnum.esriSelectionResultAnd;
            break;
        default:
            pMap.ClearSelection();
            selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
            break;
    }
    string sWhere = textBoxWhere.Text;
    //执行查询
    bool OK = FunctionTool.SelectFeatures(pFeaLyr, selectMethod, sWhere, pMap as IActiveView);
    if (!OK)
    {
        MessageBox.Show("查找失败!");
        return;
    }
    //定位选择集
    ICommand cmd = new ControlsZoomToSelectedCommandClass();
    cmd.OnCreate(pMapControl);
    cmd.OnClick();
}

2.3 空间查询

要理解“源图层”、“空间关系”、“目标图层”概念。

2.3.1 对话框布局

空间查询

空间关系如下:

相交(Intersects)
包含(Contains)
被包含(Within)
穿过(Crosses)
相接(Touches)

2.3.2 核心代码

/// <summary>
/// 空间查询
/// </summary>
/// <param name="pFeaTargetLyr">目标图层</param>
/// <param name="Method">选择方式</param>
/// <param name="spatialRel">空间关系</param>
/// <param name="pGeo">源图层几何属性</param>
/// <param name="pActiveView">活动视图</param>
static public bool SelectFeatures(esriSelectionResultEnum Method, esriSpatialRelEnum spatialRel,
                                  IGeometry pGeo, IFeatureLayer pFeaTargetLyr, IActiveView pActiveView)
{
    IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaTargetLyr;
    ISpatialFilter pSF = new SpatialFilterClass();
    pSF.Geometry = pGeo;
    pSF.SpatialRel = spatialRel;
    pFeaSelection.SelectFeatures(pSF, Method, false);
    if (pFeaSelection.SelectionSet.Count == 0)
        return false;
    pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
    return true;
}

在对话框内再封装:

private void SelectFeaturesBySpatial()
{
    //1. 获取参数
    //1.1 选择方式
    esriSelectionResultEnum selectMethod;
    switch (comboBoxMethod.SelectedItem.ToString())
    {
        case "创建新选择集":
            selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
            break;
        case "添加到当前选择集":
            selectMethod = esriSelectionResultEnum.esriSelectionResultAdd;
            break;
        case "从当前选择集中删除":
            selectMethod = esriSelectionResultEnum.esriSelectionResultXOR;
            break;
        case "从当前选择集中选择":
            selectMethod = esriSelectionResultEnum.esriSelectionResultAnd;
            break;
        default:
            selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
            break;
    }
    //1.2 空间关系
    esriSpatialRelEnum spatialRel;
    switch (comboBoxSpatialRel.SelectedItem.ToString())
    {
        case "相交(Intersects)":
            spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            break;
        case "包含(Contains)":
            spatialRel = esriSpatialRelEnum.esriSpatialRelContains;
            break;
        case "被包含(Within)":
            spatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
            break;
        case "穿过(Crosses)":
            spatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
            break;
        case "相接(Touches)":
            spatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
            break;
        default:
            spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            break;
    }
    //1.3 源图层的几何体
    IFeatureLayer pFeaSourceLyr = (IFeatureLayer)pMap.get_Layer(comboBoxSourceLayer.SelectedIndex);
    int count1 = pMapControl.Map.SelectionCount;
    IFeatureSelection pFeaSourceSel = pFeaSourceLyr as IFeatureSelection;
    IGeometry pGeo = null;
    if (checkBoxUseSelected.Checked)
        pGeo = FunctionTool.GetGeoUnion(pFeaSourceSel);
    //1.4 目标图层&执行查询
    for (int i = 0; i < checkedListBoxTargetLayers.CheckedItems.Count; i++)
    {
        string sLyrName = checkedListBoxTargetLayers.CheckedItems[i].ToString();
        IFeatureLayer pFeaTargetLyr = FunctionTool.GetFeaLyr(pMap, sLyrName);
        IFeatureSelection pFeaTargetSel = (IFeatureSelection)pFeaTargetLyr;
        bool OK = FunctionTool.SelectFeatures
            (selectMethod, spatialRel, pGeo, pFeaTargetLyr, pMap as IActiveView);
        if (!OK)
        {
            MessageBox.Show("图层【{0}】查找失败!", pFeaTargetLyr.Name);
            return;
        }
    }
    //定位选择集
    ICommand cmd = new ControlsZoomToSelectedCommandClass();
    cmd.OnCreate(pMapControl);
    cmd.OnClick();
}

其中合并几何体的代码:

static public IGeometry GetGeoUnion(IFeatureSelection pFeaSelection)
{
    IGeometry pGeo = null;
    ISelectionSet pSelSet = pFeaSelection.SelectionSet;
    ICursor pCur;
    pSelSet.Search(null, false, out pCur);
    IFeatureCursor pFeaCur = (IFeatureCursor)pCur;
    IFeature pFea = pFeaCur.NextFeature();
    while (pFea != null)
    {
        if (pGeo != null)
        {
            ITopologicalOperator pTopoOper = (ITopologicalOperator)pGeo;
            pGeo = pTopoOper.Union(pFea.Shape);
        }
        else
            pGeo = pFea.Shape;
        pFea = pFeaCur.NextFeature();
    }
    return pGeo;
}

2.3.3 运行结果

【查询前】“行政区B”(源图层)的邻接“行政区”(目标图层) 【查询后】
查询前 邻接
【查询前】跟选中“铁路”(源图层)相交的“道路”和“河流”(目标图层) 【查询后】
查询前 查询后

2.4 选择集

功能跟【属性表】类似,只是数据不一样,因此依然使用【属性表】的窗体,数据获取封装成方法,然后再窗体的构造函数内订阅不同的方法即可。

2.4.1 核心代码

/// <summary>
/// 获取选择集图层名称
/// </summary>
/// <param name="pMap">地图</param>
/// <returns>选择集图层名称</returns>
static public List<string> GetFeaSelNameList(IMap pMap)
{
    List<string> pFeaSelectionNameList = new List<string>();
    for (int i = 0; i < pMap.LayerCount; i++)
    {
        IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(i);
        IFeatureSelection pFeaSel = (IFeatureSelection)pFeaLyr;
        if (pFeaSel.SelectionSet.Count != 0)
            pFeaSelectionNameList.Add(pFeaLyr.Name);
    }
    return pFeaSelectionNameList;
}

获取选择集表的代码跟获取属性表的代码大同小异

/// <summary>
/// 获取选择集表
/// </summary>
/// <param name="pFeaSel">选择集</param>
/// <returns>选择集表</returns>
static public DataTable GetAttributeTable(IFeatureSelection pFeaSel)
{
    DataTable pDataTable = new DataTable();
    ISelectionSet pSelSet = pFeaSel.SelectionSet;
    ICursor pCur;
    pSelSet.Search(null, false, out pCur);
    IFeatureCursor pFeaCur = (IFeatureCursor)pCur;
    IFeature pFea = pFeaCur.NextFeature();
    //1. 填充字段名
    for (int i = 0; i < pFea.Fields.FieldCount; i++)
        pDataTable.Columns.Add(pFea.Fields.get_Field(i).Name);
    //2. 填充要素
    while (pFea != null)
    {
        object[] rowValue = new object[pFea.Fields.FieldCount];
        for (int i = 0; i < pFea.Fields.FieldCount; i++)
        {
            object fieldValue;
            if (pFea.Fields.get_Field(i).Name == "Shape")
            {
                switch (pFea.Shape.GeometryType)
                {
                    case esriGeometryType.esriGeometryLine:
                        fieldValue = "线";
                        break;
                    case esriGeometryType.esriGeometryPoint:
                        fieldValue = "点";
                        break;
                    case esriGeometryType.esriGeometryPolygon:
                        fieldValue = "面";
                        break;
                    case esriGeometryType.esriGeometryPolyline:
                        fieldValue = "线";
                        break;
                    default:
                        fieldValue = "未知";
                        break;
                }
            }
            else
                fieldValue = pFea.get_Value(i);
            rowValue[i] = fieldValue;
        }
        pDataTable.LoadDataRow(rowValue, true);
        pFea = pFeaCur.NextFeature();
    }
    return pDataTable;
}

订阅不同事件

public FormAttributeTable(IMap pMap, bool isSelectionSet = false)
{
    InitializeComponent();
    this.pMap = pMap;
    if (isSelectionSet)
    {
        this.Text = "选择集";
        //订阅事件
        lstbLayersName.SelectedIndexChanged += lsbLayersName_SelectedIndexChanged_SelSet;
        //触发事件
        lstbLayersName.DataSource = FunctionTool.GetFeaSelNameList(pMap);
    }
    else
    {
        //注册事件
        lstbLayersName.SelectedIndexChanged += lsbLayersName_SelectedIndexChanged;
        //触发事件
        lstbLayersName.DataSource = FunctionTool.GetLayerNameList(pMap);
    }
}

2.4.2 运行结果

空间查询:”行政区D“内有多少“居民地”?

选择集

源码链接:组件GIS

原文地址:https://www.cnblogs.com/liuwenzhen/p/13126826.html