• 组件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

  • 相关阅读:
    经典算法之猴子吃桃
    VS2008C#Sqlserver2008数据库的连接以及增删改查
    在数组中随机插入数字且不重复
    菲波那切数列
    Js之AJAX
    经典算法之冒泡排序
    《Head First 设计模式》 第一章 设计模式入门
    Redis 的 IO 多路复用,学习研究
    高性能MySQL 第十章 复制 Part2
    高性能MySQL 第十一章 可扩展的MySQL
  • 原文地址:https://www.cnblogs.com/liuwenzhen/p/13126826.html
Copyright © 2020-2023  润新知