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()); } }); }
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()); }
/// <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()); }
/// <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()); }