예제 #1
0
        public void createPolygon(GraphicsOverlay myGraphicsOverlay)
        {
            var rec   = new PolygonBuilder(SpatialReferences.Wgs84);
            var lnSym = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Colors.Red, 2);

            rec.AddPoint(new MapPoint(xMin, yMin));
            rec.AddPoint(new MapPoint(xMin, yMax));
            rec.AddPoint(new MapPoint(xMax, yMax));
            rec.AddPoint(new MapPoint(xMax, yMin));
            myGraphicsOverlay.Graphics.Add(new Graphic(rec.ToGeometry(), lnSym));
            _geom = rec.ToGeometry();
        }
예제 #2
0
        private void GeneratePolyGeometry()
        {
            //PolyCoordinates.ToList()
            List <MapPoint> points = new List <MapPoint>();

            foreach (CoordinateObject coordObject in PolyCoordinates)
            {
                //points.Add(new MapPointBuilder(coordObject.MapPoint.X, coordObject.MapPoint.Y, 0, coordObject.MapPoint.SpatialReference));
                points.Add(coordObject.MapPoint);
            }

            ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                if (GeometryType == GeometryType.Polyline)
                {
                    PolylineBuilder polylineBuilder = new PolylineBuilder(points);
                    polylineBuilder.HasZ            = true;
                    MapGeometry = polylineBuilder.ToGeometry();
                }
                else if (GeometryType == GeometryType.Polygon)
                {
                    PolygonBuilder polygonBuilder = new PolygonBuilder(points);
                    polygonBuilder.HasZ           = true;
                    MapGeometry = polygonBuilder.ToGeometry();
                }
            });
        }
        /// <summary>
        ///     Creates a <see cref="Polygon" /> using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     tokenizer over a stream of text in Well-known Text
        ///     format. The next tokens must form a MultiPolygon.
        /// </param>
        /// <returns>
        ///     a <code>MultiPolygon</code> specified by the next token in the
        ///     stream, or if if the coordinates used to create the <see cref="Polygon" />
        ///     shells and holes do not form closed linestrings.
        /// </returns>
        private static Polygon ReadMultiPolygonText(WktStreamTokenizer tokenizer)
        {
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                throw new Exception("Empty MultiPolygon");
            }

            var polygon = ReadPolygonText(tokenizer);

            var polygons = new PolygonBuilder(polygon);

            var exteriorRingCcw = false;

            // Need to pay attention to whether or not the first exterior ring is CW or CCW, so
            // the other exterior rings match.
            if (polygon.Parts.Count > 0)
            {
                exteriorRingCcw = Algorithms.IsCcw(polygon.Parts[0]);
            }

            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                polygon = ReadPolygonText(tokenizer, exteriorRingCcw, true);
                polygons.AddParts(polygon.Parts);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(polygons.ToGeometry());
        }
        internal static Geometry MakeFishnetPolygon(Polygon inputPoly)
        {
            Envelope envPoly  = inputPoly.Extent;
            var      interval = GetFishnetIntervalDistance(envPoly);
            var      pb       = new PolygonBuilder(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 = EnvelopeBuilder.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());
        }
        private void CreateOverlay()
        {
            // Create polygon builder and add polygon corners into it
            PolygonBuilder builder = new PolygonBuilder(SpatialReferences.WebMercator);
            builder.AddPoint(new MapPoint(-20e5, 20e5));
            builder.AddPoint(new MapPoint(20e5, 20e5));
            builder.AddPoint(new MapPoint(20e5, -20e5));
            builder.AddPoint(new MapPoint(-20e5, -20e5));

            // Get geometry from the builder
            Polygon polygonGeometry = builder.ToGeometry();

            // Create symbol for the polygon
            SimpleFillSymbol polygonSymbol = new SimpleFillSymbol(
                SimpleFillSymbolStyle.Solid,
                System.Drawing.Color.Yellow,
                null);

            // Create new graphic
            Graphic polygonGraphic = new Graphic(polygonGeometry, polygonSymbol);

            // Create overlay to where graphics are shown
            _polygonOverlay = new GraphicsOverlay();
            _polygonOverlay.Graphics.Add(polygonGraphic);

            // Add created overlay to the MapView
            _myMapView.GraphicsOverlays.Add(_polygonOverlay);
        }
예제 #6
0
        /// <summary>
        ///     Writes a multipolygon.
        /// </summary>
        /// <param name="mp">The mulitpolygon to be written.</param>
        /// <param name="bWriter">Stream to write to.</param>
        /// <param name="byteorder">Byte order</param>
        private static void WriteMultiPolygon(Polygon mp, BinaryWriter bWriter, WkbByteOrder byteorder)
        {
            //Write the number of polygons.
            WriteUInt32((uint)mp.Parts.Count, bWriter, byteorder);

            //Loop on the number of polygons.
            for (var i = 0; i < mp.Parts.Count; i++)
            {
                var poly = mp.Parts[i];

                //create a polygon and remember its orientation
                var singlePolygon = new PolygonBuilder(poly);

                var exteriorRingOrientation = Algorithms.IsCcw(poly);

                //Add any interior rings
                while (++i < mp.Parts.Count && Algorithms.IsCcw(mp.Parts[i]) != exteriorRingOrientation)
                {
                    singlePolygon.AddPart(mp.Parts[i]);
                }

                //Write polygon header
                bWriter.Write((byte)byteorder);
                WriteUInt32((uint)WkbGeometryType.WkbPolygon, bWriter, byteorder);
                //Write each polygon.
                WritePolygon(singlePolygon.ToGeometry(), bWriter, byteorder);
            }
        }
    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 PolygonBuilder(new[] { lastSketchPoint,lastSketchPoint });
          await MapView.Active.SetCurrentSketchAsync(sketchPoly.ToGeometry());
        }
        else
        {
          var sketchPolyline = new PolylineBuilder(new[] { lastSketchPoint });
          await MapView.Active.SetCurrentSketchAsync(sketchPolyline.ToGeometry());
        }
      });
    }
예제 #8
0
 private void MySceneView_MouseDoubleClick(object sender, MouseEventArgs e)
 {
     if (type == "line" && mapPoint_list.Count != 0)
     {
         BorderContentText.Visibility = Visibility.Visible;
         var boatPositions = new PolylineBuilder(SpatialReferences.Wgs84);
         for (var i = 0; i < mapPoint_list.Count; i++)
         {
             boatPositions.AddPoint(new MapPoint(mapPoint_list[i].X, mapPoint_list[i].Y));
         }
         var boatRoute = boatPositions.ToGeometry();
         _mapViewModel.Line(boatRoute, "line");
         LineText.Text = "Line Length: " + GeometryEngine.LengthGeodetic(boatRoute).ToString("N2") + " meters";
     }
     else if (type == "area" && mapPoint_list.Count != 0)
     {
         BorderContentText.Visibility = Visibility.Visible;
         var boatPositions = new PolygonBuilder(SpatialReferences.Wgs84);
         for (var i = 0; i < mapPoint_list.Count; i++)
         {
             boatPositions.AddPoint(new MapPoint(mapPoint_list[i].X, mapPoint_list[i].Y));
         }
         var boatRoute = boatPositions.ToGeometry();
         _mapViewModel.Area(boatRoute);
         AreaText.Text = "Area Size: " + GeometryEngine.AreaGeodetic(boatRoute).ToString("N2") + "  square meters";
     }
     mapPoint_list.Clear();
 }
        private void CreateOverlay()
        {
            // Create polygon builder and add polygon corners into it.
            PolygonBuilder builder = new PolygonBuilder(SpatialReferences.WebMercator);

            builder.AddPoint(new MapPoint(-20e5, 20e5));
            builder.AddPoint(new MapPoint(20e5, 20e5));
            builder.AddPoint(new MapPoint(20e5, -20e5));
            builder.AddPoint(new MapPoint(-20e5, -20e5));

            // Get geometry from the builder.
            Polygon polygonGeometry = builder.ToGeometry();

            // Create symbol for the polygon.
            SimpleFillSymbol polygonSymbol = new SimpleFillSymbol(
                SimpleFillSymbolStyle.Solid,
                System.Drawing.Color.Yellow,
                null);

            // Create new graphic.
            Graphic polygonGraphic = new Graphic(polygonGeometry, polygonSymbol);

            // Create overlay to where graphics are shown.
            _polygonOverlay = new GraphicsOverlay();
            _polygonOverlay.Graphics.Add(polygonGraphic);

            // Add created overlay to the MapView.
            _myMapView.GraphicsOverlays.Add(_polygonOverlay);
        }
