IMap.FeatureSelection方法获取Feature的属性信息

本文介绍通过IMap.FeatureSelection获取地图选择集要素时,默认只返回shape信息的原因及如何通过IEnumFeatureSetup::AllFields方法设置返回所有字段属性信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近日在通过 IMap.FeatureSelection 获取了地图的选择集要素之后,发现获取的 IFeature 对象属性信息都是空的。感到很奇怪,仔细看了一下文档,发现如下的描述:


only the shape field is guaranteed with the selection. This is the default and exists for performance reasons. The IMap::FeatureSelection property is typically used to draw the map selection, not access feature attributes. This is particularly noticeable with shapefiles and coverage but also in geodatabases if the selection is large enough. Use IEnumFeatureSetup::AllFields to set a flag indicating all fields be returned with the selection. If you want to loop through the map selection to perform an operation, it is typically best to access each layer's selection rather than the entire map's selection. See the example for a sample of each.

 

原来出于性能方面的考虑,该接口默认只返回 shape 信息, FeatureSelection 方法主要是用来获取选中要素进行绘制,不需要访问属性信息。可以通过 IEnumFeatureSetup::AllFields 方法来设置允许返回属性。如果要遍历地图中的选择集,最好是通过 Layer 来获取选择集,比这种方法好。


IMap 获取选择集属性信息的方法如下:


// 获取选择集

ISelection pSelection = axMapControl1 .Map .FeatureSelection ;

 

// 打开属性标签

IEnumFeatureSetup pEnumFeatureSetup = pSelection as IEnumFeatureSetup ;

pEnumFeatureSetup .AllFields = true ;

 

// 读取属性

IEnumFeature pEnumFeature = pSelection as IEnumFeature ;

IFeature pFeature = pEnumFeature .Next ();

 

while (pFeature != null )

