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 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); }
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; }
// 11 group private int makeGroup(Mesh newMesh, PRIM prim, int startIndex) { int cp = 0; foreach (Vertices vertices in prim.VerticesList) { if (vertices.VertexList.Count < 3) { continue; } List <Vector4> controlPoints = new List <Vector4>(); foreach (RVMUtility.Data.Vertex v in vertices.VertexList) { Vector4 vector = this.CalcMatrix(prim, v.X, v.Y, v.Z); controlPoints.Add(vector); } newMesh.ControlPoints.AddRange(controlPoints); PolygonBuilder builder = new PolygonBuilder(newMesh); builder.Begin(); for (int i = 0; i < controlPoints.Count; i++) { builder.AddVertex(startIndex + i + cp); } builder.End(); cp += controlPoints.Count; } return(cp); }
bool isPolygonSelected() { if (Selection.activeGameObject == null) { return false; } builder = Selection.activeGameObject.GetComponent<PolygonBuilder>(); return builder != null; }
/// <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 static IList<RawProvince> Provinces(string text) { IList<RawProvince> provinces = new List<RawProvince>(); ProvinceBuilder provBuilder = new ProvinceBuilder(); PolygonBuilder polyBuilder = new PolygonBuilder(); foreach (string line in Lines(text)) { Vector2[] vectors; switch (line[0]) { case '§': // New province if (provBuilder.Tag != "") { provBuilder.Polys.Add(polyBuilder.Build()); provinces.Add(provBuilder.Build()); } string[] tokens = line.Split(' '); provBuilder.Tag = tokens[0].Substring(1); if (!TryParseHexColor(tokens[1], out provBuilder.Color)) { Console.Error.WriteLine("Failed to parse color: " + tokens[1]); } break; case '\\': // New hole to existing polygon vectors = ParseVectors(line.Substring(1)); polyBuilder.Holes.Add(new Poly(vectors)); break; default: // New polygon vectors = ParseVectors(line); if (polyBuilder.Outline != null) { provBuilder.Polys.Add(polyBuilder.Build()); } polyBuilder.Outline = new Poly(vectors); break; } } provBuilder.Polys.Add(polyBuilder.Build()); provinces.Add(provBuilder.Build()); return provinces; }
public static Mesh CreateMesh() { // Initialize control points Vector4[] controlPoints = new Vector4[]{ new Vector4( -5.0, 0.0, 5.0, 1.0), new Vector4( 5.0, 0.0, 5.0, 1.0), new Vector4( 5.0, 10.0, 5.0, 1.0), new Vector4( -5.0, 10.0, 5.0, 1.0), new Vector4( -5.0, 0.0, -5.0, 1.0), new Vector4( 5.0, 0.0, -5.0, 1.0), new Vector4( 5.0, 10.0, -5.0, 1.0), new Vector4( -5.0, 10.0, -5.0, 1.0) }; // Initialize mesh object Mesh mesh = new Mesh(); // Add control points to the mesh mesh.ControlPoints.AddRange(controlPoints); // Indices of the vertices per each polygon int[] indices = new int[]{ 0,1,2,3, // front face (Z+) 1,5,6,2, // right side (X+) 5,4,7,6, // back face (Z-) 4,0,3,7, // left side (X-) 0,4,5,1, // bottom face (Y-) 3,2,6,7 // top face (Y+) }; int vertexId = 0; PolygonBuilder builder = new PolygonBuilder(mesh); for (int face = 0; face < 6; face++) { // Start defining a new polygon builder.Begin(); for (int v = 0; v < 4; v++) // The indice of vertice per each polygon builder.AddVertex(indices[vertexId++]); // Finished one polygon builder.End(); } return mesh; }
public static Mesh CreateMeshUsingPolygonBuilder() { // ExStart:CreateMeshUsingPolygonBuilder Vector4[] controlPoints = DefineControlPoints(); // Initialize mesh object Mesh mesh = new Mesh(); // Add control points to the mesh mesh.ControlPoints.AddRange(controlPoints); // Indices of the vertices per each polygon int[] indices = new int[] { 0,1,2,3, // Front face (Z+) 1,5,6,2, // Right side (X+) 5,4,7,6, // Back face (Z-) 4,0,3,7, // Left side (X-) 0,4,5,1, // Bottom face (Y-) 3,2,6,7 // Top face (Y+) }; int vertexId = 0; PolygonBuilder builder = new PolygonBuilder(mesh); for (int face = 0; face < 6; face++) { // Start defining a new polygon builder.Begin(); for (int v = 0; v < 4; v++) // The indice of vertice per each polygon builder.AddVertex(indices[vertexId++]); // Finished one polygon builder.End(); } // ExEnd:CreateMeshUsingPolygonBuilder return mesh; }
// Move the polygon the specified distance and angle private void GeodesicMoveButton_Click(object sender, RoutedEventArgs e) { try { if (_originalOverlay.Graphics.Count == 0) throw new Exception("Digitize a polygon to move."); var coords = _originalOverlay.Graphics[0].Geometry as Multipart; if (coords == null) throw new Exception("Digitize a polygon to move."); var points = coords.Parts.First().GetPoints(); var distance = (double)comboDistance.SelectedItem; var azimuth = (double)sliderAngle.Value; var movedPoints = GeometryEngine.GeodesicMove(points, distance, LinearUnits.Miles, azimuth); Polygon movedPoly = new PolygonBuilder(movedPoints, MyMapView.SpatialReference).ToGeometry(); _movedOverlay.Graphics.Clear(); _movedOverlay.Graphics.Add(new Graphic(movedPoly)); } catch (Exception ex) { var _x = new MessageDialog(ex.Message, "Sample Error").ShowAsync(); } }
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(); } }); }
/// <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(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; }
/// <summary> /// Create polyline features from graphics and add to table /// </summary> /// <param name="graphicsList">List of graphics to add to table</param> /// <returns></returns> private static async Task CreateFeatures(List<Graphic> graphicsList) { RowBuffer rowBuffer = null; try { await QueuedTask.Run(() => { var layer = MapView.Active.GetSelectedLayers()[0]; if (layer is FeatureLayer) { var featureLayer = layer as FeatureLayer; using (var table = featureLayer.GetTable()) { TableDefinition definition = table.GetDefinition(); int shapeIndex = definition.FindField("Shape"); //EditOperation editOperation = new EditOperation(); //editOperation.Callback(context => //{ foreach (Graphic graphic in graphicsList) { //int nameIndex = featureClassDefinition.FindField("NAME"); rowBuffer = table.CreateRowBuffer(); if (graphic.Geometry is Polyline) rowBuffer[shapeIndex] = new PolylineBuilder(graphic.Geometry as Polyline).ToGeometry(); else if (graphic.Geometry is Polygon) rowBuffer[shapeIndex] = new PolygonBuilder(graphic.Geometry as Polygon).ToGeometry(); Row row = table.CreateRow(rowBuffer); //To Indicate that the Map has to draw this feature and/or the attribute table to be updated //context.Invalidate(row); } //}); //bool editResult = editOperation.Execute(); //bool saveResult = await Project.Current.SaveEditsAsync(); } } }); } catch (GeodatabaseException exObj) { Console.WriteLine(exObj); throw; } finally { if (rowBuffer != null) rowBuffer.Dispose(); } }