C#ArcEngine二次开发如何实现Arcmap中编辑器里面的部分功能

C#ArcEngine二次开发如何实现Arcmap中编辑器里面的部分功能
增加、删除面等功能已经实现,我需要类似Arcmap中的“整形要素工具”来协助我修改面要素
感谢

以下内容部分参考ChatGPT模型:
首先,要实现类似ArcMap中的“整形要素工具”,您需要使用ArcObjects的编辑器对象来实现。具体来说,您需要创建一个新的编辑工具类,该类将继承自ESRI.ArcGIS.Desktop.AddIns.Tool类,并实现IEditTask接口。

在您的编辑工具类中,您需要实现OnMouseDown和OnMouseMove事件处理程序以捕获鼠标单击和移动事件。然后,您可以使用IEditor对象来获取当前编辑会话中的活动编辑图层,并使用IEditTask接口中的EditSketch对象来获取当前正在编辑的要素的几何图形。

接下来,您可以使用IEditTask接口提供的一些方法和属性来执行您的编辑操作。例如,您可以使用EditSketch对象中的AddVertex方法向当前正在编辑的要素添加新的顶点,使用MovePoint方法移动现有顶点,使用Cut方法将要素分割为两个要素等等。

最后,您需要在您的编辑工具类中实现OnDoubleClick事件处理程序以完成编辑操作,并将编辑结果保存到编辑会话中。

以下是一个简单的示例,演示如何使用编辑器对象实现“整形要素工具”:

using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Editor;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Desktop.AddIns;

namespace EditTools
{
    public class ReshapeTool : Tool, IEditTask
    {
        private IEditor m_editor;
        private IEditSketch m_editSketch;
        private IFeature m_editFeature;

        public ReshapeTool()
        {
            m_editor = ArcMap.Editor;
        }

        protected override void OnMouseDown(MouseEventArgs arg)
        {
            // Get the active edit layer
            IFeatureLayer editLayer = m_editor.EditLayer as IFeatureLayer;

            if (editLayer == null)
                return;

            // Get the clicked point in map coordinates
            IPoint clickedPoint = ArcMap.Document.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);

            // Get the nearest feature to the clicked point
            m_editFeature = GetNearestFeature(editLayer, clickedPoint);

            if (m_editFeature == null)
                return;

            // Start editing the feature
            m_editor.StartOperation();

            // Get the edit sketch for the feature
            m_editSketch = m_editor as IEditSketch;
            m_editSketch.Geometry = m_editFeature.ShapeCopy;
            m_editSketch.RefreshSketch();

            // Capture mouse move events to reshape the feature
            this.Cursor = Cursors.Cross;
            this.Enabled = true;
        }

        protected override void OnMouseMove(MouseEventArgs arg)
        {
            if (m_editSketch == null)
                return;

            // Get the current mouse position in map coordinates
            IPoint currentPoint = ArcMap.Document.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);

            // Reshape the feature based on the current mouse position
            m_editSketch.MovePoint(m_editSketch.PointCount - 1, currentPoint);
            m_editSketch.RefreshSketch();
        }

        protected override void OnDoubleClick()
        {
            if (m_editSketch == null)
                return;

            // Finish editing the feature
            m_editor.StopOperation("Reshape Feature");
            m_editor.Map.SelectFeature(m_editor.EditLayer, m_editFeature);

            // Clear the edit sketch
            m_editSketch.Geometry = null;
            m_editSketch.RefreshSketch();

            // Reset the cursor and tool state
            this.Cursor = Cursors.Default;
            this.Enabled = false;
        }

        #region IEditTask Members

        public void Activate()
        {
            // Nothing to do
        }

        public void Deactivate()
        {
            // Nothing to do
        }

        public void Delete()
        {
            // Nothing to do
        }

        public void FinishSketch()
        {
            // Nothing to do
        }

        public void RefreshSketch()
        {
            // Nothing to do
        }

        public void StartSketch(IGeometry geometry)
        {
            // Nothing to do
        }

        public void UpdateSketch(IGeometry geometry)
        {
            // Nothing to do
        }

        #endregion

        private IFeature GetNearestFeature(IFeatureLayer layer, IPoint point)
        {
            // Get a search envelope around the clicked point
            IEnvelope searchEnvelope = point.Envelope;
            searchEnvelope.Expand(0.1, 0.1, false);

            // Create a spatial filter to search for features within the search envelope
            ISpatialFilter spatialFilter = new SpatialFilterClass();
            spatialFilter.Geometry = searchEnvelope;
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            // Search for features within the search envelope
            IFeatureCursor featureCursor = layer.Search(spatialFilter, false);
            IFeature feature = featureCursor.NextFeature();

            // Get the nearest feature to the clicked point
            double minDistance = double.MaxValue;
            IFeature nearestFeature = null;

            while (feature != null)
            {
                double distance = point.DistanceTo(feature.ShapeCopy as IPoint);

                if (distance < minDistance)
                {
                    minDistance = distance;
                    nearestFeature = feature;
                }

                feature = featureCursor.NextFeature();
            }

            return nearestFeature;
        }
    }
}

