许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  ArcEngine简单教程:数据属性(属性表、识别Identify)及删除图层等功能实现

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

阅读数 18
点赞 0
article_banner

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.esriFieldTypeOIhttps://www.gofarlic.com                    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.esriFieldTypeOIhttps://www.gofarlic.com                            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);

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空