private Task OnBeforeSketchCompletedEvent(BeforeSketchCompletedEventArgs arg) { //replace curved sketch segments with straight segments //return if sketch geometry is not polygon or polyline if (!(arg.Sketch.GeometryType == GeometryType.Polyline || arg.Sketch.GeometryType == GeometryType.Polygon)) { return(Task.CompletedTask); } var sketchMP = arg.Sketch as Multipart; //if the sketch doesnt have curves then return if (!sketchMP.HasCurves) { return(Task.CompletedTask); } //itterate through each sketch part var newParts = new List <List <Segment> >(); foreach (var sketchPart in sketchMP.Parts) { //itterate through each sketch segment var newSegments = new List <Segment>(); foreach (var sketchSegment in sketchPart) { if (sketchSegment.IsCurve) { newSegments.Add(LineBuilderEx.CreateLineSegment(sketchSegment.StartPoint, sketchSegment.EndPoint)); } else { newSegments.Add(sketchSegment); } } newParts.Add(newSegments); } //create the new sketch geometry based on sketch type and set back on the sketch if (arg.Sketch.GeometryType == GeometryType.Polyline) { var polyline = PolylineBuilderEx.CreatePolyline(newParts, AttributeFlags.None); arg.SetSketchGeometry(polyline); } else { var polygon = PolygonBuilderEx.CreatePolygon(newParts, AttributeFlags.None); arg.SetSketchGeometry(polygon); } return(Task.CompletedTask); }
protected override void OnClick() { QueuedTask.Run(() => { //Get all the graphics layers in the map var allGraphicsLayers = MapView.Active?.Map?.GetLayersAsFlattenedList().OfType <GraphicsLayer>(); if (allGraphicsLayers.Count() == 0) { return; } //Get the geometry of the map's extent var geometry = PolygonBuilderEx.CreatePolygon(MapView.Active.Extent); //Keep adding the elements to the selection MapView.Active.SelectElements(geometry, SelectionCombinationMethod.Add); }); }
/// <summary> /// Copy the elements to an offset location /// </summary> /// <param name="graphicsLayer"></param> /// <param name="elements"></param> internal static void CustomCopyElements(this GraphicsLayer graphicsLayer, IEnumerable <Element> elements) { if (elements.Count() == 0) { return; } //Copy the elements. var copyElements = graphicsLayer.CopyElements(elements); //Iterate through the elements to move the anchor point for the copy. foreach (var element in copyElements) { var elementPoly = PolygonBuilderEx.CreatePolygon(element.GetBounds()); var pointsList = elementPoly.Copy2DCoordinatesToList(); element.SetAnchorPoint(pointsList[1]); } }
private Geometry Buffer(Geometry geom, esriGeometryType shapeType, double margin, MaskKind maskKind, bool isAnno = false) { var poly_outline = geom as Polygon; if (poly_outline.HasCurves) { poly_outline = GeometryEngine.Instance.DensifyByDeviation(geom, 0.1 * margin) as Polygon; } if (margin > 0.0) { if (maskKind == MaskKind.Box || maskKind == MaskKind.ConvexHull) { //strip out interior polygons var ext_poly = PolygonBuilderEx.CreatePolygon(poly_outline.GetExteriorRings(true), AttributeFlags.None); var joins = maskKind == MaskKind.Box ? LineJoinType.Miter : LineJoinType.Bevel; var buff_out = GeometryEngine.Instance.GraphicBuffer(ext_poly, margin, joins, LineCapType.Butt, 4, 0.05 * margin, 64); poly_outline = GeometryEngine.Instance.Generalize(buff_out, 0.01 * margin) as Polygon; } else { var buff_out = GeometryEngine.Instance.Buffer(poly_outline, margin); if (maskKind == MaskKind.ExactSimplified) { poly_outline = GeometryEngine.Instance.Generalize(buff_out, 0.05 * margin) as Polygon; } else { poly_outline = buff_out as Polygon; } } } //simplify if needed //return GeometryEngine.Instance.SimplifyAsFeature(poly_outline); return(poly_outline); }
protected override Task <bool> OnSketchCompleteAsync(Geometry geometry) { if (ActiveElementContainer == null) { Task.FromResult(true); } if (Module1.SelectedSymbol == null) { return(Task.FromResult(true)); } return(QueuedTask.Run(() => { ICollection <Segment> segments = null; (geometry as Polygon).GetAllSegments(ref segments); if (segments.Count == 0) { return false; } var ellipticalArcSegment = segments.First() as EllipticArcSegment; //If this cast fails, this is not an ellipse if (ellipticalArcSegment == null) { return false; } var ellipsePolygon = PolygonBuilderEx.CreatePolygon(segments); var ge = ElementFactory.Instance.CreateTextGraphicElement (this.ActiveElementContainer, TextType.EllipseParagraph, ellipsePolygon, Module1.SelectedSymbol as CIMTextSymbol); //The new text graphic element has been created //We now switch to Pro's out of box "esri_layouts_inlineEditTool" //This will allow inline editing of the text //This tool will work on graphics on both map view and layouts FrameworkApplication.SetCurrentToolAsync("esri_layouts_inlineEditTool"); return true; })); }
/// <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) { if (CurrentTemplate == null || geometry == null) { return(Task.FromResult(false)); } return(QueuedTask.Run(() => { //build a circular arc var cent = new Coordinate2D(geometry as MapPoint); var circleEAB = EllipticArcBuilderEx.CreateCircle(cent, Radius, ArcOrientation.ArcClockwise, MapView.Active.Map.SpatialReference); // find the source layer and determine whether polyline/polygon. Create the appropriate shape var lyr = CurrentTemplate.Layer as BasicFeatureLayer; Geometry circleGeom = null; if (lyr.ShapeType == esriGeometryType.esriGeometryPolygon) { circleGeom = PolygonBuilderEx.CreatePolygon(new[] { circleEAB }, AttributeFlags.None); } else { circleGeom = PolylineBuilderEx.CreatePolyline(circleEAB, AttributeFlags.None); } // Create an edit operation var createOperation = new EditOperation(); createOperation.Name = string.Format("Create circular {0}", CurrentTemplate.Layer.Name); createOperation.SelectNewFeatures = true; // Queue feature creation createOperation.Create(CurrentTemplate, circleGeom); // Execute the operation return createOperation.ExecuteAsync(); })); }
protected override Task <bool> OnSketchCompleteAsync(Geometry geometry) { if (ActiveElementContainer == null) { Task.FromResult(true); } if (Module1.SelectedSymbol == null) { return(Task.FromResult(true)); } return(QueuedTask.Run(() => { var centerPt = ((Polygon)geometry).Extent.CenterCoordinate; double circleArea = ((Polygon)geometry).Extent.Area; double radius = Math.Sqrt(circleArea / Math.PI); var circle = EllipticArcBuilderEx.CreateCircle(centerPt, radius, ArcOrientation.ArcClockwise); List <Segment> circleSegments = new List <Segment>() { circle }; var circlePolygon = PolygonBuilderEx.CreatePolygon(circleSegments); var ge = ElementFactory.Instance.CreateTextGraphicElement (this.ActiveElementContainer, TextType.CircleParagraph, circlePolygon, Module1.SelectedSymbol as CIMTextSymbol, "Text" ); //The new text graphic element has been created //We now switch to Pro's out of box "esri_layouts_inlineEditTool" //This will allow inline editing of the text //This tool will work on graphics on both map view and layouts FrameworkApplication.SetCurrentToolAsync("esri_layouts_inlineEditTool"); return true; })); }
protected override void OnClick() { QueuedTask.Run(() => { var allGraphicLayers = MapView.Active.Map.GetLayersAsFlattenedList().OfType <GraphicsLayer>(); foreach (var gl in allGraphicLayers) { var selElements = gl.GetSelectedElements(); if (selElements.Count == 0) { continue; } //Move the element up foreach (var selElement in selElements) { var elementPoly = PolygonBuilderEx.CreatePolygon(selElement.GetBounds()); var pointsList = elementPoly.Copy2DCoordinatesToList(); selElement.SetAnchorPoint(pointsList[1]); } } return(true); }); }
/// <summary> /// This method takes an input multi part geometry and breaks the parts into individual standalone geometries. /// This method must be called on the MCT. Use QueuedTask.Run. /// </summary> /// <param name="inputGeometry">The geometry to be exploded into the individual parts.</param> /// <returns>An enumeration of individual parts as standalone geometries. The type of geometry is maintained, i.e. /// if the input geometry is of type Polyline then each geometry in the return is of type Polyline as well. /// If the input geometry is of type Unknown then an empty list is returned.</returns> /// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks> public IEnumerable <Geometry> MultipartToSinglePart(Geometry inputGeometry) { // list holding the part(s) of the input geometry List <Geometry> singleParts = new List <Geometry>(); // check if the input is a null pointer or if the geometry is empty if (inputGeometry == null || inputGeometry.IsEmpty) { return(singleParts); } // based on the type of geometry, take the parts/points and add them individually into a list switch (inputGeometry.GeometryType) { case GeometryType.Envelope: singleParts.Add(inputGeometry.Clone() as Envelope); break; case GeometryType.Multipatch: singleParts.Add(inputGeometry.Clone() as Multipatch); break; case GeometryType.Multipoint: var multiPoint = inputGeometry as Multipoint; foreach (var point in multiPoint.Points) { // add each point of collection as a standalone point into the list singleParts.Add(point); } break; case GeometryType.Point: singleParts.Add(inputGeometry.Clone() as MapPoint); break; case GeometryType.Polygon: var polygon = inputGeometry as Polygon; foreach (var polygonPart in polygon.Parts) { // use the PolygonBuilder turning the segments into a standalone // polygon instance singleParts.Add(PolygonBuilderEx.CreatePolygon(polygonPart)); } break; case GeometryType.Polyline: var polyline = inputGeometry as Polyline; foreach (var polylinePart in polyline.Parts) { // use the PolylineBuilder turning the segments into a standalone // polyline instance singleParts.Add(PolylineBuilderEx.CreatePolyline(polylinePart)); } break; case GeometryType.Unknown: break; default: break; } return(singleParts); }
protected override async Task <bool> OnSketchCompleteAsync(Geometry geometry) { // get the embedded control var vm = this.EmbeddableControl as ChooseTemplateViewModel; if (vm == null) { return(false); } // ensure there's a template chosen if (vm.SelectedTemplate == null) { vm.ShowMessage("Please choose a layer and template"); return(false); } // clear any message vm.ClearMessage(); var template = vm.SelectedTemplate; BasicFeatureLayer templateLayer = template.Layer as BasicFeatureLayer; if (templateLayer == null) { return(false); } bool result = await QueuedTask.Run(() => { // find the target feature from the geometry click var targetFeatures = MapView.Active.GetFeatures(geometry); if ((targetFeatures == null) || (targetFeatures.ToDictionary().Keys.Count == 0)) { return(false); } // we will use the first feature returned var targetLayer = targetFeatures.ToDictionary().Keys.First(); var targetOID = targetFeatures[targetLayer][0]; // At 2.4, EditOperation.TransferAttributes method is one of the few functions which honors the field mapping. // The only method signature for EditOperation.TransferAttributes requires a source and target feature // So our workflow will be // 1. Create a temporary feature using the chosen template and empty geometry // 2. Call TransferAttributes from the temporary feature to the target feature // 3. Delete the temporary feature // build an empty geometry according to the correct template layer type Geometry emptyGeometry = null; switch (templateLayer.ShapeType) { case esriGeometryType.esriGeometryPoint: emptyGeometry = MapPointBuilderEx.CreateMapPoint(); break; case esriGeometryType.esriGeometryPolyline: emptyGeometry = PolylineBuilderEx.CreatePolyline(); break; case esriGeometryType.esriGeometryPolygon: emptyGeometry = PolygonBuilderEx.CreatePolygon(); break; } // some other geometry type if (emptyGeometry == null) { return(false); } // create the temporary feature using the empty geometry var op = new EditOperation(); op.Name = "Transfer attributes from template"; // note Create signature.. we are interested in the new ObjectID var rowToken = op.Create(template, emptyGeometry); // execute var opResult = op.Execute(); // if create was successful if (opResult) { var newObjectID = rowToken.ObjectID.Value; // chain to create a new operation var opChain = op.CreateChainedOperation(); // transfer the attributes between the temporary feature and the target feature opChain.TransferAttributes(templateLayer, newObjectID, targetLayer, targetOID); // and now delete the temporary feature opChain.Delete(templateLayer, newObjectID); opResult = opChain.Execute(); } return(opResult); }); return(result); }