ArcGIS Pro二次开发-画线分割面工具

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Extensions;
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using System.Windows.Input;





namespace ProAppModule1
{
    internal class MapToolSelect : MapTool
    {
        public MapToolSelect()

        {

            // select the type of construction tool you wish to implement.  

            // Make sure that the tool is correctly registered with the correct component category type in the daml

            SketchType = SketchGeometryType.Line;

            // a sketch feedback is need

            IsSketchTool = true;

            // the geometry is needed in map coordinates

            SketchOutputMode = ArcGIS.Desktop.Mapping.SketchOutputMode.Map;

        }



        /// <summary>

        /// Called when the sketch finishes. This is where we will create the sketch 

        /// operation and then execute it.

        /// </summary>

        /// <param name="geometry">The geometry created by the sketch.</param>

        /// <returns>A Task returning a Boolean indicating if the sketch complete event 

        /// was successfully handled.</returns>

        protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)

        {

            return QueuedTask.Run(() => ExecuteCut(geometry));

        }



        /// <summary>

        /// Method to perform the cut operation on the geometry and change attributes

        /// </summary>

        /// <param name="geometry">Line geometry used to perform the cut against in the polygon features

        /// in the active map view.</param>

        /// <returns>If the cut operation was successful.</returns>

        protected Task<bool> ExecuteCut(Geometry geometry)

        {

            if (geometry == null)

                return Task.FromResult(false);



            // create a collection of feature layers that can be edited

            var editableLayers = ActiveMapView.Map.GetLayersAsFlattenedList()

                .OfType<FeatureLayer>()

                .Where(lyr => lyr.CanEditData() == true).Where(lyr =>

                lyr.ShapeType == esriGeometryType.esriGeometryPolygon);



            // ensure that there are target layers

            if (editableLayers.Count() == 0)

                return Task.FromResult(false);



            // create an edit operation

            EditOperation cutOperation = new EditOperation()

            {

                Name = "Cut Elements",

                ProgressMessage = "Working...",

                CancelMessage = "Operation canceled.",

                ErrorMessage = "Error cutting polygons",

                SelectModifiedFeatures = false,

                SelectNewFeatures = false

            };



            // initialize a list of ObjectIDs that need to be cut

            var cutOIDs = new List<long>();



            // for each of the layers 

            foreach (FeatureLayer editableFeatureLayer in editableLayers)

            {

                // get the feature class associated with the layer

                Table fc = editableFeatureLayer.GetTable();



                // find the field index for the 'Description' attribute

                int descriptionIndex = -1;

                descriptionIndex = fc.GetDefinition().FindField("Description");



                // find the features crossed by the sketch geometry

                //   use the featureClass to search. We need to be able to search with a recycling cursor

                //     seeing we want to Modify the row results

                using (var rowCursor = fc.Search(geometry, SpatialRelationship.Crosses, false))

                {



                    // add the feature IDs into our prepared list

                    while (rowCursor.MoveNext())

                    {

                        using (var feature = rowCursor.Current as Feature)

                        {

                            var geomTest = feature.GetShape();

                            if (geomTest != null)

                            {

                                // make sure we have the same projection for geomProjected and geomTest

                                var geomProjected = GeometryEngine.Instance.Project(geometry, geomTest.SpatialReference);

                                // we are looking for polygons are completely intersected by the cut line

                                if (GeometryEngine.Instance.Relate(geomProjected, geomTest, "TT*F*****"))

                                {

                                    var oid = feature.GetObjectID();



                                    // add the current feature to the overall list of features to cut

                                    cutOIDs.Add(oid);

                                }

                            }

                        }

                    }

                }



                // adjust the attribute before the cut

                if (descriptionIndex != -1)

                {

                    var atts = new Dictionary<string, object>();

                    atts.Add("Description", "Pro Sample");

                    foreach (var oid in cutOIDs)

                        cutOperation.Modify(editableFeatureLayer, oid, atts);

                }



                // add the elements to cut into the edit operation

                cutOperation.Split(editableFeatureLayer, cutOIDs, geometry);



            }



            //execute the operation

            var operationResult = cutOperation.Execute();



            return Task.FromResult(operationResult);

        }



