This sample demonstrates using an ESRI.ArcGIS.Client.Tasks GeometryService that takes two or more input polygons and returns a polygon that is the union of the inputs. The input polygons do not have to be contiguous (i.e. touching) to be unioned. Polygons that are spatially disparate, like islands, can be unioned into one polygon.
To use the sample, click on the parcel polygons to select or unselect graphic features. Click on the Union button to union selected parcels.
<UserControlx:Class="ArcGISWPFSDK.Union"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"><Gridx:Name="LayoutRoot"><Grid.Resources><esri:SimpleLineSymbolx:Key="RedLineSymbol"Color="Red"Width="4"Style="Solid"/><esri:FillSymbolx:Key="BlueFillSymbol"><esri:FillSymbol.ControlTemplate><ControlTemplatex:Name="CustomPolygonTemplate"><Grid><VisualStateManager.VisualStateGroups><VisualStateGroupx:Name="CommonStates"><VisualStatex:Name="Unselected"/><VisualStatex:Name="Selected"><Storyboard><ColorAnimationStoryboard.TargetName="Element"Storyboard.TargetProperty="(Fill).(Color)"To="#99FFFF00"Duration="0:0:0.1"/></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups><Pathx:Name="Element"Stroke="Red"Fill="#660000FF"StrokeStartLineCap="Round"StrokeThickness="2"StrokeLineJoin="Round"StrokeEndLineCap="Round"/></Grid></ControlTemplate></esri:FillSymbol.ControlTemplate></esri:FillSymbol><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"Offset="0.16"/><GradientStopColor="#FF3D7FAC"Offset="0.502"/><GradientStopColor="#FF88C5EF"Offset="0.984"/></LinearGradientBrush></Grid.Resources><esri:Mapx:Name="MyMap"Extent="-83.3188395774275,42.61428312652851,-83.31295664068958,42.61670913269855"><esri:ArcGISTiledMapServiceLayerID="StreetMapLayer"Url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/><esri:GraphicsLayerID="ParcelsGraphicsLayer"/></esri:Map><GridHorizontalAlignment="Right"VerticalAlignment="Top"Margin="0,10,10,0"><RectangleFill="{StaticResource PanelGradient}"Stroke="Gray"RadiusX="10"RadiusY="10"Margin="0,0,0,5"><Rectangle.Effect><DropShadowEffect/></Rectangle.Effect></Rectangle><RectangleFill="#FFFFFFFF"Stroke="DarkGray"RadiusX="5"RadiusY="5"Margin="10,10,10,15"/><StackPanelOrientation="Vertical"HorizontalAlignment="Center"Margin="30,20,20,30"><TextBlockx:Name="ResponseTextBlock"Width="200"Text="Click on the parcel polygons to select or unselect graphic features. Click on the Union button to union selected parcels."TextAlignment="Left"TextWrapping="Wrap"Foreground="Black"/><ButtonContent="Union"Margin="0,5,5,0"x:Name="UnionButton"Width="100"Click="UnionButton_Click"IsEnabled="False"/></StackPanel></Grid></Grid></UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
namespace ArcGISWPFSDK
{
publicpartialclass Union : UserControl
{
private Draw MyDrawObject;
private GraphicsLayer parcelGraphicsLayer;
List<Graphic> selectedGraphics = new List<Graphic>();
public Union()
{
InitializeComponent();
MyMap.Layers.LayersInitialized += Layers_LayersInitialized;
MyMap.MinimumResolution = double.Epsilon;
MyDrawObject = new Draw(MyMap)
{
DrawMode = DrawMode.Point,
IsEnabled = false,
};
MyDrawObject.DrawComplete += MyDrawObject_DrawComplete;
parcelGraphicsLayer = MyMap.Layers["ParcelsGraphicsLayer"] as GraphicsLayer;
}
void Layers_LayersInitialized(object sender, EventArgs args)
{
if (parcelGraphicsLayer != null && parcelGraphicsLayer.Graphics.Count == 0)
{
QueryTask queryTask =
new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsParcelCharacteristics/MapServer/1");
Query query = new Query();
query.Geometry = MyMap.Extent;
query.ReturnGeometry = true;
queryTask.ExecuteCompleted += queryTask_ExecuteCompleted;
queryTask.Failed += queryTask_Failed;
queryTask.ExecuteAsync(query);
}
}
void queryTask_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Query error: " + e.Error);
}
void queryTask_ExecuteCompleted(object sender, QueryEventArgs e)
{
foreach (Graphic g in e.FeatureSet.Features)
{
g.Symbol = LayoutRoot.Resources["BlueFillSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
g.Geometry.SpatialReference = MyMap.SpatialReference;
parcelGraphicsLayer.Graphics.Add(g);
}
MyDrawObject.IsEnabled = true;
}
privatevoid MyDrawObject_DrawComplete(object sender, DrawEventArgs args)
{
ESRI.ArcGIS.Client.Geometry.MapPoint point = args.Geometry as ESRI.ArcGIS.Client.Geometry.MapPoint;
point.SpatialReference = MyMap.SpatialReference;
System.Windows.Point screenPnt = MyMap.MapToScreen(point);
// Account for difference between Map and application origin
GeneralTransform generalTransform = MyMap.TransformToVisual(Application.Current.MainWindow);
System.Windows.Point transformScreenPnt = generalTransform.Transform(screenPnt);
IEnumerable<Graphic> selected =
parcelGraphicsLayer.FindGraphicsInHostCoordinates(transformScreenPnt);
foreach (Graphic g in selected)
if (g.Selected) { g.UnSelect(); selectedGraphics.Remove(g); }
else { g.Select(); selectedGraphics.Add(g); }
if (selectedGraphics.Count > 1)
UnionButton.IsEnabled = true;
else
UnionButton.IsEnabled = false;
}
privatevoid UnionButton_Click(object sender, RoutedEventArgs e)
{
UnionButton.IsEnabled = false;
MyDrawObject.IsEnabled = false;
GeometryService geometryService =
new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
geometryService.UnionCompleted += GeometryService_UnionCompleted;
geometryService.Failed += GeometryService_Failed;
geometryService.UnionAsync(selectedGraphics);
}
void GeometryService_UnionCompleted(object sender, GeometryEventArgs e)
{
foreach (Graphic g in selectedGraphics)
parcelGraphicsLayer.Graphics.Remove(g);
selectedGraphics.Clear();
parcelGraphicsLayer.Graphics.Add(new Graphic() { Geometry = e.Result, Symbol = LayoutRoot.Resources["BlueFillSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol });
MyDrawObject.IsEnabled = true;
}
privatevoid GeometryService_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Geometry Service error: " + e.Error);
}
}
}
Imports System.Collections.Generic
Imports System.Linq
Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Tasks
Namespace ArcGISWPFSDK
PartialPublicClass Union
Inherits UserControl
Private MyDrawObject As Draw
Private parcelGraphicsLayer As GraphicsLayer
Private selectedGraphics AsNew List(Of Graphic)()
PublicSubNew()
InitializeComponent()
AddHandler MyMap.Layers.LayersInitialized, AddressOf Layers_LayersInitialized
MyMap.MinimumResolution = Double.Epsilon
MyDrawObject = New Draw(MyMap) With { _
.DrawMode = DrawMode.Point, _
.IsEnabled = False _
}
AddHandler MyDrawObject.DrawComplete, AddressOf MyDrawObject_DrawComplete
parcelGraphicsLayer = TryCast(MyMap.Layers("ParcelsGraphicsLayer"), GraphicsLayer)
EndSubPrivateSub Layers_LayersInitialized(sender AsObject, args As EventArgs)
If parcelGraphicsLayer IsNotNothingAndAlso parcelGraphicsLayer.Graphics.Count = 0 ThenDim queryTask AsNew QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsParcelCharacteristics/MapServer/1")
Dim query AsNew Query()
query.Geometry = MyMap.Extent
query.ReturnGeometry = TrueAddHandler queryTask.ExecuteCompleted, AddressOf queryTask_ExecuteCompleted
AddHandler queryTask.Failed, AddressOf queryTask_Failed
queryTask.ExecuteAsync(query)
EndIfEndSubPrivateSub queryTask_Failed(sender AsObject, e As TaskFailedEventArgs)
MessageBox.Show("Query error: " & Convert.ToString(e.[Error]))
EndSubPrivateSub queryTask_ExecuteCompleted(sender AsObject, e As QueryEventArgs)
ForEach g As Graphic In e.FeatureSet.Features
g.Symbol = TryCast(LayoutRoot.Resources("BlueFillSymbol"), ESRI.ArcGIS.Client.Symbols.Symbol)
g.Geometry.SpatialReference = MyMap.SpatialReference
parcelGraphicsLayer.Graphics.Add(g)
Next
MyDrawObject.IsEnabled = TrueEndSubPrivateSub MyDrawObject_DrawComplete(sender AsObject, args As DrawEventArgs)
Dim point As ESRI.ArcGIS.Client.Geometry.MapPoint = TryCast(args.Geometry, ESRI.ArcGIS.Client.Geometry.MapPoint)
point.SpatialReference = MyMap.SpatialReference
Dim screenPnt As System.Windows.Point = MyMap.MapToScreen(point)
' Account for difference between Map and application originDim generalTransform As GeneralTransform = MyMap.TransformToVisual(Application.Current.MainWindow)
Dim transformScreenPnt As System.Windows.Point = generalTransform.Transform(screenPnt)
Dim selected As IEnumerable(Of Graphic) = parcelGraphicsLayer.FindGraphicsInHostCoordinates(transformScreenPnt)
ForEach g As Graphic In selected
If g.Selected Then
g.UnSelect()
selectedGraphics.Remove(g)
Else
g.[Select]()
selectedGraphics.Add(g)
EndIfNextIf selectedGraphics.Count > 1 Then
UnionButton.IsEnabled = TrueElse
UnionButton.IsEnabled = FalseEndIfEndSubPrivateSub UnionButton_Click(sender AsObject, e As RoutedEventArgs)
UnionButton.IsEnabled = False
MyDrawObject.IsEnabled = FalseDim geometryService AsNew GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer")
AddHandler geometryService.UnionCompleted, AddressOf GeometryService_UnionCompleted
AddHandler geometryService.Failed, AddressOf GeometryService_Failed
geometryService.UnionAsync(selectedGraphics)
EndSubPrivateSub GeometryService_UnionCompleted(sender AsObject, e As GeometryEventArgs)
ForEach g As Graphic In selectedGraphics
parcelGraphicsLayer.Graphics.Remove(g)
Next
selectedGraphics.Clear()
parcelGraphicsLayer.Graphics.Add(New Graphic() With { _
.Geometry = e.Result, _
.Symbol = TryCast(LayoutRoot.Resources("BlueFillSymbol"), ESRI.ArcGIS.Client.Symbols.Symbol) _
})
MyDrawObject.IsEnabled = TrueEndSubPrivateSub GeometryService_Failed(sender AsObject, e As TaskFailedEventArgs)
MessageBox.Show("Geometry Service error: " & Convert.ToString(e.[Error]))
EndSubEndClassEndNamespace