Statistics With Map

The sample demonstrates the ability to render statistics results on the Map using local data. The result of Statistics query is added to a graphicslayer then a Query is performed on states sub-layer to get all states in each sub-region. The states in each sub-region are unioned and appended to graphics layer from statistics Query result.
Download Sample Application<UserControl x:Class="ArcGISWPFSDK.LocalStatisticsWithMap" 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/client/2009"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.Resources> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <esri:Map x:Name="MyMap" WrapAround="True" UseAcceleratedDisplay="True" MinimumResolution="2500" Extent="-15000000,2000000,-7000000,8000000" > <esri:ArcGISLocalTiledLayer ID="BaseMap" Path="..\Data\TPKs\Topographic.tpk"/> <esri:GraphicsLayer ID="SumGraphicsLayer"> <esri:GraphicsLayer.MapTip> <Border esri:GraphicsLayer.MapTipHideDelay="00:00:01.5" BorderBrush="Black" BorderThickness="1" Background="WhiteSmoke"> <StackPanel Orientation="Vertical" Margin="5"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Sub-Region: " FontWeight="Bold" /> <TextBlock Text="{Binding [SUB_REGION]}" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Population: " FontWeight="Bold" /> <TextBlock Text="{Binding [SubRegionPopulation]}" /> </StackPanel> </StackPanel> </Border> </esri:GraphicsLayer.MapTip> </esri:GraphicsLayer> </esri:Map> <esri:FeatureDataGrid Grid.Column="1" Margin="5" Map="{Binding ElementName=MyMap}" GraphicsLayer="{Binding ElementName=MyMap, Path=Layers.[SumGraphicsLayer]}" /> <ProgressBar x:Name="MyProgressBar" IsIndeterminate="True" VerticalAlignment="Bottom" Width="200" Height="20" Margin="10" Visibility="{Binding Path=IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar> </Grid> </UserControl>
using System.Collections.Generic; using ESRI.ArcGIS.Client; using ESRI.ArcGIS.Client.Tasks; using System.Linq; using System.Windows.Controls; using System.Windows.Media; using ESRI.ArcGIS.Client.Local; using System.Windows; using System.ComponentModel; namespace ArcGISWPFSDK { public partial class LocalStatisticsWithMap : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private bool _isBusy = true; public bool IsBusy { get { return _isBusy; } set { _isBusy = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("IsBusy")); } } } QueryTask queryTask; LocalMapService _mapService; GraphicsLayer subRegionGraphicsLayer; string _layerUrl; GeometryService _geometryTask; public LocalStatisticsWithMap() { InitializeComponent(); LocalMapService.GetServiceAsync(@"..\Data\MPKS\USCitiesStates.mpk", (localMapService) => { _mapService = localMapService; queryTask = new QueryTask(); queryTask.Url = _mapService.UrlMapService + "/2"; _layerUrl = _mapService.UrlMapService + "/2"; subRegionGraphicsLayer = MyMap.Layers["SumGraphicsLayer"] as GraphicsLayer; // Generate a unique value renderer on the server GenerateRendererTask generateRendererTask = new GenerateRendererTask(); generateRendererTask.Url = _layerUrl; generateRendererTask.ExecuteCompleted += (o, e) => { subRegionGraphicsLayer.Renderer = e.GenerateRendererResult.Renderer; }; UniqueValueDefinition uniqueValueDefinition = new UniqueValueDefinition() { Fields = new List<string>() { "SUB_REGION" } }; uniqueValueDefinition.ColorRamps.Add(new ColorRamp() { From = Colors.Purple, To = Colors.Yellow, Algorithm = Algorithm.LabLChAlgorithm }); GenerateRendererParameters rendererParams = new GenerateRendererParameters() { ClassificationDefinition = uniqueValueDefinition, }; generateRendererTask.ExecuteAsync(rendererParams); QueryTask queryTask1 = new QueryTask(_layerUrl); Query queryAllStates = new Query() { ReturnGeometry = true, OutSpatialReference = MyMap.SpatialReference, Where = "1=1" }; queryAllStates.OutFields.Add("SUB_REGION"); queryTask1.ExecuteCompleted += (c, d) => { // Return statistics for states layer. Population and total count of states grouped by sub-region. QueryTask queryTask2 = new QueryTask(_layerUrl); Query query = new Query() { GroupByFieldsForStatistics = new List<string> { "SUB_REGION" }, OutStatistics = new List<OutStatistic> { new OutStatistic(){ OnStatisticField = "POP2010", OutStatisticFieldName = "SubRegionPopulation", StatisticType = StatisticType.Sum }, new OutStatistic(){ OnStatisticField = "SUB_REGION", OutStatisticFieldName = "NumberOfStates", StatisticType = StatisticType.Count } } }; queryTask2.ExecuteCompleted += (e, f) => { // foreach group (sub-region) returned from statistic results foreach (Graphic regionGraphic in f.FeatureSet.Features) { // Collection of graphics based on sub-region IEnumerable<Graphic> toUnion = (f.UserState as FeatureSet).Features.Where(stateGraphic => (string)stateGraphic.Attributes["SUB_REGION"] == (string)regionGraphic.Attributes["SUB_REGION"]); // Union graphics based on sub-region, add to graphics layer LocalGeometryService.GetServiceAsync(lgs => { _geometryTask = new GeometryService(); _geometryTask.Url = lgs.UrlGeometryService; _geometryTask.UnionCompleted += (g, h) => { Graphic unionedGraphic = h.UserState as Graphic; unionedGraphic.Geometry = h.Result; subRegionGraphicsLayer.Graphics.Add(unionedGraphic); DataContext = this; IsBusy = false; }; _geometryTask.UnionAsync(toUnion.ToList(), regionGraphic); }); } }; queryTask2.ExecuteAsync(query, d.FeatureSet); }; queryTask1.ExecuteAsync(queryAllStates); }); } private void GeometryService_Failed(object sender, TaskFailedEventArgs e) { MessageBox.Show("Geometry Service error: " + e.Error); } }; }
Imports System.Collections.Generic Imports ESRI.ArcGIS.Client Imports ESRI.ArcGIS.Client.Tasks Imports System.Linq Imports System.Windows.Controls Imports System.Windows.Media Imports ESRI.ArcGIS.Client.Local Imports System.Windows Imports System.ComponentModel Namespace ArcGISWPFSDK Partial Public Class LocalStatisticsWithMap Inherits UserControl Implements INotifyPropertyChanged Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private _isBusy As Boolean = True Public Property IsBusy() As Boolean Get Return _isBusy End Get Set(value As Boolean) _isBusy = value RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsBusy")) End Set End Property Private queryTask As QueryTask Private _mapService As LocalMapService Private subRegionGraphicsLayer As GraphicsLayer Private _layerUrl As String Private _geometryTask As GeometryService Public Sub New() InitializeComponent() LocalMapService.GetServiceAsync("..\Data\MPKS\USCitiesStates.mpk", Function(localMapService__1) _mapService = localMapService__1 queryTask = New QueryTask() queryTask.Url = _mapService.UrlMapService & "/2" End Function) subRegionGraphicsLayer = TryCast(MyMap.Layers("SumGraphicsLayer"), GraphicsLayer) ' Generate a unique value renderer on the server Dim generateRendererTask As New GenerateRendererTask() generateRendererTask.Url = _layerUrl AddHandler generateRendererTask.ExecuteCompleted, Sub(o, e) subRegionGraphicsLayer.Renderer = e.GenerateRendererResult.Renderer Dim uniqueValueDefinition As UniqueValueDefinition = New UniqueValueDefinition() With { .Fields = New List(Of String)() From {"SUB_REGION"} } uniqueValueDefinition.ColorRamps.Add(New ColorRamp() With {.From = Colors.Purple, .To = Colors.Yellow, .Algorithm = Algorithm.LabLChAlgorithm }) Dim rendererParams As GenerateRendererParameters = New GenerateRendererParameters() With {.ClassificationDefinition = uniqueValueDefinition} generateRendererTask.ExecuteAsync(rendererParams) ' When layers initialized, return all states, generate statistics for a group, ' union graphics based on grouped statistics AddHandler MyMap.Layers.LayersInitialized, Sub(a, b) Dim queryTask1 As New QueryTask(_layerUrl) Dim queryAllStates As New Query() With {.ReturnGeometry = True, .OutSpatialReference = MyMap.SpatialReference, .Where = "1=1"} queryAllStates.OutFields.Add("SUB_REGION") AddHandler queryTask1.ExecuteCompleted, Sub(c, d) Dim queryTask2 As New QueryTask(_layerUrl) Dim query As Query = New Query() With {.GroupByFieldsForStatistics = New List(Of String) From {"SUB_REGION"}, .OutStatistics = New List(Of OutStatistic) From { New OutStatistic() With {.OnStatisticField = "POP2000", .OutStatisticFieldName = "SubRegionPopulation", .StatisticType = StatisticType.Sum }, New OutStatistic() With {.OnStatisticField = "SUB_REGION", .StatisticType = StatisticType.Count, .OutStatisticFieldName = "NumberOfStates" } } } AddHandler queryTask2.ExecuteCompleted, Sub(e, f) ' foreach group (sub-region) returned from statistic results For Each regionGraphic As Graphic In f.FeatureSet.Features ' Collection of graphics based on sub-region Dim toUnion As IEnumerable(Of Graphic) = (TryCast(f.UserState, FeatureSet)).Features.Where(Function(stateGraphic) CStr(stateGraphic.Attributes("SUB_REGION")) = CStr(regionGraphic.Attributes("SUB_REGION"))) ' Union graphics based on sub-region, add to graphics layer LocalGeometryService.GetServiceAsync(Function(lgs) _geometryTask = New GeometryService() _geometryTask.Url = lgs.UrlGeometryService AddHandler _geometryTask.UnionCompleted, Sub(g, h) Dim unionedGraphic As Graphic = TryCast(h.UserState, Graphic) unionedGraphic.Geometry = h.Result subRegionGraphicsLayer.Graphics.Add(unionedGraphic) DataContext = Me IsBusy = False End Sub _geometryTask.UnionAsync(toUnion.ToList(), regionGraphic) End Function) Next regionGraphic End Sub queryTask2.ExecuteAsync(query, d.FeatureSet) End Sub queryTask1.ExecuteAsync(queryAllStates) End Sub End Sub End Class End Namespace
Copyright © 1995-2014 Esri. All rights reserved.
5/16/2014