了解ArcEngine中 矢量 要素的字段及属性结构,了解栅格图像的数据属性及属性表
实现右击TOC可以显示数据属性表、删除图层,双击Map可以识别 地图 属性
本文只介绍主要功能方法,具体的调用关系、窗口实现可见
https://download.csdn.net/download/nominior/11367818
首先进行判断,对栅格、矢量图层的处理方法不同
如果是栅格图层(注意:浮点数栅格一般是无法构建属性表的,浮点数唯一值过多!!!目前只可以处理单波段属性表,处理后属性表会保留在栅格数据中):
首先获取文件元数据,判断是否可以建立属性表
获取波段 集合 ,判断波段1是否存在属性数据,存在直接返回,不存在,通过:在工作空间下打开栅格数据集, 转换 为栅格数据集编辑对象,创建栅格数据集属性表等 进行创建。返回Table格式的属性表,包括属性记录号、Value、Count固定字段
根据获取的Table属性表(ArcGIS格式),将其转换为DataTable表(通用格式),转换思路:创建DataTable,游标遍历Table记录,转换为DataTable记录
如果是矢量要素图层:
获取要素 类 ,对要素类下的字段进行统计
获取字段名、字段类型构建DataTable具体结构
使用游标遍历要素类,获取每一个要素,
获取每个要素所对应的字段值
获取鼠标点击位置信息
如果是栅格图层:
图层转为Identify对象,将扩大后的点作为参数输入,进行识别
遍历识别结果记录,获取图层名和对应位置的属性值
如果是矢量要素图层:
先对点进行缓冲,扩大点覆盖范围(尽量减少 对空白区域的识别,增加对有效记录的识别)
图层转为Identify对象,将扩大后的点作为参数输入,进行识别
遍历识别结果中的记录,获取对应的要素属性记录,通过遍历属性记录来获取属性记录的字段、字段名
拖选contextMenuStrip;
定义全局 / 类变量HitLayer用于在不同方法间调用
在TOC的鼠标按下事件中,调用TOCControl.HitTest方法传入、传出参数;
根据参数判断是否对图层进行右击,如果是,将图层赋给HitLayer;
在单击处显示contextMenuStrip
调用MapControl.Map.DeleteLayer方法直接移除图层
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; } } } #endregion2)双击识别
#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"; } #endregion3)获取属性表
#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本文主要对数据属性进行操作
矢量要素的属性表构建,主要依据要素类进行,包括从要素类获取字段、从要素类获取要素及对应的字段值两部分
栅格数据的属性表构建,如果波段已有属性表,直接获取Table然后转DataTable;否则,根据图层,建立工作空间,从工作空间打开栅格数据集格式的栅格文件,对栅格数据集建立属性表,让后获取波段属性Table,转DataTable
识别也分为矢量和栅格图层:矢量图层需要先对点进行放大,增加识别几率,然后遍历结果记录对应的属性记录,得到各属性和属性值;栅格图层直接识别,遍历结果记录中的属性值
移除图层直接使用axMapControl1.Map.DeleteLayer(HitLayer);
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删