{

Console .WriteLine (pFeature .get_Value (2));

pFeature = pEnumFeature .Next ();

}

 

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Display; namespace WaterPipelineGIS2 { public partial class Form1 : Form { private IFeatureLayer _selectedFeatureLayer; private System.Drawing.Point _lastRightClickPosition; private enum SelectionMode { None, Rectangle, Circle, Polygon, Polyline } private SelectionMode currentMode = SelectionMode.None; private enum MeasureMode { None, Area, Length, Point } private MeasureMode currentMeasureMode = MeasureMode.None; private IGeometry tempGeometry; private IPointCollection pointCollection; private Label lblMeasureResult; private IGraphicsContainer _spatialSelectionGraphics; // 空间选择图形容器 private IGraphicsContainer _attributeHighlightGraphics; // 属性表高亮图形容器 public Form1() { InitializeComponent(); axMapControl1.OnMouseMove += new IMapControlEvents2_Ax_OnMouseMoveEventHandler(axMapControl1_OnMouseMove); } private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e) { // 获取地图坐标 double mapX = e.mapX; double mapY = e.mapY; // 格式化坐标显示(保留3位小数) lblCoordinate.Text = string.Format("X: {0:F3} Y: {1:F3}", mapX, mapY); // 立即刷新状态栏 statusStrip1.Refresh(); } private void toolStripMenuItem2_Click(object sender, EventArgs e) { using (var rotateForm = new RotateForm()) { if (rotateForm.ShowDialog() == DialogResult.OK) { try { axMapControl1.Rotation = rotateForm.RotationAngle; axMapControl1.ActiveView.Refresh(); // 可选:更新状态栏 lblCoordinate.Text += " 旋转角度:{rotateForm.RotationAngle}°"; } catch (Exception ex) { MessageBox.Show("旋转失败:{ex.Message}"); } } } } private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { if (e.button == 2) // 右键 { // 保存点击位置(控件坐标系) _lastRightClickPosition = new System.Drawing.Point(e.x, e.y); ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; // 修改点1:声明为接口类型并初始化为null IBasicMap basicMap = null; ILayer layer = null; // 修改点2:使用Type.Missing代替new object() object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; // 修改点3:正确传递ref参数 tocControl.HitTest(e.x, e.y, ref itemType, ref basicMap, ref layer, ref other, ref index); if (itemType == esriTOCControlItem.esriTOCControlItemLayer && layer != null) { contextMenuStripTOC.Show(axTOCControl1, e.x, e.y); } } } // 修改后(使用 MouseEventArgs) private void openAttributeTableToolStripMenuItem_Click(object sender, EventArgs e) { ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; IBasicMap basicMap = null; ILayer layer = null; object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; // 获取当前鼠标位置(屏幕坐标系) System.Drawing.Point screenPos = contextMenuStripTOC.PointToClient(Control.MousePosition); // 转换为控件坐标系 System.Drawing.Point controlPos = axTOCControl1.PointToClient(Control.MousePosition); tocControl.HitTest( controlPos.X, controlPos.Y, ref itemType, ref basicMap, ref layer, ref other, ref index ); IFeatureLayer featureLayer = layer as IFeatureLayer; if (featureLayer != null) { _selectedFeatureLayer = featureLayer; AttributeTableForm attrForm = new AttributeTableForm( _selectedFeatureLayer, this // 传递主窗体引用 ); attrForm.Show(); } } private void SetSelectionSymbol() { // 使用接口创建符号 ISimpleFillSymbol fillSymbol = new SimpleFillSymbol() as ISimpleFillSymbol; fillSymbol.Color = GetRgbColor(255, 0, 0); fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; ISimpleLineSymbol lineSymbol = new SimpleLineSymbol() as ISimpleLineSymbol; lineSymbol.Color = GetRgbColor(255, 255, 0); lineSymbol.Width = 2; fillSymbol.Outline = lineSymbol; // 设置渲染器 if (_selectedFeatureLayer != null) { IGeoFeatureLayer geoLayer = (IGeoFeatureLayer)_selectedFeatureLayer; ISimpleRenderer renderer = new SimpleRenderer() as ISimpleRenderer; renderer.Symbol = (ISymbol)fillSymbol; geoLayer.Renderer = (IFeatureRenderer)renderer; axMapControl1.ActiveView.Refresh(); } } private IRgbColor GetRgbColor(int r, int g, int b) { IRgbColor color = new RgbColor() as IRgbColor; // 正确方式 color.Red = r; color.Green = g; color.Blue = b; return color; } public void ActivateFeatureLayer(IFeatureLayer featureLayer) { if (featureLayer == null) return; // 1. 设置当前活动图层 _selectedFeatureLayer = featureLayer; // 2. 刷新地图显示(可选) axMapControl1.ActiveView.Refresh(); // 3. 更新TOC控件的选中状态(可选) axTOCControl1.Update(); } // 修改 HighlightAndZoomToFeature 方法实现 public void HighlightAndZoomToFeature(IFeatureLayer featureLayer, int oid) { try { if (featureLayer == null || featureLayer.FeatureClass == null) { MessageBox.Show("图层或要素类无效!"); return; } // 获取要素并检查有效性 IFeature feature = featureLayer.FeatureClass.GetFeature(oid); if (feature == null || feature.Shape == null) { MessageBox.Show("要素 OID {oid} 不存在或无几何!"); return; } IGeometry geometry = feature.Shape; IEnvelope envelope = geometry.Envelope; // 确保包络线有效 if (envelope.IsEmpty || envelope.Width == 0 || envelope.Height == 0) { envelope.Expand(10, 10, true); // 手动扩大点要素范围 } else { envelope.Expand(1.5, 1.5, true); } // 缩放到要素范围 axMapControl1.Extent = envelope; axMapControl1.ActiveView.ScreenDisplay.UpdateWindow(); // 高亮几何 HighlightGeometry(geometry); } catch (Exception ex) { MessageBox.Show("高亮要素失败: {ex.Message}"); } } public object _featureLayer { get; set; } // 矩形选择 private void btnRectSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Rectangle; axMapControl1.CurrentTool = null; } // 圆形选择 private void btnCircleSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Circle; axMapControl1.CurrentTool = null; } // 多边形选择 private void btnPolygonSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polygon; axMapControl1.CurrentTool = null; } // 折线选择 private void btnLineSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polyline; axMapControl1.CurrentTool = null; } // 地图鼠标按下事件 private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { try { IGeometry geometry = null; switch (currentMode) { case SelectionMode.Rectangle: // 绘制矩形(返回的是IEnvelope) geometry = axMapControl1.TrackRectangle(); break; case SelectionMode.Circle: IEnvelope envelope = axMapControl1.TrackRectangle(); if (envelope.Width <= 0 || envelope.Height <= 0) { MessageBox.Show("请拖拽有效的矩形范围以创建圆形!"); return; } // 创建圆心点 IPoint center = new PointClass(); center.PutCoords( (envelope.XMin + envelope.XMax) / 2, (envelope.YMin + envelope.YMax) / 2 ); // 计算半径(取矩形宽高的平均值) double radius = Math.Max(envelope.Width, envelope.Height) / 2; // 创建圆形几何 ICircularArc circularArc = new CircularArcClass(); IConstructCircularArc constructArc = (IConstructCircularArc)circularArc; constructArc.ConstructCircle(center, radius, true); // 将圆弧转换为多边形 ISegmentCollection segColl = new PolygonClass(); segColl.AddSegment((ISegment)circularArc); geometry = (IGeometry)segColl; geometry.SpatialReference = axMapControl1.SpatialReference; break; case SelectionMode.Polygon: // 绘制多边形 geometry = axMapControl1.TrackPolygon(); break; case SelectionMode.Polyline: // 绘制折线 geometry = axMapControl1.TrackLine(); break; } if (geometry != null) { PerformSpatialSelection(geometry); HighlightGeometry(geometry); } } catch (Exception ex) { MessageBox.Show("操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 执行空间选择 private void PerformSpatialSelection(IGeometry geometry) { try { IMap map = axMapControl1.Map; if (map == null) return; map.ClearSelection(); for (int i = 0; i < map.LayerCount; i++) { IFeatureLayer featureLayer = map.get_Layer(i) as IFeatureLayer; if (featureLayer == null || !featureLayer.Valid || featureLayer.FeatureClass == null) continue; // 检查几何类型是否支持空间查询 if (geometry.GeometryType == esriGeometryType.esriGeometryPoint && featureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPoint) continue; ISpatialFilter filter = new SpatialFilterClass { Geometry = geometry, GeometryField = featureLayer.FeatureClass.ShapeFieldName, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects }; IFeatureSelection selection = (IFeatureSelection)featureLayer; selection.SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultNew, false); } axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null); } catch (Exception ex) { MessageBox.Show("空间查询失败: {ex.Message}"); } } // 高亮显示选择图形(修复版) private void HighlightGeometry(IGeometry geometry) { if (geometry == null || geometry.IsEmpty) { MessageBox.Show("几何无效!"); return; } IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer; graphicsContainer.DeleteAllElements(); // 清除旧图形 // 创建符号和元素 IElement element = null; ISymbol symbol = null; switch (geometry.GeometryType) { case esriGeometryType.esriGeometryPolygon: case esriGeometryType.esriGeometryEnvelope: ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass { Color = GetRgbColor(255, 0, 0, 80), Style = esriSimpleFillStyle.esriSFSSolid }; fillSymbol.Outline = new SimpleLineSymbolClass { Color = GetRgbColor(255, 0, 0), Width = 2 }; symbol = (ISymbol)fillSymbol; element = new PolygonElementClass(); break; case esriGeometryType.esriGeometryPolyline: ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass { Color = GetRgbColor(255, 0, 0), Width = 3 }; symbol = (ISymbol)lineSymbol; element = new LineElementClass(); break; case esriGeometryType.esriGeometryPoint: ISimpleMarkerSymbol markerSymbol = new SimpleMarkerSymbolClass { Color = GetRgbColor(255, 0, 0), Size = 12, Style = esriSimpleMarkerStyle.esriSMSCircle }; symbol = (ISymbol)markerSymbol; element = new MarkerElementClass(); break; } if (element != null && symbol != null) { element.Geometry = geometry; graphicsContainer.AddElement(element, 0); axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } } private IColor GetRgbColor(int p, int p_2, int p_3, int p_4) { throw new NotImplementedException(); } // 创建颜色对象 private IRgbColor GetRGBColor(int r, int g, int b, int alpha = 255) { IRgbColor color = new RgbColorClass(); color.Red = r; color.Green = g; color.Blue = b; color.Transparency = (byte)(255 - alpha); return color; } // 清除选择 private void btnClearSelection_Click(object sender, EventArgs e) { axMapControl1.Map.ClearSelection(); IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer; graphicsContainer.DeleteAllElements(); axMapControl1.Refresh(); } // 新增双击事件处理 private void axMapControl1_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e) { if (currentMode != SelectionMode.None) { currentMode = SelectionMode.None; axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault; } } // 添加量测按钮点击事件 private void btnMeasureArea_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Area); lblMeasureResult.Text = "状态:绘制多边形(双击结束)"; } private void btnMeasureLength_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Length); lblMeasureResult.Text = "状态:绘制折线(双击结束)"; } private void btnMeasurePoint_Click(object sender, EventArgs e) { ResetMeasureMode(MeasureMode.Point); lblMeasureResult.Text = "状态:移动鼠标查看坐标"; } private void ResetMeasureMode(MeasureMode mode) { currentMeasureMode = mode; ClearTempGraphics(); axMapControl1.CurrentTool = null; axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; } private void ClearTempGraphics() { throw new NotImplementedException(); } // 修改后的地图鼠标事件处理 private void axMapControl1_OnMouseDown2(object sender, IMapControlEvents2_OnMouseDownEvent e) { try { if (currentMeasureMode == MeasureMode.None) return; IPoint currentPoint = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y); switch (currentMeasureMode) { case MeasureMode.Area: case MeasureMode.Length: if (pointCollection == null) { // 🟢 根据模式创建不同几何类型 pointCollection = currentMeasureMode == MeasureMode.Area ? (IPointCollection)new PolygonClass() : (IPointCollection)new PolylineClass(); pointCollection.AddPoint(currentPoint); } pointCollection.AddPoint(currentPoint); DrawTempGeometry(); break; } } catch (Exception ex) { MessageBox.Show("操作错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void DrawTempGeometry() { throw new NotImplementedException(); } } }using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Geodatabase; namespace WaterPipelineGIS2 { public partial class AttributeTableForm : Form { private IFeatureLayer _featureLayer; private Form1 _mainForm; // 主窗体引用 public AttributeTableForm(IFeatureLayer featureLayer, Form1 mainForm) { InitializeComponent(); _featureLayer = featureLayer; _mainForm = mainForm; // 绑定数据 BindData(); // 绑定行选择事件 dgvAttributes.SelectionChanged += DgvAttributes_SelectionChanged; // 添加行双击事件 dgvAttributes.CellDoubleClick += (s, args) => { if (args.RowIndex >= 0) { int oid = Convert.ToInt32(dgvAttributes.Rows[args.RowIndex].Cells[0].Value); _mainForm.ActivateFeatureLayer(_featureLayer); _mainForm.HighlightAndZoomToFeature(_featureLayer, oid); } }; } private void DgvAttributes_SelectionChanged(object sender, EventArgs e) { if (dgvAttributes.SelectedRows.Count == 0) return; // 获取当前行的 OID int oid = Convert.ToInt32(dgvAttributes.SelectedRows[0].Cells[0].Value); // 激活主窗体的图层 _mainForm.ActivateFeatureLayer(_featureLayer); // 调用主窗体的高亮方法(传递当前图层) _mainForm.HighlightAndZoomToFeature(_featureLayer, oid); } private void BindData() { IFeatureCursor cursor = _featureLayer.FeatureClass.Search(null, true); DataTable dataTable = new DataTable(); // 添加 OID 字段(关键修改:使用要素类的 OID 字段名) dataTable.Columns.Add(_featureLayer.FeatureClass.OIDFieldName, typeof(int)); // 自动获取系统 OID 字段名 // 添加其他字段 for (int i = 0; i < cursor.Fields.FieldCount; i++) { IField field = cursor.Fields.get_Field(i); if (field.Type == esriFieldType.esriFieldTypeOID) continue; // 跳过已添加的 OID 字段 dataTable.Columns.Add(field.Name, GetFieldType(field.Type)); } // 填充数据 IFeature feature; while ((feature = cursor.NextFeature()) != null) { DataRow row = dataTable.NewRow(); row[0] = feature.OID; // 直接使用 OID 属性 for (int i = 0; i < cursor.Fields.FieldCount; i++) { IField field = cursor.Fields.get_Field(i); if (field.Type == esriFieldType.esriFieldTypeOID) continue; row[field.Name] = feature.get_Value(i) ?? DBNull.Value; } dataTable.Rows.Add(row); } dgvAttributes.DataSource = dataTable; } // 辅助方法:将 ArcGIS 字段类型转换为 .NET 类型 private Type GetFieldType(esriFieldType fieldType) { switch (fieldType) { case esriFieldType.esriFieldTypeString: return typeof(string); case esriFieldType.esriFieldTypeInteger: return typeof(int); case esriFieldType.esriFieldTypeDouble: return typeof(double); case esriFieldType.esriFieldTypeDate: return typeof(DateTime); default: return typeof(string); } } } } 此代码能进行空间选择,但是绘制后会弹出报错窗口,且之前绘制后会暂时留下的红色区域不见了,如何解决
最新发布
07-13
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Display; namespace WaterPipelineGIS2 { public partial class Form1 : Form { private IFeatureLayer _selectedFeatureLayer; private System.Drawing.Point _lastRightClickPosition; private enum SelectionMode { None, Rectangle, Circle, Polygon, Polyline } private SelectionMode currentMode = SelectionMode.None; public Form1() { InitializeComponent(); axMapControl1.OnMouseMove += new IMapControlEvents2_Ax_OnMouseMoveEventHandler(axMapControl1_OnMouseMove); } private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e) { // 获取地图坐标 double mapX = e.mapX; double mapY = e.mapY; // 格式化坐标显示(保留3位小数) lblCoordinate.Text = string.Format("X: {0:F3} Y: {1:F3}", mapX, mapY); // 立即刷新状态栏 statusStrip1.Refresh(); } private void toolStripMenuItem2_Click(object sender, EventArgs e) { using (var rotateForm = new RotateForm()) { if (rotateForm.ShowDialog() == DialogResult.OK) { try { axMapControl1.Rotation = rotateForm.RotationAngle; axMapControl1.ActiveView.Refresh(); // 可选:更新状态栏 lblCoordinate.Text += " 旋转角度:{rotateForm.RotationAngle}°"; } catch (Exception ex) { MessageBox.Show("旋转失败:{ex.Message}"); } } } } private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { if (e.button == 2) // 右键 { // 保存点击位置(控件坐标系) _lastRightClickPosition = new System.Drawing.Point(e.x, e.y); ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; // 修改点1:声明为接口类型并初始化为null IBasicMap basicMap = null; ILayer layer = null; // 修改点2:使用Type.Missing代替new object() object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; // 修改点3:正确传递ref参数 tocControl.HitTest(e.x, e.y, ref itemType, ref basicMap, ref layer, ref other, ref index); if (itemType == esriTOCControlItem.esriTOCControlItemLayer && layer != null) { contextMenuStripTOC.Show(axTOCControl1, e.x, e.y); } } } // 修改后(使用 MouseEventArgs) private void openAttributeTableToolStripMenuItem_Click(object sender, EventArgs e) { ITOCControl2 tocControl = (ITOCControl2)axTOCControl1.Object; IBasicMap basicMap = null; ILayer layer = null; object other = Type.Missing; object index = Type.Missing; esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone; // 使用保存的控件坐标系位置 tocControl.HitTest( _lastRightClickPosition.X, _lastRightClickPosition.Y, ref itemType, ref basicMap, ref layer, ref other, ref index ); IFeatureLayer featureLayer = layer as IFeatureLayer; if (featureLayer != null) { _selectedFeatureLayer = featureLayer; // 确保使用正确的构造函数 AttributeTableForm attrForm = new AttributeTableForm( _selectedFeatureLayer, axMapControl1.Object as IMapControl2 ); attrForm.Show(); } else { MessageBox.Show("请选择有效的要素图层!"); } } private void SetSelectionSymbol() { // 使用接口创建符号 ISimpleFillSymbol fillSymbol = new SimpleFillSymbol() as ISimpleFillSymbol; fillSymbol.Color = GetRgbColor(255, 0, 0); fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; ISimpleLineSymbol lineSymbol = new SimpleLineSymbol() as ISimpleLineSymbol; lineSymbol.Color = GetRgbColor(255, 255, 0); lineSymbol.Width = 2; fillSymbol.Outline = lineSymbol; // 设置渲染器 if (_selectedFeatureLayer != null) { IGeoFeatureLayer geoLayer = (IGeoFeatureLayer)_selectedFeatureLayer; ISimpleRenderer renderer = new SimpleRenderer() as ISimpleRenderer; renderer.Symbol = (ISymbol)fillSymbol; geoLayer.Renderer = (IFeatureRenderer)renderer; axMapControl1.ActiveView.Refresh(); } } private IRgbColor GetRgbColor(int r, int g, int b) { IRgbColor color = new RgbColor() as IRgbColor; // 正确方式 color.Red = r; color.Green = g; color.Blue = b; return color; } public object _featureLayer { get; set; } // 矩形选择 private void btnRectSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Rectangle; axMapControl1.CurrentTool = null; } // 圆形选择 private void btnCircleSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Circle; axMapControl1.CurrentTool = null; } // 多边形选择 private void btnPolygonSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polygon; axMapControl1.CurrentTool = null; } // 折线选择 private void btnLineSelect_Click(object sender, EventArgs e) { currentMode = SelectionMode.Polyline; axMapControl1.CurrentTool = null; } // 地图鼠标按下事件 private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { try { IGeometry geometry = null; switch (currentMode) { case SelectionMode.Rectangle: // 绘制矩形 geometry = axMapControl1.TrackRectangle(); break; case SelectionMode.Circle: // 获取用户拖拽的矩形范围 IEnvelope envelope = axMapControl1.TrackRectangle(); // 创建圆心点 IPoint center = new PointClass(); center.PutCoords(envelope.XMin + envelope.Width / 2, envelope.YMin + envelope.Height / 2); // 正确创建圆形几何(修复部分) ICircularArc circularArc = new CircularArcClass(); IConstructCircularArc constructArc = (IConstructCircularArc)circularArc; double radius = Math.Min(envelope.Width, envelope.Height) / 2; constructArc.ConstructCircle(center, radius, true); // 创建多边形表示圆形 IGeometryCollection geomColl = new PolygonClass(); geomColl.AddGeometry((IGeometry)circularArc); geometry = (IGeometry)geomColl; geometry.SpatialReference = axMapControl1.SpatialReference; break; case SelectionMode.Polygon: // 绘制多边形 geometry = axMapControl1.TrackPolygon(); break; case SelectionMode.Polyline: // 绘制折线 geometry = axMapControl1.TrackLine(); break; } if (geometry != null) { PerformSpatialSelection(geometry); HighlightGeometry(geometry); } } catch (Exception ex) { MessageBox.Show("操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 执行空间选择 private void PerformSpatialSelection(IGeometry geometry) { IMap map = axMapControl1.Map; // 创建空间过滤器 ISpatialFilter spatialFilter = new SpatialFilterClass(); spatialFilter.Geometry = geometry; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; // 清除之前的选择 map.ClearSelection(); // 遍历所有图层执行选择 for (int i = 0; i < map.LayerCount; i++) { IFeatureLayer featureLayer = map.get_Layer(i) as IFeatureLayer; if (featureLayer == null) continue; spatialFilter.GeometryField = featureLayer.FeatureClass.ShapeFieldName; IFeatureSelection featureSelection = (IFeatureSelection)featureLayer; featureSelection.SelectFeatures(spatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false); } axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null); } // 高亮显示选择图形 private void HighlightGeometry(IGeometry geometry) { IMap map = axMapControl1.Map; IActiveView activeView = map as IActiveView; IGraphicsContainer graphicsContainer = map as IGraphicsContainer; // 清除之前的高亮 graphicsContainer.DeleteAllElements(); // 创建高亮符号 ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass(); fillSymbol.Color = GetRGBColor(255, 0, 0, 50); // 半透明红色 fillSymbol.Outline.Color = GetRGBColor(0, 0, 255); ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = GetRGBColor(0, 0, 255); lineSymbol.Width = 2; // 创建元素 IElement element = null; if (geometry.GeometryType == esriGeometryType.esriGeometryPolygon) { IFillShapeElement fillElement = new PolygonElementClass(); fillElement.Symbol = fillSymbol; element = (IElement)fillElement; } else if (geometry.GeometryType == esriGeometryType.esriGeometryPolyline) { ILineElement lineElement = new LineElementClass(); lineElement.Symbol = lineSymbol; element = (IElement)lineElement; } else if (geometry.GeometryType == esriGeometryType.esriGeometryPoint) { // 圆形选择使用点符号 IMarkerElement markerElement = new MarkerElementClass(); ISimpleMarkerSymbol markerSymbol = new SimpleMarkerSymbolClass(); markerSymbol.Color = fillSymbol.Color; markerSymbol.Size = 10; markerElement.Symbol = markerSymbol; element = (IElement)markerElement; } if (element != null) { element.Geometry = geometry; graphicsContainer.AddElement(element, 0); activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } } // 创建颜色对象 private IRgbColor GetRGBColor(int r, int g, int b, int alpha = 255) { IRgbColor color = new RgbColorClass(); color.Red = r; color.Green = g; color.Blue = b; color.Transparency = (byte)(255 - alpha); return color; } // 清除选择 private void btnClearSelection_Click(object sender, EventArgs e) { axMapControl1.Map.ClearSelection(); IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer; graphicsContainer.DeleteAllElements(); axMapControl1.Refresh(); } } }还是点击空间选择中的多边形选择、圆形选择等无法进行选择呢,如何结局
07-12
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值