ArcEngine简单教程——数据属性:属性表、识别(Identify);删除图层 等功能实现

其他教程请见:

ArcEngine简单教程汇总

目录

ArcEngine简单教程汇总​​​​​​​

1 目的

2 概要

1)通过图层获取属性表,返回DataTable

2)通过位置点,获取属性值,返回string

3)实现右击TOC图层显示菜单

4)移除图层

3 关键代码

4 总结


​​​​​​​

 

1 目的

了解ArcEngine中矢量要素的字段及属性结构,了解栅格图像的数据属性及属性表

实现右击TOC可以显示数据属性表、删除图层,双击Map可以识别地图属性

 

2 概要

本文只介绍主要功能方法,具体的调用关系、窗口实现可见

https://download.csdn.net/download/nominior/11367818

 

1)通过图层获取属性表,返回DataTable

首先进行判断,对栅格、矢量图层的处理方法不同

 

如果是栅格图层(注意:浮点数栅格一般是无法构建属性表的,浮点数唯一值过多!!!目前只可以处理单波段属性表,处理后属性表会保留在栅格数据中):

首先获取文件元数据,判断是否可以建立属性表

获取波段集合,判断波段1是否存在属性数据,存在直接返回,不存在,通过:在工作空间下打开栅格数据集,转换为栅格数据集编辑对象,创建栅格数据集属性表等      进行创建。返回Table格式的属性表,包括属性记录号、Value、Count固定字段

根据获取的Table属性表(ArcGIS格式),将其转换为DataTable表(通用格式),转换思路:创建DataTable,游标遍历Table记录,转换为DataTable记录

 

如果是矢量要素图层:

获取要素类,对要素类下的字段进行统计

获取字段名、字段类型构建DataTable具体结构

使用游标遍历要素类,获取每一个要素,

获取每个要素所对应的字段值

2)通过位置点,获取属性值,返回string

获取鼠标点击位置信息

       如果是栅格图层:

图层转为Identify对象,将扩大后的点作为参数输入,进行识别

遍历识别结果记录,获取图层名和对应位置的属性值

       如果是矢量要素图层:

先对点进行缓冲,扩大点覆盖范围(尽量减少 对空白区域的识别,增加对有效记录的识别)

图层转为Identify对象,将扩大后的点作为参数输入,进行识别

遍历识别结果中的记录,获取对应的要素属性记录,通过遍历属性记录来获取属性记录的字段、字段名

3)实现右击TOC图层显示菜单

拖选contextMenuStrip;

定义全局 / 类变量HitLayer用于在不同方法间调用

在TOC的鼠标按下事件中,调用TOCControl.HitTest方法传入、传出参数;

根据参数判断是否对图层进行右击,如果是,将图层赋给HitLayer;

在单击处显示contextMenuStrip

4)移除图层

调用MapControl.Map.DeleteLayer方法直接移除图层

 

3 关键代码

1)右击打开菜单

        #region 右击打开菜单
        private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e)
        {
            //判断是否为右键
            if (e.button == 2)
            {
                esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
                IBasicMap map = null;
                ILayer layer = null;
                System.Object other = null;
                System.Object index = null;

                axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index);
                //判断鼠标单击的事件源是否为图层(也可能是数据框或空白)
                if (item == esriTOCControlItem.esriTOCControlItemLayer)
                {
                    contextMenuStrip1.Show(axTOCControl1, e.x, e.y);
                    HitLayer = layer;
                }
            }
        }
        #endregion

2)双击识别

 #region 双击识别
        private void axMapControl1_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e)
        {
            //获取鼠标点击位置点
            IPoint point = new PointClass();
            point.PutCoords(e.mapX, e.mapY);
            string output = "";
            for (int i = 0; i < axMapControl1.LayerCount; i++)
            {
                output += Identify_layer(axMapControl1.get_Layer(i), point);
            }
            MessageBox.Show(output);
        }
        private string Identify_layer(ILayer layer, IPoint SelectedPoint)
        {
            //定义几何图形
            IGeometry pGeometry;
            //定义结果字符串
            string output = "";
            //如果是矢量图层
            if (layer is IFeatureLayer)
            {
                //图层转Identify对象
                IIdentify pFL = layer as IIdentify;
                //对点进行缓冲赋给几何图形,尽量减少对空白区域判定
                ITopologicalOperator pTopo = SelectedPoint as ITopologicalOperator;
                pGeometry = pTopo.Buffer(500);
                //将几何图形作为输入传入Identify对象,进行识别
                IArray id_result = pFL.Identify(pGeometry);
                if (id_result != null)
                {
                    //对识别结果中的记录进行遍历(由于缓冲扩大,可能识别到同一图层多条记录)
                    for (int i = 0; i < id_result.Count; i++)
                    {
                        //获取识别结果记录中的属性记录
                        IIdentifyObj featureIdentifyobj = (IIdentifyObj)id_result.get_Element(i);
                        IRowIdentifyObject iRowIdentifyObject = featureIdentifyobj as IRowIdentifyObject;
                        IRow pRow = iRowIdentifyObject.Row;//添加引用GeoDatabase
                        output += "\"" + featureIdentifyobj.Layer.Name + "\":\n";
                        //遍历属性记录,获取字段名、字段值
                        for (int a = 0; a < pRow.Fields.FieldCount; a++)
                        {
                            if (pRow.Fields.get_Field(a).Type != esriFieldType.esriFieldTypeGeometry)
                            {
                                output += String.Format("{0}={1} \n", pRow.Fields.get_Field(a).Name, pRow.get_Value(a).ToString());
                            }
                        }
                    }
                }
            }
            else if (layer is IRasterLayer)
            {
                //图层转Identify对象
                IIdentify pFL = layer as IIdentify;
                //点转几何对象
                pGeometry = SelectedPoint as IGeometry;
                //将几何图形作为输入传入Identify对象,进行识别
                IArray id_result = pFL.Identify(pGeometry);
                if (id_result != null)
                {
                    //遍历识别结果记录,获取图层名和对应位置的属性值
                    for (int i = 0; i < id_result.Count; i++)
                    {
                        IIdentifyObj featureIdentifyobj = (IIdentifyObj)id_result.get_Element(i);
                        IRasterIdentifyObj rasterIdentifyobj = featureIdentifyobj as IRasterIdentifyObj;
                        output += "\"" + featureIdentifyobj.Layer.Name + "\":" + "\n" + rasterIdentifyobj.MapTip + "\n";
                    }
                }
            }

            return output + "\n";
        }
        #endregion