在这个示例中,我们创建了一个名为“ReshapeTool”的编辑工具类,它允许用户在单击要素时捕获要素,并在鼠标移动时重新形状要素。要实现这个功能,我们使用了IEditor、IEditTask和IEditSketch等编辑器对象,以及一些编辑操作,如AddVertex、MovePoint和Cut等。我们还使用了GetNearestFeature方法来查找最接近鼠标单击点的要素。

注意,这只是一个简单的示例,您可能需要根据您的具体需求进行一些修改和定制。但是,这个示例应该可以帮助您了解如何使用ArcObjects编辑器对象来实现类似ArcMap中的“整形要素工具”。
如果我的建议对您有帮助、请点击采纳、祝您生活愉快

回答引用new Bing:
以下是一个简单的示例代码,演示如何使用C# ArcEngine中的ITopologicalOperator接口和IEditTool接口实现要素编辑:

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Editor;
using ESRI.ArcGIS.Geometry;

// 获取当前编辑图层和编辑器对象
IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;
IFeatureLayer featureLayer = editor.EditWorkspace.GetFeatureLayer("your_featurelayer_name");

// 定义拓扑操作类型
esriTopologyRuleType topologyRuleType = esriTopologyRuleType.esriTRTAreaNoOverlap;

// 创建整形要素工具对象
IEditTool editTool = new EditTool_Class();
editTool.OnCreate(editor);

// 启动编辑模式
editor.StartOperation();

// 循环选择的面要素,对其进行整形操作
foreach (IFeature feature in editor.EditSelection)
{
    IGeometry geometry = feature.ShapeCopy;
    ITopologicalOperator topoOperator = geometry as ITopologicalOperator;
    IGeometry resultGeom = topoOperator.Buffer(0); // 进行拓扑修复

    // 将处理后的几何图形设置为要素的新几何图形
    feature.Shape = resultGeom;

    // 验证整形操作结果是否符合要求
    if (featureLayer.CheckTopologyRule(topologyRuleType, feature))
    {
        // 提交要素修改
        feature.Store();
    }
}

// 结束编辑操作
editor.StopOperation("Edit Feature");


此示例代码仅供参考,并且可能需要根据您的具体需求进行修改。

引用chatGPT作答,要实现类似 ArcMap 中的 "整形要素工具" 功能,可以使用 ArcEngine 编辑器对象模型(Editor Object Model)中的 "Reshape Feature" 方法。

以下是实现此功能的一些步骤:

1.获取编辑器对象,使用 IEditor 接口。

IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;

2.选择要进行整形操作的面要素,使用 ISelectionSet 接口和 IEditor 接口。

ISelectionSet selectionSet = editor.EditSelection;
IEnumFeature enumFeature = editor.EditSelection as IEnumFeature;
enumFeature.Reset();
IFeature feature = enumFeature.Next();

3.调用 IEditTools2.ReshapeFeature 方法对选定的要素进行整形操作。

IEditTools editTools = editor as IEditTools;
editTools.ReshapeFeature(feature, newPolyline);

其中,newPolyline 是用于整形操作的线要素,它可以使用 IGeometryCollection 接口创建。

完整的代码示例如下:

//获取编辑器对象
IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;

//获取要进行整形操作的面要素
ISelectionSet selectionSet = editor.EditSelection;
IEnumFeature enumFeature = editor.EditSelection as IEnumFeature;
enumFeature.Reset();
IFeature feature = enumFeature.Next();