        /// <summary>

        /// Method to override the sketch symbol after collecting the second vertex

        /// </summary>

        /// <returns>If the sketch symbology was successfully changed.</returns>

        protected override async Task<bool> OnSketchModifiedAsync()

        {

            // retrieve the current sketch geometry

            Polyline cutGeometry = await base.GetCurrentSketchAsync() as Polyline;



            await QueuedTask.Run(() =>

            {

                // if there are more than 2 vertices in the geometry

                if (cutGeometry.PointCount > 2)

                {

                    // adjust the sketch symbol

                    var symbolReference = base.SketchSymbol;

                    if (symbolReference == null)

                    {

                        var cimLineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.RedRGB, 3,

                            SimpleLineStyle.DashDotDot);

                        base.SketchSymbol = cimLineSymbol.MakeSymbolReference();

                    }

                    else

                    {

                        symbolReference.Symbol.SetColor(ColorFactory.Instance.RedRGB);

                        base.SketchSymbol = symbolReference;

                    }

                }

            });



            return true;

        }

    }



    /// <summary>

    /// Extension method to search and retrieve rows

    /// </summary>

    public static class SketchExtensions

    {

        /// <summary>

        /// Performs a spatial query against a feature layer.

        /// </summary>

        /// <remarks>It is assumed that the feature layer and the search geometry are using the same spatial reference.</remarks>

        /// <param name="searchLayer">The feature layer to be searched.</param>

        /// <param name="searchGeometry">The geometry used to perform the spatial query.</param>

        /// <param name="spatialRelationship">The spatial relationship used by the spatial filter.</param>

        /// <returns>Cursor containing the features that satisfy the spatial search criteria.</returns>

        public static RowCursor Search(this BasicFeatureLayer searchLayer, Geometry searchGeometry, SpatialRelationship spatialRelationship)

        {

            RowCursor rowCursor = null;



            // define a spatial query filter

            var spatialQueryFilter = new SpatialQueryFilter

            {

                // passing the search geometry to the spatial filter

                FilterGeometry = searchGeometry,

                // define the spatial relationship between search geometry and feature class

                SpatialRelationship = spatialRelationship

            };



            // apply the spatial filter to the feature layer in question

            rowCursor = searchLayer.Search(spatialQueryFilter);



            return rowCursor;

        }



        /// <summary>

        /// Performs a spatial query against a feature class

        /// </summary>

        /// <remarks>It is assumed that the feature layer and the search geometry are using the same spatial reference.</remarks>

        /// <param name="searchFC">The feature class to be searched.</param>

        /// <param name="searchGeometry">The geometry used to perform the spatial query.</param>

        /// <param name="spatialRelationship">The spatial relationship used by the spatial filter.</param>

        /// <param name="useRecyclingCursor"></param>

        /// <returns>Cursor containing the features that satisfy the spatial search criteria.</returns>

        public static RowCursor Search(this Table searchFC, Geometry searchGeometry, SpatialRelationship spatialRelationship, bool useRecyclingCursor)

        {

            RowCursor rowCursor = null;



            // define a spatial query filter

            var spatialQueryFilter = new SpatialQueryFilter

            {

                // passing the search geometry to the spatial filter

                FilterGeometry = searchGeometry,

                // define the spatial relationship between search geometry and feature class

                SpatialRelationship = spatialRelationship

            };



            // apply the spatial filter to the feature layer in question

            rowCursor = searchFC.Search(spatialQueryFilter, useRecyclingCursor);



            return rowCursor;

        }

    }

}
原文地址:https://www.cnblogs.com/gisoracle/p/12467400.html