3)获取属性表

#region 获取属性表
        private void show_attribute(ILayer layer)
        {
            if (layer is FeatureLayer)
            {
                DataTable FT = FL_BuildTable(layer as FeatureLayer);
                FT = FL_FillTable(FT, layer as FeatureLayer);
                dataGridView1.DataSource = FT;
            }
            else if (layer is RasterLayer)
            {
                DataTable RT = RL_GetTable(layer as RasterLayer);
                dataGridView1.DataSource = RT;
            }
        }

        #region 获取矢量属性表
        private DataTable FL_BuildTable(FeatureLayer layer)
        {
            //创建DataTable,以图层名命名
            DataTable featureTable = new DataTable(layer.Name);
            //获取图层的要素类
            IFeatureClass featureClass = layer.FeatureClass;//添加引用GeoDatabase
            //对要素类下的字段进行遍历,添加到DataTable中
            int numFields = featureClass.Fields.FieldCount;
            for (int i = 0; i < numFields; i++)
            {
                //创建列
                DataColumn field = new DataColumn();
                //确定列名
                field.ColumnName = featureClass.Fields.get_Field(i).Name;
                //确定列数据类型
                switch (featureClass.Fields.get_Field(i).Type)
                {
                    case esriFieldType.esriFieldTypeOID:
                    case esriFieldType.esriFieldTypeSingle:
                    case esriFieldType.esriFieldTypeInteger:
                    case esriFieldType.esriFieldTypeSmallInteger:
                        field.DataType = System.Type.GetType("System.Int32");
                        break;
                    case esriFieldType.esriFieldTypeDouble:
                        field.DataType = System.Type.GetType("System.Double");
                        break;
                    case esriFieldType.esriFieldTypeGeometry:
                    case esriFieldType.esriFieldTypeString:
                    default:
                        field.DataType = System.Type.GetType("System.String");
                        break;
                }
                //添加列
                featureTable.Columns.Add(field);
            }
            return featureTable;
        }
        private DataTable FL_FillTable(DataTable featureTable, FeatureLayer featureLayer)
        {
            IFeatureClass featureClass = featureLayer.FeatureClass;
            //根据条件查找获取要素遍历游标,无限定条件(即全部遍历),不循环遍历
            IFeatureCursor cursor = featureLayer.Search(null, false);
            if (cursor != null)
            {   //清除当前Table中的记录
                featureTable.Rows.Clear();
                //使用cursor.NextFeature,不断进行遍历
                IFeature pFeature = cursor.NextFeature();
                while (pFeature != null)
                {
                    //根据Table创建行记录
                    DataRow pFeatureRow = featureTable.NewRow();
                    //遍历feature中的字段值,并将其由ArcGIS格式转换为通用格式存放到行记录中
                    for (int i = 0; i < featureClass.Fields.FieldCount; i++)
                    {
                        switch (pFeature.Fields.get_Field(i).Type)
                        {
                            case esriFieldType.esriFieldTypeOID:
                            case esriFieldType.esriFieldTypeSingle:
                            case esriFieldType.esriFieldTypeInteger:
                            case esriFieldType.esriFieldTypeSmallInteger:
                                pFeatureRow[i] = Convert.ToInt32(pFeature.get_Value(i));
                                break;
                            case esriFieldType.esriFieldTypeDouble:
                                pFeatureRow[i] = Convert.ToDouble(pFeature.get_Value(i));
                                break;
                            case esriFieldType.esriFieldTypeGeometry:
                                //调用自定义方法,将ArcGIS中的几何类型,转换为字符串描述
                                pFeatureRow[i] = GeometryTypeToString(pFeature.Shape.GeometryType);
                                break;
                            case esriFieldType.esriFieldTypeString:
                            default:
                                pFeatureRow[i] = pFeature.get_Value(i).ToString();
                                break;
                        }
                    }
                    //将行记录添加到Table中
                    featureTable.Rows.Add(pFeatureRow);
                    //游标继续遍历
                    pFeature = cursor.NextFeature();
                }
            }
            return featureTable;
        }
        private String GeometryTypeToString(esriGeometryType esrigeometryType)
        {
            string strType = "";
            switch (esrigeometryType)
            {
                case esriGeometryType.esriGeometryPoint:
                case esriGeometryType.esriGeometryMultipoint:
                    strType = "point";
                    break;
                case esriGeometryType.esriGeometryLine:
                case esriGeometryType.esriGeometryPolyline:
                    strType = "line";
                    break;
                case esriGeometryType.esriGeometryPolygon:
                    strType = "polygon";
                    break;
                default:
                    strType = "geometry";
                    break;
            }
            return strType;
        }
        #endregion

        #region 获取属性表栅格
        private ITable RL_BuildTable(RasterLayer rasterLayer)
        {
            //获取栅格图层中的栅格数据
            IRaster pRaster = rasterLayer.Raster;
            //栅格图层元数据
            IRasterProps rProp = pRaster as IRasterProps;//添加引用DataSourceRaster
            if (rProp == null)
            {
                return null;
            }
            //判断栅格像元值是否是整型
            else if (rProp.PixelType == rstPixelType.PT_FLOAT || rProp.PixelType == rstPixelType.PT_DOUBLE) 
            {
                return null;
            }

            //从栅格图像的波段集合中,获取第一波段
            IRasterBandCollection pRasterbandCollection = (IRasterBandCollection)pRaster;
            IRasterBand rasterBand = pRasterbandCollection.Item(0);
            ITable rTable = rasterBand.AttributeTable;
            //已经存在属性表,直接返回属性表
            if (rTable != null)
            {
                return rasterBand.AttributeTable;
            }
            //否则,构建属性表
            else
            {
                //获取文件名全局路径,拆分为路径、文件名
                string strPath = rasterLayer.FilePath;
                string strDirName = System.IO.Path.GetDirectoryName(strPath);
                string strRasterName = System.IO.Path.GetFileName(strPath);
                //根据路径,创建工作空间
                IWorkspaceFactory pWork = new RasterWorkspaceFactoryClass();
                IRasterWorkspace pRasterWs = (IRasterWorkspace)pWork.OpenFromFile(strDirName, 0);
                //打开工作空间下的栅格文件,并转换为栅格编辑接口
                IRasterDataset rasterDataset = pRasterWs.OpenRasterDataset(strRasterName);
                IRasterDatasetEdit2 rasterDatasetEdit = (IRasterDatasetEdit2)rasterDataset;
                if (rasterDatasetEdit == null)
                {
                    return null;
                }
                //建立栅格数据集属性表
                rasterDatasetEdit.BuildAttributeTable();  
                //更新选择的波段对象
                pRasterbandCollection = (IRasterBandCollection)rasterDataset;
                rasterBand = pRasterbandCollection.Item(0);
                return rasterBand.AttributeTable;    //重新获取属性表
            }
        }
        private DataTable RL_GetTable(RasterLayer rasterLayer)
        {
            //获取Table类型属性表
            ITable table = RL_BuildTable(rasterLayer);
            //创建DataTable
            DataTable rasterTable = new DataTable();
            //直接为DataTable添加列
            for (int i = 0; i < table.Fields.FieldCount; i++)
            {
                rasterTable.Columns.Add(table.Fields.Field[i].Name);
            }

            //使用游标,遍历table行记录
            ICursor pCursor = table.Search(null, false);
            IRow pRrow = pCursor.NextRow();
            while (pRrow != null)
            {
                //根据DataTable创建行记录
                DataRow pRow = rasterTable.NewRow();
                //table行记录值转DataTable行记录
                for (int i = 0; i < pRrow.Fields.FieldCount; i++)
                {
                    pRow[i] = pRrow.Value[i].ToString();
                }
                //添加行记录
                rasterTable.Rows.Add(pRow);
                //继续遍历
                pRrow = pCursor.NextRow();
            }
            return rasterTable;
        }
        #endregion
        #endregion

4 总结

本文主要对数据属性进行操作

矢量要素的属性表构建,主要依据要素类进行,包括从要素类获取字段、从要素类获取要素及对应的字段值两部分

栅格数据的属性表构建,如果波段已有属性表,直接获取Table然后转DataTable;否则,根据图层,建立工作空间,从工作空间打开栅格数据集格式的栅格文件,对栅格数据集建立属性表,让后获取波段属性Table,转DataTable

识别也分为矢量和栅格图层:矢量图层需要先对点进行放大,增加识别几率,然后遍历结果记录对应的属性记录,得到各属性和属性值;栅格图层直接识别,遍历结果记录中的属性值

移除图层直接使用axMapControl1.Map.DeleteLayer(HitLayer);

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值