Statistics

Download Samples Repository

Description

Demonstrates how to use a QueryTask to get statistics from a map service. A statistics query is executed against a US states map service that gets statistics about population in sub-regions. This is combined with another query that retrieves all state features and the result is added to a graphicslayer and a tabular list view.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.Statistics"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
    <Grid x:Name="layoutGrid">
        <esri:MapView x:Name="MyMapView" WrapAround="True">
            <esri:Map InitialViewpoint="-14675766.357,2695407.734,-6733121.861,6583994.101,102100">
                <esri:ArcGISTiledMapServiceLayer 
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="graphicsOverlay" />
			</esri:MapView.GraphicsOverlays>
        </esri:MapView>

        <Border Background="White" BorderBrush="Black" BorderThickness="1"
				Margin="30" Padding="20" Width="300"
                HorizontalAlignment="Right" VerticalAlignment="Top">
			<Border.Effect>
				<DropShadowEffect/>
			</Border.Effect>
			<Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <TextBlock Text="United States Region Statistics" Margin="6" FontSize="14" FontWeight="Bold" />

                <ProgressBar Grid.Row="1" x:Name="progress" IsIndeterminate="True" Margin="10" Visibility="Collapsed" />

                <ListView x:Name="resultsGrid" Grid.Row="2" Margin="0,20,0,0" ItemsSource="{x:Null}" 
                          SelectionMode="Single" SelectionChanged="resultsGrid_SelectionChanged">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="SubRegion" DisplayMemberBinding="{Binding Attributes[sub_region]}" Width="75" />
                            <GridViewColumn Header="Population" DisplayMemberBinding="{Binding Attributes[subregionpopulation], StringFormat='#,#'}" Width="75" />
                            <GridViewColumn Header="States" DisplayMemberBinding="{Binding Attributes[numberofstates]}" Width="50" />
                        </GridView>
                    </ListView.View>
                </ListView>
            </Grid>
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Tasks.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ArcGISRuntime.Samples.Desktop
{
    /// <summary>
    /// Demonstrates how to use a QueryTask to get statistics from a map service. A statistics query is executed against a US states map service that gets statistics about population in sub-regions. This is combined with another query that retrieves all state features and the result is added to a graphicslayer and a tabular list view.
    /// </summary>
    /// <title>Statistics</title>
	/// <category>Tasks</category>
	/// <subcategory>Query</subcategory>
	public partial class Statistics : UserControl
    {
        private const string LAYER_URL = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2";

		private GraphicsOverlay _graphicsOverlay;

        /// <summary>Construct Statistics sample control</summary>
        public Statistics()
        {
            InitializeComponent();

			_graphicsOverlay = MyMapView.GraphicsOverlays["graphicsOverlay"];

			MyMapView.NavigationCompleted += MyMapView_NavigationCompleted;
        }

		private async void MyMapView_NavigationCompleted(object sender, EventArgs e)
		{
			MyMapView.NavigationCompleted -= MyMapView_NavigationCompleted;
			await SetupSymbology();
			await RunQuery();
		}

        // Create a unique value renderer by state sub-region name
		private async Task SetupSymbology()
        {
            try
            {
                // Generate a unique value renderer on the server
                GenerateRendererTask generateRendererTask = new GenerateRendererTask(new Uri(LAYER_URL));

                UniqueValueDefinition uvDef = new UniqueValueDefinition() { Fields = new List<string> { "sub_region" } };
                uvDef.ColorRamps.Add(new ColorRamp() { From = Colors.Purple, To = Colors.Yellow, Algorithm = Algorithm.LabLch });
                GenerateRendererParameters rendererParams = new GenerateRendererParameters() { ClassificationDefinition = uvDef };

                var rendererResult = await generateRendererTask.GenerateRendererAsync(rendererParams);
				_graphicsOverlay.Renderer = rendererResult.Renderer;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Statistics Sample");
            }
        }

        // Query states the for graphics and statistics
        private async Task RunQuery()
        {
            try
            {
                progress.Visibility = Visibility.Visible;
				_graphicsOverlay.Graphics.Clear();
                resultsGrid.ItemsSource = null;

                QueryTask queryTask = new QueryTask(new Uri(LAYER_URL));
                Query query = new Query("1=1")
                {
                    GroupByFieldsForStatistics = new List<string> { "sub_region" },
                    OutStatistics = new List<OutStatistic> 
                    { 
                        new OutStatistic() 
                        {
                            OnStatisticField = "pop2000",
                            OutStatisticFieldName = "SubRegionPopulation",
                            StatisticType = StatisticType.Sum
                        },
                        new OutStatistic()
                        {
                            OnStatisticField = "sub_region",
                            OutStatisticFieldName = "NumberOfStates",
                            StatisticType = StatisticType.Count
                        }
                    }
                };

                var result = await queryTask.ExecuteAsync(query);
                if (result.FeatureSet.Features != null && result.FeatureSet.Features.Count > 0)
                {
                    await CreateSubRegionLayerGraphics(result.FeatureSet.Features.OfType<Graphic>());
					resultsGrid.ItemsSource = _graphicsOverlay.Graphics;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Statistics Sample");
            }
            finally
            {
                progress.Visibility = Visibility.Collapsed;
            }
        }

        private async Task CreateSubRegionLayerGraphics(IEnumerable<Graphic> statistics)
        {
            QueryTask queryTask = new QueryTask(new Uri(LAYER_URL));
            Query query = new Query("1=1")
            {
                ReturnGeometry = true,
                OutSpatialReference = MyMapView.SpatialReference,
                OutFields = new OutFields(new List<string> { "sub_region" })
            };

            var states = await queryTask.ExecuteAsync(query);

            // Create unioned graphics from state geometries for each region
            var regions = states.FeatureSet.Features
                .GroupBy(g => g.Attributes["sub_region"], g => g.Geometry)
                .Select(grp => new Graphic(GeometryEngine.Union(grp), statistics.First(stat => grp.Key.Equals(stat.Attributes["sub_region"])).Attributes));

			_graphicsOverlay.Graphics.Clear();
			_graphicsOverlay.Graphics.AddRange(regions);
        }

        private void resultsGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
			_graphicsOverlay.ClearSelection();

            if (e.AddedItems != null && e.AddedItems.Count > 0)
            {
                var graphic = e.AddedItems[0] as Graphic;
                if (graphic != null)
                    graphic.IsSelected = true;
            }
        }
    }
}
Feedback on this topic?