예제 #10
0
        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 PolygonBuilder(new[] { lastSketchPoint, lastSketchPoint });
                    await MapView.Active.SetCurrentSketchAsync(sketchPoly.ToGeometry());
                }
                else
                {
                    var sketchPolyline = new PolylineBuilder(new[] { lastSketchPoint });
                    await MapView.Active.SetCurrentSketchAsync(sketchPolyline.ToGeometry());
                }
            });
        }
예제 #11
0
        public static Graphic NewDonut(double x, double y, double innerRadius, double outerRadius)
        {
            double[] px = new double[NUM];
            double[] py = new double[NUM];
            GeometryAlgorithms.CircleToPoints(x, y, outerRadius, NUM, px, py, AngleDirection.CounterClockwise);

            Esri.ArcGISRuntime.Geometry.PointCollection pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            for (int i = 0; i < NUM; i++)
            {
                MapPoint p = new MapPoint(px[i], py[i]);
                pc.Add(p);
            }
            pc.Add(pc[0]);

            PolygonBuilder polygon = new PolygonBuilder(pc);

            GeometryAlgorithms.CircleToPoints(x, y, innerRadius, NUM, px, py, AngleDirection.Clockwise);
            pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            for (int i = 0; i < NUM; i++)
            {
                MapPoint p = new MapPoint(px[i], py[i]);
                pc.Add(p);
            }
            pc.Add(pc[0]);
            polygon.AddPart(pc);

            Graphic g = new Graphic();

            g.Geometry = polygon.ToGeometry();
            return(g);
        }
예제 #12
0
        private static Polygon CreateWkbMultiPolygon(BinaryReader reader, WkbByteOrder byteOrder)
        {
            // Get the number of Polygons.
            var numPolygons = (int)ReadUInt32(reader, byteOrder);


            if (numPolygons < 1)
            {
                throw new Exception("Could not create MultiPolygon");
            }

            // Read linestring header
            reader.ReadByte();
            ReadUInt32(reader, byteOrder);


            // Create a new array for the Polygons.
            var polygons = new PolygonBuilder(CreateWkbPolygon(reader, byteOrder));

            // Loop on the number of polygons.
            for (var i = 1; i < numPolygons; i++)
            {
                // read polygon header
                reader.ReadByte();
                ReadUInt32(reader, byteOrder);

                // TODO: Validate type

                polygons.AddParts(CreateWkbPolygon(reader, byteOrder).Parts);
            }

            //Create and return the MultiPolygon.
            return(polygons.ToGeometry());
        }
        private Geometry polygonForStartingPoint(MapPoint mapPoint)
        {
            var polygon = new PolygonBuilder(SpatialReferences.Wgs84);

            polygon.AddPoint(mapPoint.X, mapPoint.Y);
            polygon.AddPoint(mapPoint.X, mapPoint.Y + squareSize);
            polygon.AddPoint(mapPoint.X + squareSize, mapPoint.Y + squareSize);
            polygon.AddPoint(mapPoint.X + squareSize, mapPoint.Y);

            return(polygon.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);
            }

            PolygonBuilder outerRings    = new PolygonBuilder();
            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.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());
        }
예제 #15
0
        private Polygon ToPolygon(Polyline line)
        {
            var builder = new PolygonBuilder(SpatialReferences.WebMercator);

            if (line.Parts != null && line.Parts.Count > 0)
            {
                foreach (var point in line.Parts[0].GetPoints())
                {
                    builder.AddPoint(point);
                }
            }
            return(builder.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.Distance(mapPoint, radiusMapPoint);

      //build a search circle geometry
      var cent = new Coordinate2D(mapPoint);
      var searchGeom = EllipticArcBuilder.CreateEllipticArcSegment(cent, searchRadius, esriArcOrientation.esriArcClockwise, MapView.Active.Map.SpatialReference);
      var searchPB = new PolygonBuilder(new[] { searchGeom });
      return searchPB.ToGeometry();
    }
예제 #17
0
        /// <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.Distance(mapPoint, radiusMapPoint);

            //build a search circle geometry
            var cent       = new Coordinate2D(mapPoint);
            var searchGeom = EllipticArcBuilder.CreateEllipticArcSegment(cent, searchRadius, esriArcOrientation.esriArcClockwise, MapView.Active.Map.SpatialReference);
            var searchPB   = new PolygonBuilder(new[] { searchGeom });

            return(searchPB.ToGeometry());
        }
        public void SystemSpatialGeometryConvertPolygonToPolygon()
        {
            PolygonBuilder pb = new PolygonBuilder(SpatialReferences.Wgs84);

            pb.AddPart(new MapPoint[] { new MapPoint(56, 67), new MapPoint(90, 10), new MapPoint(78, 89) });
            var pl = pb.ToGeometry();
            var g  = pl.ToSystemSpatialGeometry();

            Assert.IsNotNull(g);
            Assert.IsInstanceOfType(g, typeof(System.Spatial.GeometryPolygon));
            var p = (System.Spatial.GeometryPolygon)g;

            Assert.AreEqual(1, p.Rings.Count);
            Assert.AreEqual(4, p.Rings[0].Points.Count);
            Assert.AreEqual(SpatialReferences.Wgs84.Wkid, p.CoordinateSystem.EpsgId);
        }
예제 #19
0
        private static Polygon CreateWkbPolygon(BinaryReader reader, WkbByteOrder byteOrder)
        {
            // Get the Number of rings in this Polygon.
            var numRings = (int)ReadUInt32(reader, byteOrder);

            Debug.Assert(numRings >= 1, "Number of rings in polygon must be 1 or more.");

            var polygonBuilder = new PolygonBuilder(CreateWkbLinearRing(reader, byteOrder));

            // Create a new array of linearrings for the interior rings.
            for (var i = 0; i < numRings - 1; i++)
            {
                polygonBuilder.AddPart(CreateWkbLinearRing(reader, byteOrder));
            }
            // Create and return the Poylgon.
            return(polygonBuilder.ToGeometry());
        }
