ArcGIS Runtime SDK for .NET (WPF)

Get feature statistics

The statistics query API allows you to get any of the following statistics for a specified field in a feature table: Sum, Average, Count, Minimum, Maximum, Standard Deviation, or Variance. In the statistics query parameters, you can define filters for features to include in the statistics (based on attributes, spatial relationships, or time extent) as well as how the results are grouped and sorted.

Follow these steps to query a feature table for statistical information:

  1. Load a feature table that supports statistical queries from a local or online data source. This may be a layer shown in a map view in your app, or a table you’ve loaded but not displayed.

    // URI for the US states map service
    Uri usaStatesServiceUri = new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
    
    
    // Create the US states feature table directly
    _usStatesTable = new ServiceFeatureTable(usaStatesServiceUri);            
    
    
    // Load the table
    await _usStatesTable.LoadAsync();
    
    
    // (You can also get tables for layers in the map)
    // - FeatureLayer
    _usStatesTable = statesFeatureLayer.FeatureTable;
    // - ArcGISMapImageSublayer
    _usStatesTable = usaStatesSublayer.Table;
    // - A collection of non-spatial tables from an ArcGISMapImageLayer
    IReadOnlyList<ServiceFeatureTable> nonGeoTables = usaMapImageLayer.Tables;

  2. Define statistics to return from the query. Create a StatisticDefinition for each statistic you want to query from the table. This includes the field name, statistic type, and output alias name for the result.

    // Create each statistic definition for the query
    var statDefAvgPop = new StatisticDefinition("POP", StatisticType.Average, "AveragePop");
    var statDefSumPop = new StatisticDefinition("POP", StatisticType.Sum, "TotalPop");
    var statDefCount = new StatisticDefinition("OBJECTID", StatisticType.Count, "StateCount");

  3. Create a StatisticsQueryParameters object, passing in your list of (one or more) statistic definitions.

    // Create a list of the definitions
    var statisticDefinitions = new List<StatisticDefinition>
    {
        statDefAvgPop, statDefSumPop, statDefCount
    };
    
    
    // Create a new StatisticsQueryParameters object, pass in the list of definitions
    var statisticsQueryParams = new StatisticsQueryParameters(statisticDefinitions);

  4. Define spatial, attribute, or temporal filters (if any) and add them to the query parameters.

    // Filter the query to only include features in an area of interest
    statisticsQueryParams.Geometry = areaOfInterestPolygon;
    statisticsQueryParams.SpatialRelationship = SpatialRelationship.Intersects;

  5. Specify the fields you want to group and order the results with.

    // Use the SUB_REGION field to group results
    statisticsQueryParams.GroupByFieldNames.Add("SUB_REGION");
    
    
    // Create an OrderBy object to sort on the SUB_REGION field in ascending order
    var orderSubregion = new OrderBy("SUB_REGION", SortOrder.Ascending);
    statisticsQueryParams.OrderByFields.Add(orderSubregion);

  6. Execute the query. The results are returned as a StatisticsQueryResult.

    // Execute the statistical query with these parameters and await the results
    StatisticsQueryResult statQueryResult = await _usStatesTable.QueryStatisticsAsync(statisticsQueryParams);

  7. Iterate the result records to read the statistic values. The output alias name defined for each statistic definitions is the key for a corresponding value. If results were grouped, iterate the group names and associated collection of values.

    var groupedResults = new Dictionary<string, IReadOnlyDictionary<string, object>>();
    
    
    // Iterate all records in the results and create a dictionary to show in a (hierarchical) tree view
    foreach (StatisticRecord record in statQueryResult)
    {
        // Create a name for this group by joining all group field values
        string groupName = string.Join(",", record.Group.Values);
    
    
        // Add a dictionary entry with group stats using the group name as the key
        groupedResults.Add(groupName, record.Statistics);
    }
    
    
    // Set the tree view data source 
    ResultsTreeView.ItemsSource = groupedResults;

Tables that support statistical queries

To see if a feature table supports a statistical query, check ArcGISFeatureLayerInfo.SupportsStatistics for a feature layer or ArcGISMapServiceSublayerInfo.SupportsStatistics for an ArcGIS map image sublayer.

Note:

If the query capability is disabled in the service capabilities, then statistics query is also disabled.

When using a service feature table (reading data from an online service, in other words), statistical queries are executed on the service unless the table is in manual cache mode, in which case the query executes on the locally available (cached) data. All other feature tables also execute statistical queries against a local data source.

Define a statistics query

Use a StatisticsQueryParameters to define:

  • Statistics to calculate and their output alias field names
  • How results are grouped and ordered
  • Filters that restrict which features are evaluated

Each of these are described in the following sections.

Statistic definitions

A StatisticDefinition specifies the name of the field that contains values to query, the statistic type, and the output (alias) name to use for the results. A statistics query must contain at least one statistic definition, but may contain several. A field of any data type can be used for statistic types Count, Minimum, or Maximum, which will return the number of values, first value, or last value (when sorted in ascending order) respectively. Other statistic types: Average, Sum, Standard Deviation, and Variance are only valid for numeric fields. If these statistics are attempted on a non-numeric field, you will receive an error from the server ("unable to complete operation").

If the output statistic alias name is empty or missing, a default name will be assigned by the map server for the returned statistic field. The server-generated output name is composed of the field name and the statistic type separated by an underscore. If you specify a name, it can only contain alphanumeric characters and an underscore. If the output name is a reserved keyword of the underlying DBMS, the operation may fail.

Group and order results

Unless otherwise specified, the results from a statistical query will not be grouped using a table attribute. In this case, the statistic values returned are single values that describe all the input features. If one or more group fields are specified, the results contain a value for each statistic for each group. If getting average population for world cities grouped by countries, for example, each country would have a value for the average population of their cities. Without this grouping, you would get a single value for all cities in the world.

Results are also not ordered unless you specify one or several fields to sort on. The fields you choose to order results by must be fields you've also chosen for grouping. The following example shows results for statistics on US states grouped by sub-region. The results are also sorted by sub-region (in ascending order).

Statistics query results grouped and ordered by sub-region.

Filter features to evaluate

You can define any combination of spatial, attribute, or temporal criteria to filter the features that are evaluated by the statistical query. If none of these filters are set, the query will be evaluated against all features in the table.

  • Attribute—define a where expression that uses any of the fields in the table.
  • Spatial—use a geometry object and a spatial relationship.
  • Temporal—specify a time or time range.

Process results from a statistical query

The results from a statistical query are returned as an enumerator of StatisticRecord objects. Each record describes a group and contains a dictionary of group values and a dictionary of statistic values. The group dictionary contains key/value pairs that describe each group field, with the field name ("SUB_REGION", for example) as the key for the field value ("Mountain", for example). Since multiple group fields can be specified for a query, each record in the results represents a unique combination of the group field values.

The statistics dictionary for each record contains the requested statistics for the group. The key for each statistic value is the alias name (by default, in the form fieldName_statisticType). If no group fields were specified for the query, the groups dictionary is empty and a single set of statistics are returned to describe all features included in the query.