This sample demonstrates using the GenerateRendererTask to create a class breaks or a unique value renderer on the server without having to retrieve all the data to the client. To use the sample, click either the Generate Range Values or Generate Unique Values button. This updates the renderer on the map.
In the code-behind, a GenerateRendererTask is used to create a renderer, and the LayerDrawingOptions.Renderer is set to the GenerateRendererResultEventArgs.GenerateRendererResult.Renderer to use the generated renderer in the map's display.
<UserControlx:Class="ArcGISWPFSDK.GenerateRenderer"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:esri="http://schemas.esri.com/arcgis/client/2009"><Gridx:Name="LayoutRoot"Background="White"><Grid.Resources><BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter"/><LinearGradientBrushx:Key="PanelGradient"EndPoint="0.5,1"StartPoint="0.5,0"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransformCenterY="0.5"CenterX="0.5"/><SkewTransformCenterY="0.5"CenterX="0.5"/><RotateTransformAngle="176"CenterY="0.5"CenterX="0.5"/><TranslateTransform/></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStopColor="#FF145787"/><GradientStopColor="#FF3D7FAC"Offset="0.184"/><GradientStopColor="#FF88C5EF"Offset="0.984"/></LinearGradientBrush></Grid.Resources><esri:Mapx:Name="MyMap"Background="#FFE3E3E3"><esri:Map.Extent><esri:EnvelopeXMin="-3548912"YMin="-1847469"XMax="2472012"YMax="1742990"><esri:Envelope.SpatialReference><esri:SpatialReferenceWKID="102009"/></esri:Envelope.SpatialReference></esri:Envelope></esri:Map.Extent><esri:ArcGISDynamicMapServiceLayerID="USA"Url="http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer"VisibleLayers="2"/></esri:Map><GridHorizontalAlignment="Left"VerticalAlignment="Top"Margin="10,10,0,10"><RectangleFill="{StaticResource PanelGradient}"Stroke="Gray"RadiusX="10"RadiusY="10"><Rectangle.Effect><DropShadowEffect/></Rectangle.Effect></Rectangle><RectangleMargin="5"RadiusX="5"RadiusY="5"Fill="#DDFFFFFF"Stroke="DarkGray"Width="150"HorizontalAlignment="Left"/><StackPanel><ButtonContent="Generate Range Values"Click="GenerateRangeValueClick"Width="140"Height="30"VerticalAlignment="Top"HorizontalAlignment="Left"Margin="10,10,0,5"/><ButtonContent="Generate Unique Values"Click="GenerateUniqueValueClick"Width="140"Height="30"VerticalAlignment="Top"HorizontalAlignment="Left"Margin="10,0,0,10"/></StackPanel></Grid><ProgressBarx:Name="_progressBar"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 System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using System.ComponentModel;
namespace ArcGISWPFSDK
{
publicpartialclass GenerateRenderer : UserControl, INotifyPropertyChanged
{
GenerateRendererTask generateRendererTask;
publicevent PropertyChangedEventHandler PropertyChanged;
privatebool _isBusy = true;
publicbool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsBusy"));
}
}
}
public GenerateRenderer()
{
InitializeComponent();
// Set the DataContext for the ProgressBar Visibility property data binding
DataContext = this;
// Set up the GenerateRendererTask and wire up event handlers for the ExecuteCompleted and Failed events.
generateRendererTask = new GenerateRendererTask();
generateRendererTask.Url = "http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer/2";
generateRendererTask.ExecuteCompleted += generateRendererTask_ExecuteCompleted;
generateRendererTask.Failed += generateRendererTask_Failed;
// Display the progress bar whilst the map layers are initializing.
MyMap.Layers.LayersInitialized += (o, evt) =>
{
IsBusy = false;
};
// Display the progress bar whilst the map is refreshing in response to a renderer change.
MyMap.Progress += (s, progressEventArgs) =>
{
if (progressEventArgs.Progress == 100)
IsBusy = false;
};
}
privatevoid GenerateRangeValueClick(object sender, RoutedEventArgs e)
{
// Tasks do not support concurrent operations therefore exit if there is a request pendingif (generateRendererTask.IsBusy)
return;
// Display the progress bar
IsBusy = true;
// Create a Class Breaks definition
ClassBreaksDefinition classBreaksDefinition = new ClassBreaksDefinition()
{
ClassificationField = "SQMI",
ClassificationMethod = ClassificationMethod.StandardDeviation,
BreakCount = 5,
StandardDeviationInterval = ESRI.ArcGIS.Client.Tasks.StandardDeviationInterval.OneQuarter
};
// Add a color ramp.
classBreaksDefinition.ColorRamps.Add(new ColorRamp()
{
From = Colors.Blue,
To = Colors.Red,
Algorithm = Algorithm.HSVAlgorithm
});
// Create a new GenerateRendererParameters object and set the ClassificationDefinition.// Also specify a Where clause on the layer to demonstrate excluding features from the classification.
GenerateRendererParameters rendererParams = new GenerateRendererParameters()
{
ClassificationDefinition = classBreaksDefinition,
Where = "STATE_NAME NOT IN ('Alaska', 'Hawaii')"
};
// Asynchronously execute the task.
generateRendererTask.ExecuteAsync(rendererParams, rendererParams.Where);
}
privatevoid GenerateUniqueValueClick(object sender, RoutedEventArgs e)
{
// Tasks do not support concurrent operations therefore exit if there is a request pending.if (generateRendererTask.IsBusy)
return;
// Display the progress bar.
IsBusy = true;
// Create a new definition for a UniqueValueRenderer.
UniqueValueDefinition uniqueValueDefinition = new UniqueValueDefinition()
{
Fields = new List<string>() { "STATE_NAME" }
};
// Add a color ramp.
uniqueValueDefinition.ColorRamps.Add(new ColorRamp()
{
From = Colors.Blue,
To = Colors.Red,
Algorithm = Algorithm.CIELabAlgorithm
});
// Create a new GenerateRendererParameters object and set the ClassificationDefinition.// Also specify a Where clause on the layer to demonstrate excluding features from the classification.
GenerateRendererParameters rendererParams = new GenerateRendererParameters()
{
ClassificationDefinition = uniqueValueDefinition,
Where = "STATE_NAME NOT IN ('Alaska', 'Hawaii')"
};
// Asynchronously execute the task.
generateRendererTask.ExecuteAsync(rendererParams, rendererParams.Where);
}
void generateRendererTask_ExecuteCompleted(object sender, GenerateRendererResultEventArgs e)
{
// Get the result from the event arguments
GenerateRendererResult rendererResult = e.GenerateRendererResult;
// Create a LayerDrawingOptions object for the layer that will be updated
LayerDrawingOptions layerDrawingOptionsParcels = null;
// Create a LayerDrawingOptionsCollection
LayerDrawingOptionsCollection options = null;
// If this is the first execution of this sample create a new LayerDrawingOptionsCollection.if ((MyMap.Layers["USA"] as ArcGISDynamicMapServiceLayer).LayerDrawingOptions == null)
{
options = new LayerDrawingOptionsCollection();
// Add a new LayerDrawingOptions for layer ID 2 using the generated renderer.
options.Add(new LayerDrawingOptions() { LayerID = 2, Renderer = rendererResult.Renderer });
}
else
{
// Otherwise the layer will have an existing LayerDrawingOptionsCollection from a previous button click.
options = (MyMap.Layers["USA"] as ArcGISDynamicMapServiceLayer).LayerDrawingOptions;
// Iterate over the LayerDrawingOptionsCollection. // For layer ID 2 get the existing LayerDrawingOptions object and apply the newly generated renderer.foreach (LayerDrawingOptions drawOption in options)
{
if (drawOption.LayerID == 2)
{
layerDrawingOptionsParcels = drawOption;
drawOption.Renderer = rendererResult.Renderer;
}
}
}
// Retrieve the GenerateRendererParameters Where clause from the GenerateRendererResulteventArgs and create a new LayerDefinition for layer ID 2.if (e.UserState != null)
{
// Create a new LayerDefinition object to apply to the layer
LayerDefinition layerDefinition = new LayerDefinition()
{
LayerID = 2,
Definition = e.UserState asstring
};
// Apply the new LayerDefinition
(MyMap.Layers["USA"] as ArcGISDynamicMapServiceLayer).LayerDefinitions =
new System.Collections.ObjectModel.ObservableCollection<LayerDefinition>() { layerDefinition };
}
// Apply the updated LayerDrawingOptionsCollection to the LayerDrawingOptions property on the layer
(MyMap.Layers["USA"] as ArcGISDynamicMapServiceLayer).LayerDrawingOptions = options;
// The layer must be refreshed in order to update the renderer
(MyMap.Layers["USA"] as ArcGISDynamicMapServiceLayer).Refresh();
}
// Handle the task failed eventvoid generateRendererTask_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Error: " + e.Error.Message);
IsBusy = false;
}
}
}
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Tasks
Imports System.ComponentModel
Namespace ArcGISWPFSDK
PartialPublicClass GenerateRenderer
Inherits UserControl
Implements INotifyPropertyChanged
Private generateRendererTask As GenerateRendererTask
PublicEvent PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private _isBusy AsBoolean = TruePublicProperty IsBusy() AsBooleanGetReturn _isBusy
EndGetSet(value AsBoolean)
_isBusy = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsBusy"))
EndSetEndPropertyPublicSubNew()
InitializeComponent()
' Set the DataContext for the ProgressBar Visibility property data binding
DataContext = Me' Set up the GenerateRendererTask and wire up event handlers for the ExecuteCompleted and Failed events.
generateRendererTask = New GenerateRendererTask()
generateRendererTask.Url = "http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer/2"AddHandler generateRendererTask.ExecuteCompleted, AddressOf generateRendererTask_ExecuteCompleted
AddHandler generateRendererTask.Failed, AddressOf generateRendererTask_Failed
' Display the progress bar whilst the map layers are initializing.AddHandler MyMap.Layers.LayersInitialized, AddressOf Layers_LayersInitialized
' Display the progress bar whilst the map is refreshing in response to a renderer change.AddHandler MyMap.Progress, AddressOf Map_Progress
EndSub' Display the progress bar whilst the map layers are initializing.PrivateSub Layers_LayersInitialized(sender AsObject, e As EventArgs)
IsBusy = FalseEndSub' Display the progress bar whilst the map is refreshing in response to a renderer change.PrivateSub Map_Progress(sender AsObject, e As ProgressEventArgs)
If e.Progress = 100 Then
IsBusy = FalseEndIfEndSubPrivateSub GenerateRangeValueClick(sender AsObject, e As RoutedEventArgs)
' Tasks do not support concurrent operations therefore exit if there is a request pendingIf generateRendererTask.IsBusy ThenReturnEndIf' Display the progress bar
IsBusy = True' Create a new definition for the ClassBreaksRenderer.Dim classBreaksDefinition AsNew ClassBreaksDefinition() With { _
.ClassificationField = "SQMI", _
.ClassificationMethod = ClassificationMethod.StandardDeviation, _
.BreakCount = 5, _
.StandardDeviationInterval = ESRI.ArcGIS.Client.Tasks.StandardDeviationInterval.OneQuarter _
}
' Add a color ramp.
classBreaksDefinition.ColorRamps.Add(New ColorRamp() With { _
.From = Colors.Blue, _
.[To] = Colors.Red, _
.Algorithm = Algorithm.HSVAlgorithm _
})
' Create a new GenerateRendererParameters object and set the ClassificationDefinition.' Also specify a Where clause on the layer to demonstrate excluding features from the classification.Dim rendererParams AsNew GenerateRendererParameters() With _
{
.ClassificationDefinition = classBreaksDefinition, _
.Where = "STATE_NAME NOT IN ('Alaska', 'Hawaii')" _
}
' Asynchronously execute the task.
generateRendererTask.ExecuteAsync(rendererParams, rendererParams.Where)
EndSubPrivateSub GenerateUniqueValueClick(sender AsObject, e As RoutedEventArgs)
' Tasks do not support concurrent operations therefore exit if there is a request pendingIf generateRendererTask.IsBusy ThenReturnEndIf' Display the progress bar
IsBusy = True' Create a new definition for a UniqueValueRenderer.Dim uniqueValueDefinition AsNew UniqueValueDefinition() With { _
.Fields = New List(Of String)() From { _
"STATE_NAME" _
} _
}
' Add a color ramp.
uniqueValueDefinition.ColorRamps.Add(New ColorRamp() With { _
.From = Colors.Blue, _
.[To] = Colors.Red, _
.Algorithm = Algorithm.CIELabAlgorithm _
})
' Create a new GenerateRendererParameters object and set the ClassificationDefinition.' Also specify a Where clause on the layer to demonstrate excluding features from the classification.Dim rendererParams AsNew GenerateRendererParameters() With { _
.ClassificationDefinition = uniqueValueDefinition, _
.Where = "STATE_NAME NOT IN ('Alaska', 'Hawaii')" _
}
' Asynchronously execute the task.
generateRendererTask.ExecuteAsync(rendererParams, rendererParams.Where)
EndSubPrivateSub generateRendererTask_ExecuteCompleted(sender AsObject, e As GenerateRendererResultEventArgs)
' Get the result from the event argumentsDim rendererResult As GenerateRendererResult = e.GenerateRendererResult
' Create a LayerDrawingOptions object for the layer that will be updatedDim layerDrawingOptionsParcels As LayerDrawingOptions = Nothing' Create a LayerDrawingOptionsCollection Dim options As LayerDrawingOptionsCollection = Nothing' If this is the first execution of this sample create a new LayerDrawingOptionsCollection.If TryCast(MyMap.Layers("USA"), ArcGISDynamicMapServiceLayer).LayerDrawingOptions IsNothingThen
options = New LayerDrawingOptionsCollection()
' Add a new LayerDrawingOptions for layer ID 2 using the generated renderer.If layerDrawingOptionsParcels IsNothingThen
options.Add(New LayerDrawingOptions() With { _
.LayerID = 2, _
.Renderer = rendererResult.Renderer _
})
EndIfElse' Otherwise the layer will have an existing LayerDrawingOptionsCollection from a previous button click.
options = TryCast(MyMap.Layers("USA"), ArcGISDynamicMapServiceLayer).LayerDrawingOptions
' Iterate over the LayerDrawingOptionsCollection. ' For layer ID 2 get the existing LayerDrawingOptions object and apply the newly generated renderer.ForEach drawOption As LayerDrawingOptions In options
If drawOption.LayerID = 2 Then
layerDrawingOptionsParcels = drawOption
drawOption.Renderer = rendererResult.Renderer
EndIfNextEndIf' Retrieve the GenerateRendererParameters Where clause from the GenerateRendererResulteventArgs and create a new LayerDefinition for layer ID 2.If e.UserState IsNotNothingThen' Create a new LayerDefinition object to apply to the layerDim layerDefinition AsNew LayerDefinition() With { _
.LayerID = 2, _
.Definition = TryCast(e.UserState, String) _
}
' Apply the new LayerDefinition
TryCast(MyMap.Layers("USA"), ArcGISDynamicMapServiceLayer).LayerDefinitions = New System.Collections.ObjectModel.ObservableCollection(Of LayerDefinition)() From { _
LayerDefinition _
}
EndIf' Apply the updated LayerDrawingOptionsCollection to the LayerDrawingOptions property on the layer
TryCast(MyMap.Layers("USA"), ArcGISDynamicMapServiceLayer).LayerDrawingOptions = options
' The layer must be refreshed in order to update the renderer
TryCast(MyMap.Layers("USA"), ArcGISDynamicMapServiceLayer).Refresh()
EndSub' Handle the task failed eventPrivateSub generateRendererTask_Failed(sender AsObject, e As TaskFailedEventArgs)
MessageBox.Show("Error: " & e.[Error].Message)
EndSubEndClassEndNamespace