예제 #20
0
        public void ZoomToEnvelope(double xMin, double yMin, double xMax, double yMax, MapView MyMapView)
        {
            var p1     = new PolygonBuilder(SpatialReferences.Wgs84);
            var lnSym1 = new SimpleLineSymbol(SimpleLineSymbolStyle.Dash, Colors.Yellow, 2);

            p1.AddPoint(xMin, yMin);
            p1.AddPoint(xMin, yMax);
            p1.AddPoint(180, yMax);
            p1.AddPoint(180, yMin);
            var rec = new Graphic(p1.ToGeometry(), lnSym1);

            graphicsOverlay2.Graphics.Add(rec);

            Envelope envelope = new Envelope(xMin + 1.6, yMin, 180.0, yMax, SpatialReferences.Wgs84);

            MyMapView.SetViewpointGeometryAsync(envelope);
        }
        public void SystemSpatialGeometryConvertPolygonToMultiPolygon()
        {
            PolygonBuilder pb = new PolygonBuilder(SpatialReferences.Wgs84);

            pb.AddPart(new MapPoint[] { new MapPoint(0, 0), new MapPoint(1, 1), new MapPoint(1, 0) });
            pb.AddPart(new MapPoint[] { new MapPoint(10, 10), new MapPoint(10, 11), new MapPoint(11, 11), new MapPoint(11, 10) });
            var pl = pb.ToGeometry();
            var g  = pl.ToSystemSpatialGeometry();

            Assert.IsNotNull(g);
            Assert.IsInstanceOfType(g, typeof(System.Spatial.GeometryMultiPolygon));
            var p = (System.Spatial.GeometryMultiPolygon)g;

            Assert.AreEqual(2, p.Polygons.Count);
            Assert.AreEqual(1, p.Polygons[0].Rings.Count);
            Assert.AreEqual(1, p.Polygons[1].Rings.Count);
            Assert.AreEqual(SpatialReferences.Wgs84.Wkid, p.CoordinateSystem.EpsgId);
        }
        /// <summary>
        ///     Creates a Polygon using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next tokens must form a &lt;Polygon Text&gt;.
        /// </param>
        /// <param name="exteriorRingCcw"></param>
        /// <param name="exteriorRingCcwSpecified"></param>
        /// <returns>
        ///     Returns a Polygon specified by the next token
        ///     in the stream
        /// </returns>
        /// <remarks>
        ///     ParseException is thown if the coordinates used to create the Polygon
        ///     shell and holes do not form closed linestrings, or if an unexpected
        ///     token is encountered.
        /// </remarks>
        private static Polygon ReadPolygonText(WktStreamTokenizer tokenizer, bool exteriorRingCcw = false,
                                               bool exteriorRingCcwSpecified = false)
        {
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                throw new Exception("Empty Polygon");
            }

            var exteriorRing = GetCoordinates(tokenizer);


            IEnumerable <MapPoint> firstRing;

            // Exterior ring.  Force it to be CW/CCW to match the first exterior ring of the multipolygon, if it is part of a multipolygon
            if (exteriorRingCcwSpecified)
            {
                firstRing = Algorithms.IsCcw(exteriorRing) != exteriorRingCcw?Reverse(exteriorRing) : exteriorRing;
            }
            else
            {
                firstRing = exteriorRing;
            }

            var polygonBuilder = new PolygonBuilder(firstRing);

            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                //Add holes
                var interiorRing  = GetCoordinates(tokenizer);
                var correctedRing = interiorRing;
                // Make sure interior rings go in the opposite direction of the exterior rings
                if (Algorithms.IsCcw(interiorRing) == exteriorRingCcw)
                {
                    correctedRing = Reverse(interiorRing);
                }
                polygonBuilder.AddPart(correctedRing); //interior rings
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(polygonBuilder.ToGeometry());
        }
예제 #23
0
        /// <summary>
        ///     Converts a MultiPolygon to &lt;MultiPolygon Text&gt; format, then Appends to it to the writer.
        /// </summary>
        /// <param name="multiPolygon">The MultiPolygon to process.</param>
        /// <param name="writer">The output stream to Append to.</param>
        private static void AppendMultiPolygonText(Polygon multiPolygon, StringWriter writer)
        {
            if (multiPolygon == null || multiPolygon.Parts.Count == 0)
            {
                writer.Write("EMPTY");
            }
            else
            {
                writer.Write("(");

                var outerRing = true;
                if (multiPolygon.Parts.Count > 0)
                {
                    outerRing = Algorithms.IsCcw(multiPolygon.Parts[0]);
                }
                for (var i = 0; i < multiPolygon.Parts.Count; i++)
                {
                    if (i > 0)
                    {
                        writer.Write(", ");
                    }

                    var singlePolygon = new PolygonBuilder(multiPolygon.Parts[i]);

                    //Add any interior rings
                    for (var j = i + 1; j < multiPolygon.Parts.Count; j++)
                    {
                        // It is an interior ring if the clockwise direction is opposite of the first ring
                        if (Algorithms.IsCcw(multiPolygon.Parts[j]) == outerRing)
                        {
                            break;
                        }

                        singlePolygon.AddPart(multiPolygon.Parts[j]);
                        i++;
                    }

                    AppendPolygonText(singlePolygon.ToGeometry(), writer);
                }
                writer.Write(")");
            }
        }
예제 #24
0
        private void AddShapeLayer(List <IGeoInfo> shapeList, Layer layer)
        {
            foreach (ShapeGeoInfo shape in shapeList)
            {
                if (shape.Polygons.Values.Count == 0)
                {
                    continue;
                }

                PolygonBuilder builder = new PolygonBuilder(SpatialReferences.Wgs84);
                shape.Polygons.Values.ToList().ForEach(p => builder.AddParts(p.Parts));
                Polygon polygon = builder.ToGeometry();

                Dictionary <string, object> attr = new Dictionary <string, object>(shape.AttrList);
                attr[KEY_CODE] = shape.KeyCode;
                layer.GraphicsLayer.Graphics.Add(new Graphic(polygon, attr, MapShapeLayer.GetSymbol(GeoMarkerType.Fill, GeoStatus.Normal)));
                _shapeList.Add(polygon.Extent);

                layer.GraphicsLayer.Graphics.Add(new Graphic(polygon.Extent.GetCenter(), attr, MapShapeLayer.GetSymbol(GeoMarkerType.Point, GeoStatus.Normal)));
            }
        }
예제 #25
0
        public void CodeExamples()
        {
            #region Example1

            // methods need to run on the MCT
            ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                List <MapPoint> list = new List <MapPoint>();
                MapPoint minPt       = MapPointBuilder.CreateMapPoint(1.0, 1.0);
                MapPoint maxPt       = MapPointBuilder.CreateMapPoint(2.0, 2.0);

                // create an envelope
                Envelope env = EnvelopeBuilder.CreateEnvelope(minPt, maxPt);

                // create a polygon from the envelope
                using (PolygonBuilder polygonBuilder = new PolygonBuilder(env))
                {
                    Polygon poly = polygonBuilder.ToGeometry();
                }
            });

            #endregion Example1

            #region Example2

            // methods need to run on the MCT
            ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                List <MapPoint> list3D = new List <MapPoint>();
                list3D.Add(MapPointBuilder.CreateMapPoint(1.0, 1.0, 1.0, 2.0));
                list3D.Add(MapPointBuilder.CreateMapPoint(1.0, 2.0, 1.0, 2.0));
                list3D.Add(MapPointBuilder.CreateMapPoint(2.0, 2.0, 1.0, 2.0));
                list3D.Add(MapPointBuilder.CreateMapPoint(2.0, 1.0, 1.0, 2.0));

                var polygon = PolygonBuilder.CreatePolygon(list3D);
            });


            #endregion Example2
        }
