// Intersects feature geometries with a user defined polygon. private async void IntersectButton_Click(object sender, RoutedEventArgs e) { try { _resultGraphics.Graphics.Clear(); // wait for user to draw a polygon Polygon userpoly = await MyMapView.Editor.RequestShapeAsync(DrawShape.Polygon) as Polygon; Polygon poly = GeometryEngine.NormalizeCentralMeridian(userpoly) as Polygon; // get intersecting features from the feature layer SpatialQueryFilter filter = new SpatialQueryFilter(); filter.Geometry = GeometryEngine.Project(poly, _statesLayer.FeatureTable.SpatialReference); filter.SpatialRelationship = SpatialRelationship.Intersects; filter.MaximumRows = 52; var stateFeatures = await _statesLayer.FeatureTable.QueryAsync(filter); // Intersect the feature geometries and add to graphics layer var states = stateFeatures.Select(feature => feature.Geometry); var intersectGraphics = states .Select(state => GeometryEngine.Intersection(state, poly)) .Select(geo => new Graphic(geo, _fillSymbol)); _resultGraphics.Graphics.AddRange(intersectGraphics); } catch (Exception ex) { var _x = new MessageDialog("Intersection Error: " + ex.Message, "Sample Error").ShowAsync(); } }
// Handle selection events in the spatial operations picker. private void OperationModel_ValueChanged(object sender, EventArgs e) { // Get the data model that contains the spatial operation choices. PickerDataModel operationsModel = (PickerDataModel)_operationPicker.Model; // If an operation hasn't been selected, return. if (operationsModel.SelectedItem == "") { return; } // Remove any currently displayed result. _polygonsOverlay.Graphics.Remove(_resultGraphic); // Polygon geometry from the input graphics. Geometry polygonOne = _graphicOne.Geometry; Geometry polygonTwo = _graphicTwo.Geometry; // Result polygon for spatial operations. Geometry resultPolygon = null; // Run the selected spatial operation on the polygon graphics and get the result geometry. switch (operationsModel.SelectedItem) { case "Union": resultPolygon = GeometryEngine.Union(polygonOne, polygonTwo); break; case "Difference": resultPolygon = GeometryEngine.Difference(polygonOne, polygonTwo); break; case "Symmetric difference": resultPolygon = GeometryEngine.SymmetricDifference(polygonOne, polygonTwo); break; case "Intersection": resultPolygon = GeometryEngine.Intersection(polygonOne, polygonTwo); break; } // Create a black outline symbol to use for the result polygon. SimpleLineSymbol outlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Black, 1); // Create a solid red fill symbol for the result polygon graphic. SimpleFillSymbol resultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.Red, outlineSymbol); // Create the result polygon graphic and add it to the graphics overlay. _resultGraphic = new Graphic(resultPolygon, resultSymbol); _polygonsOverlay.Graphics.Add(_resultGraphic); }
private void OperationsPicker_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e) { // If an operation hasn't been selected, return. if (_operationPicker.SelectedItem.ToString() == "") { return; } // Remove any currently displayed result. _polygonsOverlay.Graphics.Remove(_resultGraphic); // Polygon geometry from the input graphics. Geometry polygonOne = _graphicOne.Geometry; Geometry polygonTwo = _graphicTwo.Geometry; // Result polygon for spatial operations. Geometry resultPolygon = null; // Run the selected spatial operation on the polygon graphics and get the result geometry. string selectedOperation = _operationPicker.SelectedItem.ToString(); switch (selectedOperation) { case "Union": resultPolygon = GeometryEngine.Union(polygonOne, polygonTwo); break; case "Difference": resultPolygon = GeometryEngine.Difference(polygonOne, polygonTwo); break; case "Symmetric difference": resultPolygon = GeometryEngine.SymmetricDifference(polygonOne, polygonTwo); break; case "Intersection": resultPolygon = GeometryEngine.Intersection(polygonOne, polygonTwo); break; } // Create a black outline symbol to use for the result polygon. SimpleLineSymbol outlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Black, 1); // Create a solid red fill symbol for the result polygon graphic. SimpleFillSymbol resultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.Red, outlineSymbol); // Create the result polygon graphic and add it to the graphics overlay. _resultGraphic = new Graphic(resultPolygon, resultSymbol); _polygonsOverlay.Graphics.Add(_resultGraphic); }
// Handle the spatial operation selection by performing the operation and showing the result polygon. private void SpatialOperationComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { // If an operation hasn't been selected, return. if (SpatialOperationComboBox.SelectedItem == null) { return; } // Remove any currently displayed result. _polygonsOverlay.Graphics.Remove(_resultGraphic); // Polygon geometry from the input graphics. Geometry polygonOne = _graphicOne.Geometry; Geometry polygonTwo = _graphicTwo.Geometry; // Result polygon for spatial operations. Geometry resultPolygon = null; // Run the selected spatial operation on the polygon graphics and get the result geometry. string operation = (string)SpatialOperationComboBox.SelectedItem; switch (operation) { case "Union": resultPolygon = GeometryEngine.Union(polygonOne, polygonTwo); break; case "Difference": resultPolygon = GeometryEngine.Difference(polygonOne, polygonTwo); break; case "Symmetric difference": resultPolygon = GeometryEngine.SymmetricDifference(polygonOne, polygonTwo); break; case "Intersection": resultPolygon = GeometryEngine.Intersection(polygonOne, polygonTwo); break; } // Create a black outline symbol to use for the result polygon. SimpleLineSymbol outlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.Black, 1); // Create a solid red fill symbol for the result polygon graphic. SimpleFillSymbol resultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, System.Drawing.Color.Red, outlineSymbol); // Create the result polygon graphic and add it to the graphics overlay. _resultGraphic = new Graphic(resultPolygon, resultSymbol); _polygonsOverlay.Graphics.Add(_resultGraphic); }
private async void Initialize() { _markerSymbol = layoutGrid.Resources["markerSymbol"] as Symbol; _pointFeatureOverlay = MyMapView.GraphicsOverlays["pointFeatureOverlay"]; // City Layer FeatureLayer cityLayer = new FeatureLayer(new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0")); // State Layer FeatureLayer stateLayer = new FeatureLayer(new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2")); MyMap.OperationalLayers.Add(cityLayer); MyMap.OperationalLayers.Add(stateLayer); // State Query QueryParameters stateQueryParameters = new QueryParameters(); // only select one polygon from State layer stateQueryParameters.WhereClause = "state_name = 'California'"; // Query the State feature table FeatureQueryResult stateQueryResult = await stateLayer.FeatureTable.QueryFeaturesAsync(stateQueryParameters); var stateResult = stateQueryResult.ToList(); // City Query QueryParameters cityQueryParameter = new QueryParameters(); cityQueryParameter.WhereClause = "1=1"; // Query the City feature table FeatureQueryResult cityQueryResult = await cityLayer.FeatureTable.QueryFeaturesAsync(cityQueryParameter); var cities = cityQueryResult.Select(feature => feature.Geometry); var city_name = cityQueryResult.Select(feature => feature.Attributes); var citiesWithinState = cities .Select(city => GeometryEngine.Intersection(city, stateResult[0].Geometry)) .Select(city => new Graphic(city, _markerSymbol)); foreach (Graphic g in citiesWithinState) { _pointFeatureOverlay.Graphics.Add(g); } }
void _operationChoiceButton_ValueChanged(object sender, EventArgs e) { // Remove any currently displayed result. _polygonsOverlay.Graphics.Remove(_resultGraphic); // Polygon geometry from the input graphics. Geometry polygonOne = _graphicOne.Geometry; Geometry polygonTwo = _graphicTwo.Geometry; // Result polygon for spatial operations. Geometry resultPolygon = null; // Run the selected spatial operation on the polygon graphics and get the result geometry. switch (_operationChoiceButton.SelectedSegment) { case 0: resultPolygon = GeometryEngine.Difference(polygonOne, polygonTwo); break; case 1: resultPolygon = GeometryEngine.Intersection(polygonOne, polygonTwo); break; case 2: resultPolygon = GeometryEngine.SymmetricDifference(polygonOne, polygonTwo); break; case 3: resultPolygon = GeometryEngine.Union(polygonOne, polygonTwo); break; } // Create a black outline symbol to use for the result polygon. SimpleLineSymbol outlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Black, 1); // Create a solid red fill symbol for the result polygon graphic. SimpleFillSymbol resultSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.Red, outlineSymbol); // Create the result polygon graphic and add it to the graphics overlay. _resultGraphic = new Graphic(resultPolygon, resultSymbol); _polygonsOverlay.Graphics.Add(_resultGraphic); }
protected Task <bool> ExecuteCut(Geometry geometry) { if (geometry == null) { return(Task.FromResult(false)); } // create an edit operation EditOperation op = new EditOperation(); op.Name = "Cut Elements"; op.ProgressMessage = "Working..."; op.CancelMessage = "Operation canceled."; op.ErrorMessage = "Error cutting polygons"; op.SelectModifiedFeatures = false; op.SelectNewFeatures = false; // create a collection of feature layers that can be edited var editableLayers = ActiveMapView.Map.GetLayersAsFlattenedList().OfType <FeatureLayer>() .Where(lyr => lyr.CanEditData() == true).Where(lyr => lyr.ShapeType == ArcGIS.Core.CIM.esriGeometryType.esriGeometryPolygon); // for each of the layers foreach (FeatureLayer editableFeatureLayer in editableLayers) { // get the feature class associated with the layer Table fc = editableFeatureLayer.GetTable(); // initialize a list of ObjectIDs that need to be cut var cutOIDs = new List <long>(); // find the features crossed by the sketch geometry var rowCursor = fc.Search(geometry, SpatialRelationship.Crosses); // add the feature IDs into our prepared list while (rowCursor.MoveNext()) { var feature = rowCursor.Current as Feature; if (feature == null) { break; } if (feature.GetShape() != null) { // we are interested in the intersection points // in case there is only one intersection then the sketch geometry doesn't enter and leave the // base geometry and the cut operation won't work. Geometry intersectionGeometry = GeometryEngine.Intersection(feature.GetShape(), geometry, GeometryDimension.esriGeometry0Dimension); if (intersectionGeometry is Multipoint) { var intersectionPoints = intersectionGeometry as Multipoint; // we are only interested in feature IDs where the count of intersection points is larger than 1 // i.e., at least one entry and one exit if (intersectionPoints.Points.Count > 1) { // add the current feature to the overall list of features to cut cutOIDs.Add(rowCursor.Current.GetObjectID()); } } } } // add the elements to cut into the edit operation op.Cut(editableFeatureLayer, cutOIDs, geometry); } //execute the operation return(op.ExecuteAsync()); }
protected async Task <bool> ExecuteCut(EditingTemplate template, Geometry geometry, Dictionary <string, object> attributes) { if (template == null) { return(false); } if (geometry == null) { return(false); } // create an edit operation EditOperation op = EditingModule.CreateEditOperation(); op.Name = "Cut Elements"; op.ProgressMessage = "Working..."; op.CancelMessage = "Operation canceled."; op.ErrorMessage = "Error cutting polygons"; op.SelectModifiedFeatures = false; op.SelectNewFeatures = false; // get the feature class associated with the layer Table fc = await template.Layer.GetTableAsync(); // initialize a list of ObjectIDs that need to be cut var cutOIDs = new List <long>(); // on a separate thread await QueuingTaskFactory.StartNew(async() => { // TODO // find the features crossed by the sketch geometry RowCursor rc = await fc.SearchAsync(geometry, SpatialRelationship.Crosses); // add the feature IDs into our prepared list while (rc.MoveNext()) { var feature = rc.Current as Feature; if (feature == null) { break; } if (feature.Shape != null) { // we are interested in the intersection points // in case there is only one intersection then the sketch geometry doesn't enter and leave the // base geometry and the cut operation won't work. Geometry intersectionGeometry = GeometryEngine.Intersection(feature.Shape, geometry, GeometryDimension.esriGeometry0Dimension); if (intersectionGeometry is MultiPoint) { //var intersectionPoints = intersectionGeometry as MultiPoint; //// we are only interested in feature IDs where the count of intersection points is larger than 1 //// i.e., at least one entry and one exit //if (intersectionPoints.Coordinates.Count > 1) //{ // // add the current feature to the overall list of features to cut // cutOIDs.Add(rc.Current.ObjectID); //} } } } }); // add the elements to cut into the edit operation op.Cut(template.Layer, cutOIDs, geometry); //execute the operation bool operationResult = await op.ExecuteAsync(); return(operationResult); }
private void Update(ShapefileFeatureTable sf, CancellationToken ct, IProgress <int> p) { Task.Run(async() => { var directory = Globals.Model.Assets.PathTo("BasinShapefile"); if (String.IsNullOrWhiteSpace(directory)) { MessageBox.Show("You need to have imported a basin shapefile."); Clear(); return; } var file = Directory.EnumerateFiles(directory, "*.shp").FirstOrDefault(); if (String.IsNullOrWhiteSpace(file)) { MessageBox.Show("Error reading the basin shapefile."); Clear(); return; } var ci = Globals.Model.EcosystemVitality.FetchIndicator <ConnectivityIndicator>(); var reaches = ci?.Reaches; if (reaches == null) { MessageBox.Show( "You must import a river network for the Connectivity Indicator in Ecosystem Vitality."); Clear(); return; } var bsf = await ShapefileFeatureTable.OpenAsync(file); var allQuery = new QueryParameters { Geometry = bsf.Extent, SpatialRelationship = SpatialRelationship.Contains }; ConservationAreaIndicator.TotalProtectedArea = 0; ConservationAreaIndicator.TotalArea = 0; foreach (var mapFeature in await bsf.QueryFeaturesAsync(allQuery)) { if (ct.IsCancellationRequested) { Clear(); return; } ConservationAreaIndicator.TotalArea += GeometryEngine.AreaGeodetic(mapFeature.Geometry); var areaFeatures = await sf.QueryFeaturesAsync(new QueryParameters { Geometry = mapFeature.Geometry, SpatialRelationship = SpatialRelationship.Contains }); foreach (var feature in areaFeatures) { ConservationAreaIndicator.TotalProtectedArea += GeometryEngine.AreaGeodetic(feature.Geometry); if (ct.IsCancellationRequested) { Clear(); return; } } } p.Report(25); // todo: this is not an efficient algorithm var pb = new PolylineBuilder(new SpatialReference(Model.Attributes.Wkid)); foreach (var reach in reaches) { pb.AddPart( reach.Nodes.Select(node => new MapPoint(node.Location.Longitude, node.Location.Latitude))); } var mapGeometry = pb.ToGeometry(); ConservationAreaIndicator.TotalLength = GeometryEngine.Length(mapGeometry); if (ct.IsCancellationRequested) { Clear(); return; } var lengthFeatures = await sf.QueryFeaturesAsync(new QueryParameters { Geometry = sf.Extent, SpatialRelationship = SpatialRelationship.Contains }); var tpl = 0.0; var reachNumber = 0; foreach (var reach in reaches) { var poly = new PolylineBuilder(new SpatialReference(Model.Attributes.Wkid)); poly.AddPart(reach.Nodes.Select(node => new MapPoint(node.Location.Longitude, node.Location.Latitude))); var pg = poly.ToGeometry(); foreach (var feature in lengthFeatures) { var intersection = GeometryEngine.Intersection(pg, feature.Geometry) as Polyline; if (intersection?.Parts.Count > 0) { tpl += GeometryEngine.Length(pg); } if (ct.IsCancellationRequested) { Clear(); return; } } p.Report(25 + (int)(75.0 * reachNumber++ / reaches.Count)); } ConservationAreaIndicator.TotalProtectedLength = tpl; }, ct).Wait(ct); }
private async Task DoIntersection() { intersectGraphicsLayer.Graphics.Clear(); ResetButton.IsEnabled = false; try { if (MyMapView.Editor.IsActive) { MyMapView.Editor.Cancel.Execute(null); } // Wait for user to draw a polygon Polygon userpoly = await MyMapView.Editor.RequestShapeAsync(DrawShape.Polygon) as Polygon; Polygon inputGeom = GeometryEngine.NormalizeCentralMeridian(userpoly) as Polygon; if (inputGeom != null) { //Add the polygon drawn by the user var g = new Graphic { Geometry = inputGeom, Symbol = new SimpleFillSymbol { Outline = new SimpleLineSymbol { Width = 2, Color = Colors.Gray }, Style = SimpleFillStyle.Null } }; intersectGraphicsLayer.Graphics.Add(g); //Optional - Simplify the input geometry inputGeom = GeometryEngine.Simplify(inputGeom) as Polygon; //Do the intersection for each of the graphics in the parcels layer foreach (var parcel in parcelGraphicsLayer.Graphics) { var intersected = GeometryEngine.Intersection(inputGeom, parcel.Geometry); if (intersected != null) { var color = Color.FromArgb((byte)100, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)); intersectGraphicsLayer.Graphics.Add(new Graphic { Geometry = intersected, Symbol = new SimpleFillSymbol { Color = color, Outline = new SimpleLineSymbol { Color = Colors.Black, Width = 2 } } }); } } } } catch (Exception) { } ResetButton.IsEnabled = true; }