//创建用于整形的线要素
IGeometryCollection newPolyline = new PolylineClass();
IPointCollection pointCollection = new PolylineClass();
pointCollection.AddPoint(new PointClass() { X = 10, Y = 10 });
pointCollection.AddPoint(new PointClass() { X = 20, Y = 20 });
(newPolyline as IPolyline).AddGeometry(pointCollection as IGeometry);

//对选定的要素进行整形操作
IEditTools editTools = editor as IEditTools;
editTools.ReshapeFeature(feature, newPolyline);

请根据实际需要修改代码中的要素选择方式和线要素创建方式。

该回答引用ChatGPT
要实现类似ArcMap中的整形要素工具,需要进行以下几个步骤:

1. 在编辑器工具栏中添加整形编辑工具按钮,并设置工具的执行时机为编辑器启动时执行。

 c#
// 添加整形编辑工具按钮
ICommandItem reshapeFeatureCmdItem = new ControlsReshapeFeatureToolClass();
reshapeFeatureCmdItem.OnCreate(ESRI.ArcGIS.Framework.app);
ICommand reshapeFeatureCmd = reshapeFeatureCmdItem.Command;
edSvc.AddTool(reshapeFeatureCmd);
edSvc.SetMenu(reshapeFeatureCmd, false);
edSvc.SetTooltip(reshapeFeatureCmd, "整形要素工具");
reshapeFeatureCmd.Caption = "整形要素工具";
reshapeFeatureCmd.Category = "整形要素";
reshapeFeatureCmd.SmallBitmap = new Bitmap(Path.Combine(Application.StartupPath, @"Reshaping\Reshape.bmp"));


2. 在编辑器启动时注册整形编辑工具的事件处理器。

 c#
// 注册整形编辑工具的事件处理器
private IEditEvents_Event m_editEvents;
private void RegisterReshapeEvent()
{
m_editEvents = axMapControl.Map as IEditEvents_Event;
((IEditEvents_Event)m_editEvents).OnReshapeFeature += OnReshapeFeature;
}


3. 在整形编辑工具事件处理器中实现要素的整形编辑操作。

 c#