예제 #26
0
        public static Graphic NewDonut(double x, double y, double innerRadius, double outerRadius)
        {
            double[] px = new double[NUM];
            double[] py = new double[NUM];
            GeometryAlgorithms.CircleToPoints(x, y, outerRadius, NUM, px, py, AngleDirection.CounterClockwise);

            Esri.ArcGISRuntime.Geometry.PointCollection pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            for (int i = 0; i < NUM; i++)
            {
                MapPoint p = new MapPoint(px[i], py[i]);
                pc.Add(p);
            }
            pc.Add(pc[0]);

            PolygonBuilder polygon = new PolygonBuilder(pc);

            GeometryAlgorithms.CircleToPoints(x, y, innerRadius, NUM, px, py, AngleDirection.Clockwise);
            pc = new Esri.ArcGISRuntime.Geometry.PointCollection();
            for (int i = 0; i < NUM; i++)
            {
                MapPoint p = new MapPoint(px[i], py[i]);
                pc.Add(p);
            }
            pc.Add(pc[0]);
            polygon.AddPart(pc);

            Graphic g = new Graphic();
            g.Geometry = polygon.ToGeometry();
            return g;
        }
        /// <summary>
        /// Edit existing <see cref="Polygon"/>. This will activate editing experience on the map. Edit is completed on double click.
        /// </summary>
        /// <param name="sceneView">The <see cref="SceneView"/> that is used for editing.</param>
        /// <exception cref="TaskCanceledException">If previous task wasn't completed, <see cref="TaskCanceledException"/>
        /// will be thrown. The task is cancelled if <see cref="Cancel"/> method or if any other draw or edit method is called.
        /// </exception>
        /// <returns>Return edited <see cref="Polygon"/> based on the user interactions.</returns>
        public static async Task <Polygon> EditPolygonAsync(SceneView sceneView, Polygon polygon)
        {
            Initialize();

            var            tcs             = new TaskCompletionSource <Polygon>();
            PolygonBuilder polylineBuilder = new PolygonBuilder(sceneView.SpatialReference);
            var            sketchlayer     = CreateSketchLayer(sceneView);
            var            vertexlayer     = CreateSketchLayer(sceneView);

            // Create vertices from the original polyline
            var vertices = new List <Graphic>();

            foreach (var vertex in (polygon.Parts[0].GetPoints()))
            {
                vertices.Add(new Graphic(vertex, DefaultVertexSymbol));
            }

            vertices.RemoveAt(vertices.Count - 1);             // don't add closing point

            // Default to original polyline
            var newPolygon = new Polygon(polygon.Parts);

            Graphic fillGraphic = new Graphic(newPolygon)
            {
                Symbol = DefaultFillSymbol
            };
            Graphic lineMoveGraphic = new Graphic()
            {
                Symbol = DefaultLineMoveSymbol
            };

            sketchlayer.Graphics.AddRange(new Graphic[] { fillGraphic, lineMoveGraphic });
            vertexlayer.Graphics.AddRange(vertices);

            CancellationTokenSource tokenSource = null;
            Graphic selectedVertex  = null;
            bool    isEditingVertex = false;

            Action cleanupEvents = SetUpHandlers(sceneView,
                                                 (p) => //On mouse move, move completion line around
            {
                if (p != null && isEditingVertex)
                {
                    // Update visual indicator polyline
                    var vertexPoints = newPolygon.Parts[0].GetPoints().ToList();
                    vertexPoints.RemoveAt(vertexPoints.Count - 1);                             // don't add closing point
                    var index = vertexPoints
                                .IndexOf(vertexPoints.Where
                                             (point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
                    var temporaryVertices = new List <MapPoint>();

                    if (index > 0)
                    {
                        temporaryVertices.Add(vertexPoints[index - 1]);                                 // Add previous segment
                    }
                    else
                    {
                        temporaryVertices.Add(vertexPoints.Last());                                 // Add start segment from end
                    }
                    temporaryVertices.Add(p);
                    if (index != vertexPoints.Count() - 1)
                    {
                        temporaryVertices.Add(vertexPoints[index + 1]);                                 // Add next segment
                    }
                    else
                    {
                        temporaryVertices.Add(vertexPoints.First());
                    }

                    var builder = new PolylineBuilder(temporaryVertices);
                    lineMoveGraphic.Geometry  = builder.ToGeometry();
                    lineMoveGraphic.IsVisible = true;
                }
                else
                {
                    lineMoveGraphic.IsVisible = false;
                }
            },
                                                 async(p) => //On tap add a vertex
            {
                if (p == null)
                {
                    return;
                }
                if (isEditingVertex)
                {
                    return;
                }
                if (selectedVertex != null)
                {
                    selectedVertex.IsSelected = false;
                }

                selectedVertex = await vertexlayer.HitTestAsync(sceneView, sceneView.LocationToScreen(p));

                // No vertex found so return
                if (selectedVertex == null)
                {
                    return;
                }

                isEditingVertex           = true;
                selectedVertex.IsSelected = true;
                tokenSource = new CancellationTokenSource();
                try
                {
                    var newPoint = await SceneDrawHelper.DrawPointAsync(sceneView, tokenSource.Token);
                    if (newPoint == null)
                    {
                        return;
                    }

                    var vertexPoints = newPolygon.Parts[0].GetPoints().ToList();
                    vertexPoints.RemoveAt(vertexPoints.Count - 1);                             // don't add closing point
                    var index = vertexPoints
                                .IndexOf(vertexPoints.Where
                                             (point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
                    var builder = new PolygonBuilder(vertexPoints);
                    builder.Parts[0].MovePoint(index, newPoint);

                    // Update polyline
                    newPolygon           = builder.ToGeometry();
                    fillGraphic.Geometry = newPolygon;
                    // Update vertex
                    selectedVertex.Geometry = newPoint;
                    tokenSource             = null;
                }
                catch (TaskCanceledException tce)
                {
                }
                finally
                {
                    lineMoveGraphic.IsVisible = false;
                    selectedVertex.IsSelected = false;
                    selectedVertex            = null;
                    isEditingVertex           = false;
                }
            },
                                                 (p) => // Double tapped - completes task and returns new polygon
            {
                fillGraphic.IsVisible     = false;
                lineMoveGraphic.IsVisible = false;
                tcs.SetResult(newPolygon);
            });
            Action cleanup = () =>
            {
                cleanupEvents();
                sceneView.GraphicsOverlays.Remove(sketchlayer);
                sceneView.GraphicsOverlays.Remove(vertexlayer);
                if (tokenSource != null)
                {
                    tokenSource.Cancel();                                      // Cancel vertex draw if it isn't finished
                }
                Cleanup();
            };

            _drawTaskTokenSource.Token.Register(() => tcs.SetCanceled());

            Polygon result = null;

            try
            {
                result = await tcs.Task;
            }
            finally
            {
                cleanup();
            }
            return(result);
        }
예제 #28
0
        async private void   Image_MouseEnter(object sender, MouseEventArgs e)
        {
            Polygon polygon;


            var blackSolidLineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlueRGB, 5, SimpleLineStyle.Solid);

            Geometry geometry = null;
            await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                SpatialReference inSR   = SpatialReferenceBuilder.CreateSpatialReference(32604);
                SpatialReference sr4326 = SpatialReferences.WGS84;
                SpatialReference sr3857 = SpatialReferences.WebMercator;
                ProjectionTransformation projTransFromSRs = ArcGIS.Core.Geometry.ProjectionTransformation.Create(inSR, sr3857);
                List <Coordinate2D> coordinates           = new List <Coordinate2D>()
                {
                    //new Coordinate2D(-159.20168702818188, 21.876487211082708),
                    //new Coordinate2D(-159.42653907783114, 21.838951660451173),
                    //new Coordinate2D(-159.44077880308507, 21.94718691051718),
                    //new Coordinate2D(-159.21630329750306, 21.94718691051718),
                    //new Coordinate2D(-159.21413990271841, 21.9365008022738),
                    //new Coordinate2D(-159.21383956606297, 21.93655454291286),
                    //new Coordinate2D(-159.20168702818188, 21.876487211082708),
                    new Coordinate2D(-17773406.8675, 2478583.7239999995),
                    new Coordinate2D(-17773406.8675, 2578583.7239999995),
                    new Coordinate2D(-16773406.8675, 2578583.7239999995),
                    new Coordinate2D(-17773406.8675, 2478583.7239999995)
                };
                //MapPoint point = new MapPointBuilder.FromGeoCoordinateString()
                //List<MapPoint> mapPoints = new List<MapPoint>();
                //foreach (Coordinate2D item in coordinates)
                //{
                //    MapPoint point = new MapPointBuilder()
                //}
                //mapPoints.Add( coordinates[0].ToMapPoint());
                MapPointBuilder asas = new MapPointBuilder(new Coordinate2D(-159.20168702818188, 21.876487211082708), MapView.Active.Extent.SpatialReference);
                _polygonSymbol       = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.BlackRGB, SimpleFillStyle.Null, SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid));
                MapPoint point       = asas.ToGeometry();
                MapPoint point2      = MapPointBuilder.FromGeoCoordinateString(point.ToGeoCoordinateString(new ToGeoCoordinateParameter(GeoCoordinateType.DD)), MapView.Active.Extent.SpatialReference, GeoCoordinateType.DD);
                using (PolygonBuilder polygonBuilder = new PolygonBuilder(coordinates, inSR))
                {
                    polygonBuilder.SpatialReference = inSR;
                    polygon            = polygonBuilder.ToGeometry();
                    geometry           = polygonBuilder.ToGeometry();
                    Geometry geometry2 = GeometryEngine.Instance.ProjectEx(geometry, projTransFromSRs);
                    _graphic           = MapView.Active.AddOverlayAsync(geometry, _polygonSymbol.MakeSymbolReference());
                    //Application.Current.
                }
            });

            //await  QueuedTask.Run(() =>
            //{
            //    MapView.Active.UpdateOverlay(_graphic, point, SymbolFactory.Instance.ConstructPointSymbol(
            //                            ColorFactory.Instance.BlueRGB, 20.0, SimpleMarkerStyle.Circle).MakeSymbolReference());
            //});
            //_graphic = await this.AddOverlayAsync(geometry, _lineSymbol.MakeSymbolReference());
            Console.WriteLine(sender.ToString());
            //_graphic = MapView.Active.AddOverlay(geometry, _lineSymbol.MakeSymbolReference());


            //Geometry geometry = new PolygonBuilder.CreatePolygon(coordinates, inSR); ;
        }
