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(); }
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); }
/// <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()); } }); }
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); }
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()); } }); }
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); }
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()); }
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(); }
/// <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); }
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()); }
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 <Polygon Text>. /// </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()); }
/// <summary> /// Converts a MultiPolygon to <MultiPolygon Text> 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(")"); } }
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))); } }
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 }
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); }
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); ; }
// 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; } }
// 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; } }
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(); } }); }