// 实现要素的整形编辑操作
private void OnReshapeFeature(IObject obj)
{
try
{
// 要素整形编辑操作
IEngineEditSketch pSketch = axMapControl.EditWorkspace as IEngineEditSketch;
IPoint point = pSketch.Vertex;
IFeature feature = obj as IFeature;
IGeometry geometry = feature.Shape;
IHitTest hitTest = geometry as IHitTest;
IPath path = hitTest.HitTest(point, 0.1, esriGeometryHitPartType.esriGeometryPartBoundary, null, null, null, out double hitDist, out int partIndex, out int vertexIndex, out bool inside);
if (path != null)
{
ITopologicalOperator topoOperator = geometry as ITopologicalOperator;
topoOperator.Simplify();
IFeatureEdit2 featureEdit = feature as IFeatureEdit2;
featureEdit.ModifyGeometry(topoOperator.Difference(path));
featureEdit.Update();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}


在整形编辑工具事件处理器中,首先获取当前鼠标位置的点,并获取要素的几何形状。然后使用 HitTest 方法在要素的几何形状上进行击中测试,获取命中的边界路径。使用 Difference 方法将路径从几何形状中剪切出来,并使用 ModifyGeometry 方法将剪切后的几何对象应用到要素上,最后调用 Update 方法更新要素。这样完成整形编辑操作。该回答引用ChatGPT
要实现类似ArcMap中的“整形要素工具”,可以通过C#ArcEngine提供的IEditTask接口来实现。

IEditTask接口是ArcEngine提供的一个编辑任务接口,可以帮助我们实现复杂的编辑操作。利用IEditTask接口,我们可以定义自己的编辑任务,并在ArcMap的编辑器中运行它。

以下是一个简单的示例,演示如何在C#ArcEngine中使用IEditTask接口来实现整形要素工具:

csharp
// 定义一个 IEditTask 接口实现类
public class MyTask : ESRI.ArcGIS.Editor.IEditTask
{
// 在编辑器中选中要素时调用的方法
public void OnCreate(ESRI.ArcGIS.Editor.IEditor Editor)
{
// 获取选中的要素集合
ESRI.ArcGIS.Editor.IEnumFeature selectedFeatures = Editor.EditSelection;
selectedFeatures.Reset();
ESRI.ArcGIS.Geodatabase.IFeature feature = selectedFeatures.Next();

// 遍历每个选中的要素
while (feature != null)
{
// 获取要素的几何图形
ESRI.ArcGIS.Geometry.IPolygon polygon = feature.Shape as ESRI.ArcGIS.Geometry.IPolygon;

// 对几何图形进行整形操作
ESRI.ArcGIS.Geometry.IArea area = polygon as ESRI.ArcGIS.Geometry.IArea;
area.Simplify();
ESRI.ArcGIS.Geometry.ITopologicalOperator2 topoOp = polygon as ESRI.ArcGIS.Geometry.ITopologicalOperator2;
topoOp.IsKnownSimple_2 = false;
topoOp.Simplify();

// 更新要素的几何图形
feature.Shape = polygon;

// 更新要素的属性
feature.Store();

// 获取下一个选中的要素
feature = selectedFeatures.Next();
}
}

// 在编辑器中保存时调用的方法
public void OnSave(ESRI.ArcGIS.Editor.IEditor Editor)
{
// 保存所有修改
Editor.StopOperation("Edit Operation");

// 将编辑器退出编辑模式
Editor.StopEditing(true);
}
}

// 在 ArcMap 中调用编辑任务
public void EditFeature()
{
IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;

// 指定编辑操作名称
editor.StartOperation();

// 激活编辑器的整形要素工具
MyTask myTask = new MyTask();
editor.CurrentTask = myTask;

// 启动编辑器的编辑模式
editor.StartEditing();
}


在上述代码中,我们首先定义了一个MyTask类,它实现了IEditTask接口。在OnCreate方法中,我们获取用户在编辑器中选择的要素,并对每个要素进行整形操作,然后更新要素的几何图形和属性。在OnSave方法中,我们保存所有修改,然后将编辑器退出编辑模式。

最后,我们在EditFeature方法中创建一个编辑器实例,并将整形要素工具设置为当前编辑任务。然后启动编辑器的编辑模式,并在其中完成整形要素的操作。

注意,以上代码仅是一个示例,如果要实现更复杂的功能,需要根据具体情况进行更改和优化。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
实现类似ArcMap中的“整形要素工具”的功能,您需要使用C# ArcObjects中的编辑器对象和几何对象。以下是实现该工具的大体步骤:

  1. 获取编辑器对象
IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;
  1. 获取当前编辑工作空间
IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)editor.EditWorkspace;
  1. 遍历选择集中的要素
IEnumFeature enumFeature = editor.EditSelection;
enumFeature.Reset();
IFeature feature = enumFeature.Next();
while (feature != null)
{
   //对每个要素执行操作  
   feature = enumFeature.Next();
}
  1. 获取要素的几何对象
IGeometry geometry = feature.ShapeCopy;
  1. 将几何对象转换为ITopologicalOperator2
ITopologicalOperator2 topoOperator = geometry as ITopologicalOperator2;
  1. 调用ITopologialOperator2的Simplify方法进行要素整形
IGeometry modifiedGeometry = topoOperator.Simplify();
  1. 更新要素的几何属性
feature.Shape = modifiedGeometry;
  1. 提交编辑
workspaceEdit.StartEditOperation();
feature.Store();
workspaceEdit.StopEditOperation();

下面是完整的代码示例:

IEditor editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;
IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)editor.EditWorkspace;
IEnumFeature enumFeature = editor.EditSelection;
enumFeature.Reset();
IFeature feature = enumFeature.Next();
while (feature != null)
{
   //获取要素的几何对象
   IGeometry geometry = feature.ShapeCopy;
   //将几何对象转换为ITopologicalOperator2
   ITopologicalOperator2 topoOperator = geometry as ITopologicalOperator2;
   //调用ITopologialOperator2的Simplify方法进行要素整形
   IGeometry modifiedGeometry = topoOperator.Simplify();
   //更新要素的几何属性
   feature.Shape = modifiedGeometry;
   //提交编辑
   workspaceEdit.StartEditOperation();
   feature.Store();
   workspaceEdit.StopEditOperation();
   feature = enumFeature.Next();
}

如果我的回答解决了您的问题,请采纳!

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^