예제 #29
0
        // myMapView 事件
        private async void MyMapView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IInputElement ie  = (IInputElement)(sender);
            MapPoint      loc = myMapView.ScreenToLocation(e.GetPosition(ie));

            switch (operation)
            {
            case OperateType.DrawPoint:     //画点
                Graphic pt = new Graphic(loc, pointSymbol);
                graphicsLayer.Graphics.Add(pt);
                break;

            case OperateType.DrawPolyline:    //画线
                pointCollection.Add(loc);
                if (pointCollection.Count >= 2)
                {
                    if (pointCollection.Count > 2)
                    {
                        Graphic         g  = graphicsLayer.Graphics[graphicsLayer.Graphics.Count - 1];
                        PolylineBuilder lb = new PolylineBuilder(pointCollection);
                        g.Geometry = lb.ToGeometry();
                    }
                    else
                    {
                        Esri.ArcGISRuntime.Geometry.Polyline l = new Esri.ArcGISRuntime.Geometry.Polyline(pointCollection);
                        Graphic lg = new Graphic(l, lineSymbol);
                        graphicsLayer.Graphics.Add(lg);
                    }
                }
                break;

            case OperateType.DrawPolygon:    //画多边形
                pointCollection.Add(loc);
                if (pointCollection.Count >= 3)
                {
                    if (pointCollection.Count > 3)
                    {
                        Graphic        g  = graphicsLayer.Graphics[graphicsLayer.Graphics.Count - 1];
                        PolygonBuilder pb = new PolygonBuilder(pointCollection);
                        g.Geometry = pb.ToGeometry();
                    }
                    else
                    {
                        Esri.ArcGISRuntime.Geometry.Polygon p = new Esri.ArcGISRuntime.Geometry.Polygon(pointCollection);
                        Graphic pg = new Graphic(p, fillSymbol);
                        graphicsLayer.Graphics.Add(pg);
                    }
                }
                break;

            case OperateType.None:    //缺省状态
                graphicsLayer.ClearSelection();
                IdentifyGraphicsOverlayResult result = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                //选择图形元素
                if (result.Graphics.Count < 1)
                {
                    curSelGraphic = null;
                    EditVertexMenuItem.IsEnabled   = false;
                    UneditVertexMenuItem.IsEnabled = false;
                    return;
                }
                curSelGraphic                = result.Graphics.First();
                curSelGraphic.IsSelected     = true;
                EditVertexMenuItem.IsEnabled = true;
                break;

            case OperateType.Cal_Clip:     //选择图形
                IdentifyGraphicsOverlayResult gResult = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic = gResult.Graphics.First();
                selGraphic.IsSelected = true; listOfClipGraphics.Add(selGraphic); //记录所选图形
                if (listOfClipGraphics.Count == 2)                                //图形数目为2时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    Graphic g2 = listOfClipGraphics[1];
                    if (g1.Geometry.GeometryType != GeometryType.Polygon || g2.Geometry.GeometryType != GeometryType.Polygon)     //如果所选图形不是多边形,则退出
                    {
                        MessageBox.Show("请选择两个多边形图形!");
                        listOfClipGraphics.Clear();
                        graphicsLayer.ClearSelection();
                        return;
                    }
                    Esri.ArcGISRuntime.Geometry.Geometry resultGeometry = GeometryEngine.Clip(g1.Geometry, g2.Geometry.Extent); //执行剪切操作
                    if (resultGeometry != null)                                                                                 //处理结果
                    {
                        graphicsLayer.Graphics.Remove(g1);                                                                      //从图形层中移除原图形
                        graphicsLayer.Graphics.Remove(g2);
                        Graphic clipedGraphic = new Graphic(resultGeometry, fillSymbol);                                        //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic); operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Union:     // 联合
                IdentifyGraphicsOverlayResult gResultUnion = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResultUnion.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphicUnion = gResultUnion.Graphics.First();
                selGraphicUnion.IsSelected = true;
                listOfClipGraphics.Add(selGraphicUnion); //记录所选图形
                if (listOfClipGraphics.Count == 2)       //图形数目为2时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    Graphic g2 = listOfClipGraphics[1];
                    if (g1.Geometry.GeometryType != GeometryType.Polygon || g2.Geometry.GeometryType != GeometryType.Polygon)     //如果所选图形不是多边形,则退出
                    {
                        MessageBox.Show("请选择两个多边形图形!");
                        listOfClipGraphics.Clear();
                        graphicsLayer.ClearSelection();
                        return;
                    }
                    Esri.ArcGISRuntime.Geometry.Geometry resultGeometry = GeometryEngine.Union(g1.Geometry, g2.Geometry.Extent); //执行剪切操作
                    if (resultGeometry != null)                                                                                  //处理结果
                    {
                        graphicsLayer.Graphics.Remove(g1);                                                                       //从图形层中移除原图形
                        graphicsLayer.Graphics.Remove(g2);
                        Graphic clipedGraphic = new Graphic(resultGeometry, fillSymbol);                                         //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic);
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Cut:     // 剪切
                IdentifyGraphicsOverlayResult gResult_Cut = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult_Cut.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic_Cut = gResult_Cut.Graphics.First();
                selGraphic_Cut.IsSelected = true;
                listOfClipGraphics.Add(selGraphic_Cut); //记录所选图形
                if (listOfClipGraphics.Count == 2)      //图形数目为1时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    Graphic g2 = listOfClipGraphics[1];
                    if (g1.Geometry.GeometryType != GeometryType.Polygon || g2.Geometry.GeometryType != GeometryType.Polyline)     //如果所选图形不是多边形,则退出
                    {
                        MessageBox.Show("请先选择一个面要素后再选择一个线要素.");
                        listOfClipGraphics.Clear();
                        graphicsLayer.ClearSelection();
                        return;
                    }
                    Esri.ArcGISRuntime.Geometry.Polyline   polyLine       = (Esri.ArcGISRuntime.Geometry.Polyline)g2.Geometry;
                    Esri.ArcGISRuntime.Geometry.Geometry[] resultGeometry = GeometryEngine.Cut(g1.Geometry, polyLine); //执行剪切操作
                    if (resultGeometry != null)                                                                        //处理结果
                    {
                        graphicsLayer.Graphics.Remove(g1);
                        for (int z = 0; z < resultGeometry.Length; z++)
                        {
                            Graphic clipedGraphic = new Graphic(resultGeometry[z], fillSymbol);     //利 用剪切结果构建新的图形
                            graphicsLayer.Graphics.Add(clipedGraphic);
                        }
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Simplify:     // 拓扑纠正
                IdentifyGraphicsOverlayResult gResult_Simplify = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult_Simplify.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic_Simplify = gResult_Simplify.Graphics.First();
                selGraphic_Simplify.IsSelected = true;
                listOfClipGraphics.Add(selGraphic_Simplify); //记录所选图形
                if (listOfClipGraphics.Count == 1)           //图形数目为1时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    if (g1.Geometry.GeometryType == GeometryType.Point)     //如果所选图形不是多边形,则退出
                    {
                        MessageBox.Show("请先选择一个面要素或线要素.");
                        listOfClipGraphics.Clear();
                        graphicsLayer.ClearSelection();
                        return;
                    }
                    Esri.ArcGISRuntime.Geometry.Geometry resultGeometry = GeometryEngine.Simplify(g1.Geometry); //执行剪切操作
                    if (resultGeometry != null)                                                                 //处理结果
                    {
                        graphicsLayer.Graphics.Remove(g1);                                                      //从图形层中移除原图形
                        Graphic clipedGraphic = new Graphic(resultGeometry, fillSymbol);                        //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic);
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Gene:     // 简化
                IdentifyGraphicsOverlayResult gResult_Gene = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult_Gene.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic_Gene = gResult_Gene.Graphics.First();
                selGraphic_Gene.IsSelected = true;
                listOfClipGraphics.Add(selGraphic_Gene); //记录所选图形
                if (listOfClipGraphics.Count == 1)       //图形数目为1时
                {
                    Graphic g1 = listOfClipGraphics[0];
                    if (g1.Geometry.GeometryType == GeometryType.Point)     //如果所选图形是点,则退出
                    {
                        MessageBox.Show("请先选择一个面要素或线要素.");
                        listOfClipGraphics.Clear();
                        graphicsLayer.ClearSelection();
                        return;
                    }
                    Esri.ArcGISRuntime.Geometry.Geometry resultGeometry = GeometryEngine.Generalize(g1.Geometry, 1000000.0, true); //执行剪切操作
                    if (resultGeometry != null)                                                                                    //处理结果
                    {
                        MessageBox.Show(resultGeometry.ToJson() + "\n" + resultGeometry.GeometryType);
                        graphicsLayer.Graphics.Remove(g1);                               //从图形层中移除原图形
                        Graphic clipedGraphic = new Graphic(resultGeometry, fillSymbol); //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic);
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Buff:     // 缓冲
                IdentifyGraphicsOverlayResult gResult_Buff = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult_Buff.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic_Buff = gResult_Buff.Graphics.First();
                selGraphic_Buff.IsSelected = true;
                listOfClipGraphics.Add(selGraphic_Buff); //记录所选图形
                if (listOfClipGraphics.Count == 1)       //图形数目为1时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    Esri.ArcGISRuntime.Geometry.Geometry resultGeometry = GeometryEngine.Buffer(g1.Geometry, 1000000.0);                                                                                                                           //执行剪切操作
                    if (resultGeometry != null)                                                                                                                                                                                                    //处理结果
                    {
                        graphicsLayer.Graphics.Remove(g1);                                                                                                                                                                                         //从图形层中移除原图形
                        Graphic clipedGraphic = new Graphic(resultGeometry, new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.FromArgb(125, 255, 250, 0), new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.FromArgb(0, 0, 0), 4.0))); //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic);
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;

            case OperateType.Cal_Jiaodian:     // 交点
                IdentifyGraphicsOverlayResult gResult_Jiaodian = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                if (gResult_Jiaodian.Graphics.Count < 1)
                {
                    return;
                }
                Graphic selGraphic_Jiaodian = gResult_Jiaodian.Graphics.First();
                selGraphic_Jiaodian.IsSelected = true;
                listOfClipGraphics.Add(selGraphic_Jiaodian); //记录所选图形
                if (listOfClipGraphics.Count == 2)           //图形数目为1时,进行剪切计算
                {
                    Graphic g1 = listOfClipGraphics[0];
                    Graphic g2 = listOfClipGraphics[1];
                    IReadOnlyList <Geometry> resultGeometry = GeometryEngine.Intersections(g1.Geometry, g2.Geometry); //执行剪切操作
                    if (resultGeometry != null)                                                                       //处理结果
                    {
                        Graphic clipedGraphic = new Graphic(resultGeometry[0], pointSymbol);                          //利 用剪切结果构建新的图形
                        graphicsLayer.Graphics.Add(clipedGraphic);
                        operation = OperateType.None;
                    }
                    listOfClipGraphics.Clear();     //清空图形选择集合
                    graphicsLayer.ClearSelection(); //清空图形层所选
                }
                break;
            }
        }
예제 #30
0
        // myMapView 事件
        private async void MyMapView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IInputElement ie  = (IInputElement)(sender);
            MapPoint      loc = myMapView.ScreenToLocation(e.GetPosition(ie));

            switch (operation)
            {
            case OperateType.DrawPoint:     //画点
                Graphic pt = new Graphic(loc, pointSymbol);
                graphicsLayer.Graphics.Add(pt);
                break;

            case OperateType.DrawPolyline:    //画线
                pointCollection.Add(loc); if (pointCollection.Count >= 2)
                {
                    if (pointCollection.Count > 2)
                    {
                        Graphic         g  = graphicsLayer.Graphics[graphicsLayer.Graphics.Count - 1];
                        PolylineBuilder lb = new PolylineBuilder(pointCollection); g.Geometry = lb.ToGeometry();
                    }
                    else
                    {
                        Esri.ArcGISRuntime.Geometry.Polyline l = new Esri.ArcGISRuntime.Geometry.Polyline(pointCollection);
                        Graphic lg = new Graphic(l, lineSymbol);
                        graphicsLayer.Graphics.Add(lg);
                    }
                }
                break;

            case OperateType.DrawPolygon:    //画多边形
                pointCollection.Add(loc); if (pointCollection.Count >= 3)
                {
                    if (pointCollection.Count > 3)
                    {
                        Graphic        g  = graphicsLayer.Graphics[graphicsLayer.Graphics.Count - 1];
                        PolygonBuilder pb = new PolygonBuilder(pointCollection); g.Geometry = pb.ToGeometry();
                    }
                    else
                    {
                        Esri.ArcGISRuntime.Geometry.Polygon p = new Esri.ArcGISRuntime.Geometry.Polygon(pointCollection);
                        Graphic pg = new Graphic(p, fillSymbol);
                        graphicsLayer.Graphics.Add(pg);
                    }
                }
                break;

            case OperateType.None:    //缺省状态
                graphicsLayer.ClearSelection();
                IdentifyGraphicsOverlayResult result = await myMapView.IdentifyGraphicsOverlayAsync(graphicsLayer, e.GetPosition(ie), 5, false);

                //选择图形元素
                if (result.Graphics.Count < 1)
                {
                    curSelGraphic = null;
                    EditVertexMenuItem.IsEnabled   = false;
                    UneditVertexMenuItem.IsEnabled = false;
                    return;
                }
                curSelGraphic                = result.Graphics.First();
                curSelGraphic.IsSelected     = true;
                EditVertexMenuItem.IsEnabled = true;
                break;
            }
        }
예제 #31
0
        private void MyMapView_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            myMapView.Cursor = Cursors.Arrow;//恢复光标样式
            if (curSelGraphic == null || orgPoint == null)
            {
                return;             //计算位移
            }
            IInputElement ie     = (IInputElement)(sender);
            MapPoint      loc    = myMapView.ScreenToLocation(e.GetPosition(ie));
            double        deltaX = loc.X - orgPoint.X;
            double        deltaY = loc.Y - orgPoint.Y;

            if (operation == OperateType.None)                                 //非绘制状态或顶点编辑状态
            {
                if (curSelGraphic.Geometry.GeometryType == GeometryType.Point) //当前选择的图形 为点,重新构造点
                {
                    MapPointBuilder pb = new MapPointBuilder(loc);
                    curSelGraphic.Geometry = pb.ToGeometry();
                }
                else if (curSelGraphic.Geometry.GeometryType == GeometryType.Polyline)//当前选 择的图形为线,重新计算所有点


                {
                    Esri.ArcGISRuntime.Geometry.Polyline ln = (Esri.ArcGISRuntime.Geometry.Polyline)curSelGraphic.Geometry; pointCollection.Clear();
                    for (int i = 0; i < ln.Parts[0].Points.Count; i++)
                    {
                        double   X = ln.Parts[0].Points[i].X + deltaX; double Y = ln.Parts[0].Points[i].Y + deltaY;
                        MapPoint Pt = new MapPoint(X, Y); pointCollection.Add(Pt);
                    }
                    PolylineBuilder lb = new PolylineBuilder(pointCollection);
                    curSelGraphic.Geometry = lb.ToGeometry();
                }
                else if (curSelGraphic.Geometry.GeometryType == GeometryType.Polygon)//当前选 择图形为多边形,重新计算所有点
                {
                    Esri.ArcGISRuntime.Geometry.Polygon poly = (Esri.ArcGISRuntime.Geometry.Polygon)curSelGraphic.Geometry;
                    pointCollection.Clear();
                    for (int i = 0; i < poly.Parts[0].Points.Count; i++)
                    {
                        double   X = poly.Parts[0].Points[i].X + deltaX; double Y = poly.Parts[0].Points[i].Y + deltaY;
                        MapPoint Pt = new MapPoint(X, Y); pointCollection.Add(Pt);
                    }
                    PolygonBuilder pb = new PolygonBuilder(pointCollection);
                    curSelGraphic.Geometry = pb.ToGeometry();
                }
            }
            else if (operation == OperateType.EditVertex)//处于顶点编辑状态
            {
                if (selGracphicIndex >= 0)
                {
                    Graphic g = graphicsLayer.Graphics.ElementAt(selGracphicIndex); //找到所选 图形
                    if (g.Geometry.GeometryType == GeometryType.Point)              //图形为点
                    {
                        MapPointBuilder mpb = new MapPointBuilder(loc);
                        g.Geometry = mpb.ToGeometry();
                    }
                    else if (g.Geometry.GeometryType == GeometryType.Polyline && selPointIndex >= 0)//图形为线,顶点已捕捉


                    {
                        Esri.ArcGISRuntime.Geometry.Polyline pln = (Esri.ArcGISRuntime.Geometry.Polyline)g.Geometry;
                        pointCollection.Clear(); pointCollection.AddPoints(pln.Parts[0].Points); pointCollection.SetPoint(selPointIndex, loc.X, loc.Y);
                        PolylineBuilder plb = new PolylineBuilder(pointCollection); g.Geometry = plb.ToGeometry();
                    }
                    else if (g.Geometry.GeometryType == GeometryType.Polygon && selPointIndex >= 0)//图形为多边形,顶点已捕捉
                    {
                        Esri.ArcGISRuntime.Geometry.Polygon plg = (Esri.ArcGISRuntime.Geometry.Polygon)g.Geometry; pointCollection.Clear();
                        pointCollection.AddPoints(plg.Parts[0].Points); pointCollection.SetPoint(selPointIndex, loc.X, loc.Y);
                        PolygonBuilder pgb = new PolygonBuilder(pointCollection); g.Geometry = pgb.ToGeometry();
                    }
                    if (selPointIndex >= 0)
                    {//移动相应的顶点到当前位置
                        Graphic         vtGraphic = selVertexLayer.Graphics.ElementAt(selPointIndex);
                        MapPointBuilder tgPoint   = new MapPointBuilder(loc); vtGraphic.Geometry = tgPoint.ToGeometry();
                    }
                }
            }
        }
        /// <summary>
        /// Edit existing <see cref="Polygon"/>. This will activate editing experience on the map. Edit is completed on double click.
        /// </summary>
        /// <param name="sceneView">The <see cref="SceneView"/> that is used for editing.</param>
        /// <exception cref="TaskCanceledException">If previous task wasn't completed, <see cref="TaskCanceledException"/>
        /// will be thrown. The task is cancelled if <see cref="Cancel"/> method or if any other draw or edit method is called.
        /// </exception>
        /// <returns>Return edited <see cref="Polygon"/> based on the user interactions.</returns>
        public static async Task<Polygon> EditPolygonAsync(SceneView sceneView, Polygon polygon)
		{
            Initialize();

			var tcs = new TaskCompletionSource<Polygon>();
			PolygonBuilder polylineBuilder = new PolygonBuilder(sceneView.SpatialReference);
			var sketchlayer = CreateSketchLayer(sceneView);
			var vertexlayer = CreateSketchLayer(sceneView);

			// Create vertices from the original polyline
			var vertices = new List<Graphic>();
			foreach (var vertex in (polygon.Parts[0].GetPoints()))
				vertices.Add(new Graphic(vertex, DefaultVertexSymbol));

			vertices.RemoveAt(vertices.Count - 1); // don't add closing point

			// Default to original polyline
			var newPolygon = new Polygon(polygon.Parts);

			Graphic fillGraphic = new Graphic(newPolygon) { Symbol = DefaultFillSymbol };
			Graphic lineMoveGraphic = new Graphic() { Symbol = DefaultLineMoveSymbol };
			
			sketchlayer.Graphics.AddRange(new Graphic[] { fillGraphic, lineMoveGraphic });
			vertexlayer.Graphics.AddRange(vertices);

			CancellationTokenSource tokenSource = null;
			Graphic selectedVertex = null;
			bool isEditingVertex = false;

			Action cleanupEvents = SetUpHandlers(sceneView,
				(p) => //On mouse move, move completion line around
				{
					if (p != null && isEditingVertex)
					{
						// Update visual indicator polyline
						var vertexPoints = newPolygon.Parts[0].GetPoints().ToList();
						vertexPoints.RemoveAt(vertexPoints.Count - 1); // don't add closing point
						var index = vertexPoints
							.IndexOf(vertexPoints.Where
								(point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
						var temporaryVertices = new List<MapPoint>();
						
						if (index > 0)
							temporaryVertices.Add(vertexPoints[index - 1]); // Add previous segment
						else
							temporaryVertices.Add(vertexPoints.Last()); // Add start segment from end
						temporaryVertices.Add(p);
						if (index != vertexPoints.Count() - 1)
							temporaryVertices.Add(vertexPoints[index + 1]); // Add next segment
						else
							temporaryVertices.Add(vertexPoints.First());

						var builder = new PolylineBuilder(temporaryVertices);
						lineMoveGraphic.Geometry = builder.ToGeometry();
						lineMoveGraphic.IsVisible = true;
					}
					else
					{
						lineMoveGraphic.IsVisible = false;
					}
				},
				async (p) => //On tap add a vertex
				{
					if (p == null) return;
					if (isEditingVertex) return;
					if (selectedVertex != null) selectedVertex.IsSelected = false;

					selectedVertex = await vertexlayer.HitTestAsync(sceneView, sceneView.LocationToScreen(p));

					// No vertex found so return
					if (selectedVertex == null)
						return;

					isEditingVertex = true;
					selectedVertex.IsSelected = true;
					tokenSource = new CancellationTokenSource();
					try
					{
						var newPoint = await SceneDrawHelper.DrawPointAsync(sceneView, tokenSource.Token);
						if (newPoint == null) return;

						var vertexPoints = newPolygon.Parts[0].GetPoints().ToList();
						vertexPoints.RemoveAt(vertexPoints.Count - 1); // don't add closing point
						var index = vertexPoints
							.IndexOf(vertexPoints.Where
								(point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
						var builder = new PolygonBuilder(vertexPoints);
						builder.Parts[0].MovePoint(index, newPoint);
						
						// Update polyline
						newPolygon = builder.ToGeometry();
						fillGraphic.Geometry = newPolygon;
						// Update vertex
						selectedVertex.Geometry = newPoint;
						tokenSource = null;				
					}
					catch (TaskCanceledException tce)
					{	
					}
					finally
					{
						lineMoveGraphic.IsVisible = false;
						selectedVertex.IsSelected = false;
						selectedVertex = null;
						isEditingVertex = false;
					}
				},
				(p) => // Double tapped - completes task and returns new polygon
                {
					fillGraphic.IsVisible = false;
					lineMoveGraphic.IsVisible = false;
					tcs.SetResult(newPolygon);
				});
			Action cleanup = () =>
			{
				cleanupEvents();
                sceneView.GraphicsOverlays.Remove(sketchlayer);
                sceneView.GraphicsOverlays.Remove(vertexlayer);
				if (tokenSource != null) tokenSource.Cancel(); // Cancel vertex draw if it isn't finished
                Cleanup();
			};
            _drawTaskTokenSource.Token.Register(() => tcs.SetCanceled());

			Polygon result = null;
			try
			{
				result = await tcs.Task;
			}
			finally
			{
				cleanup();
			}
			return result;
		}
        /// <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;

            PolygonBuilder outerRings = new PolygonBuilder();
            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.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();
        }
        public static async Task <Polygon> DrawPolygonAsync(MapView sceneView, System.Threading.CancellationToken cancellationToken)
        {
            var            tcs            = new TaskCompletionSource <Polygon>();
            PolygonBuilder polygonBuilder = new PolygonBuilder(sceneView.SpatialReference);
            var            sketchlayer    = CreateSketchLayer(sceneView);
            Graphic        polygonGraphic = new Graphic()
            {
                Symbol = DefaultFillSymbol
            };
            Graphic lineMoveGraphic = new Graphic()
            {
                Symbol = DefaultLineMoveSymbol
            };

            sketchlayer.Graphics.AddRange(new Graphic[] { polygonGraphic, lineMoveGraphic });
            Action cleanupEvents = SetUpHandlers(sceneView,
                                                 (p) => //On mouse move move completion line around
            {
                if (p != null && polygonBuilder.Parts.Count > 0)
                {
                    lineMoveGraphic.Geometry = new Polyline(new MapPoint[]
                    {
                        polygonBuilder.Parts[0].Last().EndPoint,
                        p,
                        polygonBuilder.Parts[0].First().StartPoint
                    });
                }
            },
                                                 (p) => //On tap add a vertex
            {
                if (p != null)
                {
                    polygonBuilder.AddPoint(p);
                    if (polygonBuilder.Parts.Count > 0 && polygonBuilder.Parts[0].Count > 0)
                    {
                        polygonGraphic.Geometry  = polygonBuilder.ToGeometry();
                        lineMoveGraphic.Geometry = null;
                    }
                }
            },
                                                 (p) => //View tapped - completes task and returns point
            {
                tcs.SetResult(polygonBuilder.ToGeometry());
            });
            Action cleanup = () =>
            {
                cleanupEvents();
                sceneView.GraphicsOverlays.Remove(sketchlayer);
            };

            cancellationToken.Register(() => tcs.SetCanceled());

            Polygon result = null;

            try
            {
                result = await tcs.Task;
            }
            finally
            {
                cleanup();
            }

            return(result);
        }
        /// <summary>
        /// Returns a polygon with a range fan(circular ring sector - like a donut wedge or wiper blade swipe with inner and outer radius)
        /// from the input parameters
        /// Input Angles must be 0-360 degrees
        /// </summary>
        public static Geometry ConstructRangeFan(MapPoint centerPoint,
                                                 double innerDistanceInMapUnits, double outerDistanceInMapUnits,
                                                 double horizontalStartAngleInBearing, double horizontalEndAngleInBearing,
                                                 SpatialReference sr, double incrementAngleStep = 1.0)
        {
            // Check inputs
            if ((centerPoint == null) || (sr == null) ||
                (innerDistanceInMapUnits < 0.0) || (outerDistanceInMapUnits < 0.0) ||
                (horizontalStartAngleInBearing < 0.0) || (horizontalStartAngleInBearing > 360.0) ||
                (horizontalEndAngleInBearing < 0.0) || (horizontalEndAngleInBearing > 360.0))
            {
                return(null);
            }

            // Tricky - if angle cuts across 360, need to adjust for this case (ex. Angle: 270->90)
            if (horizontalStartAngleInBearing > horizontalEndAngleInBearing)
            {
                horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing);
            }

            double deltaAngle = Math.Abs(horizontalStartAngleInBearing - horizontalEndAngleInBearing);

            // if full circle(or greater), return donut section with inner/outer rings
            if ((deltaAngle == 0.0) || (deltaAngle >= 360.0))
            {
                // Just add 2 concentric circle buffers
                PolygonBuilder donutPb = new PolygonBuilder();

                EllipticArcSegment circularArcOuter =
                    EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint,
                                                                outerDistanceInMapUnits, esriArcOrientation.esriArcClockwise, sr);

                donutPb.AddPart(new List <Segment> {
                    circularArcOuter
                });

                if (innerDistanceInMapUnits > 0.0)
                {
                    EllipticArcSegment circularArcInner =
                        EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint,
                                                                    innerDistanceInMapUnits, esriArcOrientation.esriArcCounterClockwise, sr);

                    donutPb.AddPart(new List <Segment> {
                        circularArcInner
                    });
                }

                return(donutPb.ToGeometry());
            }

            // Otherwise if range fan, construct that
            var points = new List <MapPoint>();

            MapPoint startPoint = null;

            if (innerDistanceInMapUnits <= 0.0)
            {
                startPoint = centerPoint;
                points.Add(startPoint);
            }

            double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing);
            double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing);

            // don't let this create more than 360 points per arc
            if ((deltaAngle / incrementAngleStep) > 360.0)
            {
                incrementAngleStep = deltaAngle / 360.0;
            }

            // Draw Outer Arc of Ring
            // Implementation Note: because of the unique shape of this ring,
            // it was easier to manually create these points than use EllipticArcBuilder
            for (double angle = minAngle; angle <= maxAngle; angle += incrementAngleStep)
            {
                double cartesianAngle = (450 - angle) % 360;
                double angleInRadians = cartesianAngle * (Math.PI / 180.0);
                double x = centerPoint.X + (outerDistanceInMapUnits * Math.Cos(angleInRadians));
                double y = centerPoint.Y + (outerDistanceInMapUnits * Math.Sin(angleInRadians));

                MapPoint pointToAdd = MapPointBuilder.CreateMapPoint(x, y, sr);
                points.Add(pointToAdd);

                if (startPoint == null)
                {
                    startPoint = pointToAdd;
                }
            }

            if (innerDistanceInMapUnits > 0.0)
            {
                // Draw Inner Arc of Ring - if inner distance set
                for (double angle = maxAngle; angle >= minAngle; angle -= incrementAngleStep)
                {
                    double cartesianAngle = (450 - angle) % 360;
                    double angleInRadians = cartesianAngle * (Math.PI / 180.0);
                    double x = centerPoint.X + (innerDistanceInMapUnits * Math.Cos(angleInRadians));
                    double y = centerPoint.Y + (innerDistanceInMapUnits * Math.Sin(angleInRadians));

                    points.Add(MapPointBuilder.CreateMapPoint(x, y, sr));
                }
            }

            // close Polygon
            points.Add(startPoint);

            PolygonBuilder pb = new PolygonBuilder();

            pb.AddPart(points);

            return(pb.ToGeometry());
        }
		public static async Task<Polygon> DrawPolygonAsync(SceneView sceneView, System.Threading.CancellationToken cancellationToken)
		{
			var tcs = new TaskCompletionSource<Polygon>();
			PolygonBuilder polygonBuilder = new PolygonBuilder(sceneView.SpatialReference);
			var sketchlayer = CreateSketchLayer(sceneView);
			Graphic polygonGraphic = new Graphic() { Symbol = DefaultFillSymbol };
			Graphic lineMoveGraphic = new Graphic() { Symbol = DefaultLineMoveSymbol };
			sketchlayer.Graphics.AddRange(new Graphic[] { polygonGraphic, lineMoveGraphic });
			Action cleanupEvents = SetUpHandlers(sceneView,
				(p) => //On mouse move move completion line around
				{
					if (p != null && polygonBuilder.Parts.Count > 0)
					{
						lineMoveGraphic.Geometry = new Polyline(new MapPoint[] 
							{
								 polygonBuilder.Parts[0].Last().EndPoint, 
								 p, 
								 polygonBuilder.Parts[0].First().StartPoint 
							});
					}
				},
				(p) => //On tap add a vertex
				{
					if (p != null)
					{
						polygonBuilder.AddPoint(p);
						if (polygonBuilder.Parts.Count > 0 && polygonBuilder.Parts[0].Count > 0)
						{
							polygonGraphic.Geometry = polygonBuilder.ToGeometry();
							lineMoveGraphic.Geometry = null;
						}
					}
				},
				(p) => //View tapped - completes task and returns point
				{
					tcs.SetResult(polygonBuilder.ToGeometry());
				});
			Action cleanup = () =>
			{
				cleanupEvents();
				sceneView.GraphicsOverlays.Remove(sketchlayer);
			};
			cancellationToken.Register(() => tcs.SetCanceled());

			Polygon result = null;
			try
			{
				result = await tcs.Task;
			}
			finally
			{
				cleanup();
			}

			return result;
		}
        private void GeneratePolyGeometry()
        {
            //PolyCoordinates.ToList()
            List<MapPoint> points = new List<MapPoint>();
            foreach (CoordinateObject coordObject in PolyCoordinates)
            {
                points.Add(coordObject.MapPoint);
            }

            ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                if (GeometryType == GeometryType.Polyline)
                {
                    PolylineBuilder polylineBuilder = new PolylineBuilder(points);
                    polylineBuilder.HasZ = true;
                    MapGeometry = polylineBuilder.ToGeometry();
                }
                else if (GeometryType == GeometryType.Polygon)
                {
                    PolygonBuilder polygonBuilder = new PolygonBuilder(points);
                    polygonBuilder.HasZ = true;
                    MapGeometry = polygonBuilder.ToGeometry();
                }
            });
        }