예제 #1
0
        // 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);
        }
예제 #4
0
        // 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);
        }
예제 #5
0
        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);
        }
예제 #7
0
        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());
        }
예제 #8
0
        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;
        }