internal static Geometry MakeFishnetPolygon(Polygon inputPoly)
        {
            Envelope envPoly  = inputPoly.Extent;
            var      interval = GetFishnetIntervalDistance(envPoly);
            var      pb       = new PolygonBuilderEx(inputPoly.SpatialReference)
            {
                HasZ = true
            };

            for (var dX = envPoly.XMin; dX < envPoly.XMax + interval; dX += interval)
            {
                for (var dY = envPoly.YMin; dY < envPoly.YMax + interval; dY += interval)
                {
                    var cutEnv = EnvelopeBuilderEx.CreateEnvelope(dX, dY, dX + interval, dY + interval, envPoly.SpatialReference);
                    if (GeometryEngine.Instance.Intersects(cutEnv, inputPoly))
                    {
                        var addPolygonPart = GeometryEngine.Instance.Clip(inputPoly, cutEnv) as Polygon;
                        if (addPolygonPart.Area < 0)
                        {
                            System.Diagnostics.Debug.WriteLine($@"area: {addPolygonPart.Area}");
                        }
                        pb.AddPart(addPolygonPart.Points);
                    }
                }
            }
            return(pb.ToGeometry());
        }
        protected override void OnClick()
        {
            QueuedTask.Run(async() =>
            {
                //get sketch geometry
                var sketchGeom = await MapView.Active.GetCurrentSketchAsync();

                //return if the sketch doesn't have enough points for its geometry type
                if ((sketchGeom.GeometryType == GeometryType.Polygon && sketchGeom.PointCount < 3) || (sketchGeom.GeometryType == GeometryType.Polyline && sketchGeom.PointCount < 2))
                {
                    return;
                }

                //get the sketch as a point collection
                var pointCol = ((Multipart)sketchGeom).Points;

                //get the last point in the sketch based on its geometry type
                var lastSketchPoint = pointCol[(sketchGeom.GeometryType == GeometryType.Polygon) ? pointCol.Count - 2 : pointCol.Count - 1];

                //build a geometry with the last sketch point and set the sketch
                if (sketchGeom.GeometryType == GeometryType.Polygon)
                {
                    //sketch polygons need two points for the initial feedback to work
                    var sketchPoly = new PolygonBuilderEx(new[] { lastSketchPoint, lastSketchPoint }, AttributeFlags.None);
                    await MapView.Active.SetCurrentSketchAsync(sketchPoly.ToGeometry());
                }
                else
                {
                    var sketchPolyline = new PolylineBuilderEx(new[] { lastSketchPoint }, AttributeFlags.None);
                    await MapView.Active.SetCurrentSketchAsync(sketchPolyline.ToGeometry());
                }
            });
        }
        private static Geometry GetGeometryFromBuffer(byte[] geomBuffer, SpatialReference sr)
        {
            var geomType = GetGeometryType(geomBuffer);

            switch (geomType)
            {
            case GeometryType.Point:
            {
                int    offset = 4;
                double x      = DoubleWithNaN(BitConverter.ToDouble(geomBuffer, offset));
                offset += 8;
                double y = DoubleWithNaN(BitConverter.ToDouble(geomBuffer, offset));

                var mp = MapPointBuilderEx.FromEsriShape(geomBuffer, sr);
                //System.Diagnostics.Debug.WriteLine($@"x: {x} = {mp.X} y: {y} = {mp.Y}");
                return(mp);
            }

            case GeometryType.Polyline:
            {
                var line = PolylineBuilderEx.FromEsriShape(geomBuffer, sr);
                return(line);
            }

            case GeometryType.Polygon:
            {
                var poly = PolygonBuilderEx.FromEsriShape(geomBuffer, sr);
                return(poly);
            }
            }
            return(null);
        }
        /// <summary>
        /// The methods retrieves the outer ring(s) of the input polygon.
        /// This method must be called on the MCT. Use QueuedTask.Run.
        /// </summary>
        /// <param name="inputPolygon">Input Polygon.</param>
        /// <returns>The outer most (exterior, clockwise) ring(s) of the polygon. If the input is null or empty, a null pointer is returned.</returns>
        /// <remarks>This method must be called on the MCT. Use QueuedTask.Run.</remarks>
        public Polygon GetOutermostRings(Polygon inputPolygon)
        {
            if (inputPolygon == null || inputPolygon.IsEmpty)
            {
                return(null);
            }

            // create a polygonbuilder - ensure it has the same spatial reference as the source polygon
            var            outerRings    = new PolygonBuilderEx(inputPolygon.SpatialReference);
            List <Polygon> internalRings = new List <Polygon>();

            // explode the parts of the polygon into a list of individual geometries
            var parts = MultipartToSinglePart(inputPolygon);

            // get an enumeration of clockwise geometries (area > 0) ordered by the area
            var clockwiseParts = parts.Where(geom => ((Polygon)geom).Area > 0).OrderByDescending(geom => ((Polygon)geom).Area);

            // for each of the exterior rings
            foreach (var part in clockwiseParts)
            {
                // add the first (the largest) ring into the internal collection
                if (internalRings.Count == 0)
                {
                    internalRings.Add(part as Polygon);
                }

                // use flag to indicate if current part is within the already selection polygons
                bool isWithin = false;

                foreach (var item in internalRings)
                {
                    if (GeometryEngine.Instance.Within(part, item))
                    {
                        isWithin = true;
                    }
                }

                // if the current polygon is not within any polygon of the internal collection
                // then it is disjoint and needs to be added to
                if (isWithin == false)
                {
                    internalRings.Add(part as Polygon);
                }
            }

            // now assemble a new polygon geometry based on the internal polygon collection
            foreach (var ring in internalRings)
            {
                outerRings.AddParts(ring.Parts);
            }

            // return the final geometry of the outer rings
            return(outerRings.ToGeometry());
        }
        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);
        }
        /// <summary>
        /// Create a circular polygon around a mappoint for with a radius in pixels.
        /// </summary>
        /// <param name="mapPoint">Center of the circle as a mappoint.</param>
        /// <param name="pixels">Circle radius in screen pixels.</param>
        /// <returns>A polygon geometry.</returns>
        private Polygon CreateSearchPolygon(MapPoint mapPoint, int pixels)
        {
            //get search radius
            var screenPoint       = MapView.Active.MapToScreen(mapPoint);
            var radiusScreenPoint = new System.Windows.Point((screenPoint.X + pixels), screenPoint.Y);
            var radiusMapPoint    = MapView.Active.ScreenToMap(radiusScreenPoint);
            var searchRadius      = GeometryEngine.Instance.Distance(mapPoint, radiusMapPoint);

            //build a search circle geometry
            var cent       = new Coordinate2D(mapPoint);
            var searchGeom = EllipticArcBuilderEx.CreateCircle(cent, searchRadius, ArcOrientation.ArcClockwise, MapView.Active.Map.SpatialReference);
            var searchPB   = new PolygonBuilderEx(new[] { searchGeom }, AttributeFlags.None);

            return(searchPB.ToGeometry());
        }
 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);
     });
 }
        protected override void OnClick()
        {
            QueuedTask.Run(() =>
            {
                //creates a crowd planning zone
                var cpLayer = MapView.Active.Map.FindLayers("CrowdPlanning").FirstOrDefault() as FeatureLayer;
                var geom    = MapView.Active.Extent.Expand(0.1, 0.1, true);
                var poly    = new PolygonBuilderEx(geom).ToGeometry();

                //create an edit operation and execute
                var editOp  = new EditOperation();
                editOp.Name = "Create crowd plan";
                editOp.Create(cpLayer, poly);
                editOp.Execute();
            });
        }
示例#9
0
        /// <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]);
            }
        }
示例#10
0
        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();
            }));
        }
示例#13
0
        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);
        }