This sample demonstrates using an ESRI.ArcGIS.Client.Tasks GeometryService that takes an input polyline graphic that cuts across a polygon graphic to generate a new polygon graphics that is reshaped to be smaller by the cutting polyline. To make this sample work requires a two step interaction of first selection and existing polygon via a mouse click and then drawing a polyline across the selected polygon. The Draw_Complete event in the code-behind uses If/Else logic to determine if the user is in the first step or the second step via the an ESRI.ArcGIS.Client Draw object to determine what drawing mode (Point, Polyline, Polygon, etc.) is being used.
To use the sample, (step 1) click to select a parcel polygon and (step 2) digitize a line that intersects the selected polygon. The start and/or end point of the line can be inside the polygon.
<UserControlx:Class="ArcGISWPFSDK.Reshape"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"xmlns:sys="clr-namespace:System;assembly=mscorlib"><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="Normal"/><VisualStatex:Name="Selected"><Storyboard><ColorAnimationUsingKeyFramesBeginTime="0"Duration="0"Storyboard.TargetName="Element"Storyboard.TargetProperty="(Fill).(Color)"><SplineColorKeyFrameKeyTime="0"Value="#6600FFFF"/></ColorAnimationUsingKeyFrames></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><sys:Stringx:Key="StartText">Click to select a parcel polygon.</sys:String><sys:Stringx:Key="EndText">Digitize a line that intersects the selected polygon. The start and/or end point of the line can be inside the polygon.</sys:String><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"/><TextBlockx:Name="InfoTextBlock"Text="{StaticResource StartText}"Width="200"TextAlignment="Left"Margin="30,20,20,30"TextWrapping="Wrap"Foreground="Black"/></Grid></Grid></UserControl>
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Tasks;
using System.Collections.Generic;
using System.Windows.Media;
namespace ArcGISWPFSDK
{
publicpartialclass Reshape : UserControl
{
private Draw MyDrawObject;
private GraphicsLayer parcelGraphicsLayer;
private Graphic selectedGraphic;
public Reshape()
{
InitializeComponent();
MyMap.Layers.LayersInitialized += Layers_LayersInitialized;
MyMap.MinimumResolution = double.Epsilon;
MyDrawObject = new Draw(MyMap)
{
DrawMode = DrawMode.Point,
LineSymbol = LayoutRoot.Resources["RedLineSymbol"] as ESRI.ArcGIS.Client.Symbols.LineSymbol,
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)
{
MyDrawObject.IsEnabled = false;
if (MyDrawObject.DrawMode == DrawMode.Point)
{
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);
if (selected.ToArray().Length <= 0)
{
MyDrawObject.IsEnabled = true;
return;
}
selectedGraphic = selected.ToList()[0] as Graphic;
selectedGraphic.Select();
MyDrawObject.DrawMode = DrawMode.Polyline;
MyDrawObject.IsEnabled = true;
InfoTextBlock.Text = LayoutRoot.Resources["EndText"] asstring;
}
else
{
ESRI.ArcGIS.Client.Geometry.Polyline polyline = args.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline;
polyline.SpatialReference = MyMap.SpatialReference;
GeometryService geometryService =
new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
geometryService.ReshapeCompleted += GeometryService_ReshapeCompleted;
geometryService.Failed += GeometryService_Failed;
// Should use one of the other geometry operations, such as RelationAsync, prior to calling ReshapeAsync to ensure that the user defined polyline actually // does intersect the selected polygon. For simplicity here we assume that it always does.
geometryService.ReshapeAsync(selectedGraphic.Geometry, polyline);
}
}
void GeometryService_ReshapeCompleted(object sender, GeometryEventArgs e)
{
parcelGraphicsLayer.Graphics.Remove(selectedGraphic);
Graphic graphic = new Graphic()
{
Symbol = LayoutRoot.Resources["BlueFillSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol,
Geometry = e.Result
};
parcelGraphicsLayer.Graphics.Add(graphic);
MyDrawObject.DrawMode = DrawMode.Point;
MyDrawObject.IsEnabled = true;
InfoTextBlock.Text = LayoutRoot.Resources["StartText"] asstring;
}
privatevoid GeometryService_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Geometry Service error: " + e.Error);
}
}
}
Imports System.Linq
Imports System.Windows
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Tasks
Imports System.Collections.Generic
Imports System.Windows.Media
Namespace ArcGISWPFSDK
PartialPublicClass Reshape
Inherits UserControl
Private MyDrawObject As Draw
Private parcelGraphicsLayer As GraphicsLayer
Private selectedGraphic As Graphic
PublicSubNew()
InitializeComponent()
AddHandler MyMap.Layers.LayersInitialized, AddressOf Layers_LayersInitialized
MyMap.MinimumResolution = Double.Epsilon
MyDrawObject = New Draw(MyMap) With { _
.DrawMode = DrawMode.Point, _
.LineSymbol = TryCast(LayoutRoot.Resources("RedLineSymbol"), ESRI.ArcGIS.Client.Symbols.LineSymbol), _
.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)
MyDrawObject.IsEnabled = FalseIf MyDrawObject.DrawMode = DrawMode.Point ThenDim 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)
If selected.ToArray().Length <= 0 Then
MyDrawObject.IsEnabled = TrueReturnEndIf
selectedGraphic = TryCast(selected.ToList()(0), Graphic)
selectedGraphic.[Select]()
MyDrawObject.DrawMode = DrawMode.Polyline
MyDrawObject.IsEnabled = True
InfoTextBlock.Text = TryCast(LayoutRoot.Resources("EndText"), String)
ElseDim polyline As ESRI.ArcGIS.Client.Geometry.Polyline = TryCast(args.Geometry, ESRI.ArcGIS.Client.Geometry.Polyline)
polyline.SpatialReference = MyMap.SpatialReference
Dim geometryService AsNew GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer")
AddHandler geometryService.ReshapeCompleted, AddressOf GeometryService_ReshapeCompleted
AddHandler geometryService.Failed, AddressOf GeometryService_Failed
' Should use one of the other geometry operations, such as RelationAsync, prior to calling ReshapeAsync to ensure that the user defined polyline actually ' does intersect the selected polygon. For simplicity here we assume that it always does.
geometryService.ReshapeAsync(selectedGraphic.Geometry, polyline)
EndIfEndSubPrivateSub GeometryService_ReshapeCompleted(sender AsObject, e As GeometryEventArgs)
parcelGraphicsLayer.Graphics.Remove(selectedGraphic)
Dim graphic AsNew Graphic() With { _
.Symbol = TryCast(LayoutRoot.Resources("BlueFillSymbol"), ESRI.ArcGIS.Client.Symbols.Symbol), _
.Geometry = e.Result _
}
parcelGraphicsLayer.Graphics.Add(graphic)
MyDrawObject.DrawMode = DrawMode.Point
MyDrawObject.IsEnabled = True
InfoTextBlock.Text = TryCast(LayoutRoot.Resources("StartText"), String)
EndSubPrivateSub GeometryService_Failed(sender AsObject, e As TaskFailedEventArgs)
MessageBox.Show("Geometry Service error: " & Convert.ToString(e.[Error]))
EndSubEndClassEndNamespace