Offset

Download Samples Repository

Description

Demonstrates how to create an offset geometry using the Offset method of the GeometryEngine class.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.Offset"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
    <Grid x:Name="LayoutRoot">
        <Grid.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="14"/>
            </Style>
        </Grid.Resources>

        <esri:MapView x:Name="MyMapView" LayerLoaded="MyMapView_LayerLoaded">
			<esri:Map InitialViewpoint="-9275076, 5253226, -9274274, 5253886, 102100">
				<esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="ParcelsGraphicsOverlay" Opacity="0.3" >
					<esri:GraphicsOverlay.Renderer>
						<esri:SimpleRenderer>
							<esri:SimpleFillSymbol Color="#990000FF">
								<esri:SimpleFillSymbol.Outline>
									<esri:SimpleLineSymbol Color="Blue" Width="1"/>
								</esri:SimpleFillSymbol.Outline>
							</esri:SimpleFillSymbol>
						</esri:SimpleRenderer>
					</esri:GraphicsOverlay.Renderer>
				</esri:GraphicsOverlay>
				<esri:GraphicsOverlay  ID="OffsetGraphicsOverlay" Opacity="0.4"  >
					<esri:GraphicsOverlay.Renderer>
						<esri:SimpleRenderer>
							<esri:SimpleFillSymbol  Color="Bisque"    >
								<esri:SimpleFillSymbol.Outline>
									<esri:SimpleLineSymbol Color="Green" Width="2"/>
								</esri:SimpleFillSymbol.Outline>
							</esri:SimpleFillSymbol>
						</esri:SimpleRenderer>
					</esri:GraphicsOverlay.Renderer>
				</esri:GraphicsOverlay>
			</esri:MapView.GraphicsOverlays>
        </esri:MapView>

        <Border Background="White" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="30" Padding="20">
            <StackPanel Orientation="Vertical">
                <TextBlock x:Name="InstructionsTextBlock" FontSize="14" Width="275" TextWrapping="Wrap" Visibility="Visible" 
                           Text="First, click on a parcel to generate an offset using the selected parmeters. Update the parameters using the controls to see the changes immediately. Click Reset to clear the graphic." />

                <StackPanel Margin="0,20" x:Name="ControlsContainer">
                    <TextBlock Margin="6,0">
                        <Run Text="Offset Distance : "/>
                        <Run Text="{Binding Value, ElementName=OffsetDistanceSlider, Mode=TwoWay}" />
                    </TextBlock>
                    <Slider x:Name="OffsetDistanceSlider" Minimum="-50" Maximum="50" Value="-20"
                            IsSnapToTickEnabled="True" TickFrequency="5" TickPlacement="BottomRight" />

                    <TextBlock Text="Offset Type : " Margin="0,12,0,0"/>
                    <ComboBox x:Name="OffsetTypeComboBox" />

                    <TextBlock Margin="0,12,0,0">
                        <Run Text="Bevel Ratio : "/>
                        <Run Text="{Binding Value, ElementName=OffsetBevelRatioSlider, Mode=TwoWay}" />
                    </TextBlock>
                    <Slider x:Name="OffsetBevelRatioSlider" Minimum="0" Maximum="5" Value="1.1" 
                            IsSnapToTickEnabled="True" TickPlacement="BottomRight" TickFrequency="0.1" />

                    <TextBlock Margin="0,12,0,0">
                        <Run Text="Flatten Error : "/>
                        <Run Text="{Binding Value, ElementName=OffsetFlattenErrorSlider, Mode=TwoWay}" />
                    </TextBlock>
                    <Slider x:Name="OffsetFlattenErrorSlider" Minimum="0" Maximum="1000" Value="50" 
                            IsSnapToTickEnabled="True" TickPlacement="BottomRight" TickFrequency="25" />
                    
                    <Button x:Name="ResetButton" Content="Reset" Click="ResetButton_Click" Margin="20" IsEnabled="False"/>
                </StackPanel>

                <StackPanel x:Name="LoadingParcelsContainer" Visibility="Collapsed">
                    <TextBlock Text="Loading parcels..." HorizontalAlignment="Center" Margin="0,0,0,4"/>
                    <ProgressBar x:Name="LoadingParcelsIndicator" Height="6" IsIndeterminate="True"/>
                </StackPanel>
            </StackPanel>
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Tasks.Query;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ArcGISRuntime.Samples.Desktop
{
	/// <summary>
	/// Demonstrates how to create an offset geometry using the Offset method of the GeometryEngine class.
	/// </summary>
	/// <title>Offset</title>
	/// <category>Geometry</category>
	public partial class Offset : UserControl
	{
		private GraphicsOverlay _parcelOverlay;
		private GraphicsOverlay _offsetOverlay;
		private Graphic _selectedParcelGraphic;

		public Offset()
		{
			InitializeComponent();

			_parcelOverlay = MyMapView.GraphicsOverlays["ParcelsGraphicsOverlay"];
			_offsetOverlay = MyMapView.GraphicsOverlays["OffsetGraphicsOverlay"];

			InitializeOffsetTypes();
			OffsetDistanceSlider.ValueChanged += Slider_ValueChanged;
			OffsetTypeComboBox.SelectionChanged += ComboBox_SelectionChanged;
			OffsetFlattenErrorSlider.ValueChanged += Slider_ValueChanged;
			OffsetBevelRatioSlider.ValueChanged += Slider_ValueChanged;

			ControlsContainer.Visibility = Visibility.Collapsed;
		}

		void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			DoOffset();
		}

		void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			DoOffset();
		}

		private void InitializeOffsetTypes()
		{
			OffsetTypeComboBox.ItemsSource = new List<OffsetType> { OffsetType.Bevel, OffsetType.Miter, OffsetType.Round, OffsetType.Square };
			OffsetTypeComboBox.SelectedIndex = 0;
		}

		private async Task SelectParcelForOffsetAsync()
		{
			try
			{
				ResetButton.IsEnabled = false;
				_offsetOverlay.Graphics.Clear();

				var pointGeom = await MyMapView.Editor.RequestPointAsync();
				var screenPnt = MyMapView.LocationToScreen(pointGeom);

				_selectedParcelGraphic = await
					_parcelOverlay.HitTestAsync(MyMapView, screenPnt);

				DoOffset();
			}
			catch (TaskCanceledException) { }
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Sample Error");
			}
			finally
			{
				ResetButton.IsEnabled = true;
			}
		}

		private void DoOffset()
		{
			if (_selectedParcelGraphic != null)
			{
				_offsetOverlay.Graphics.Clear();

				try
				{
					var offsetGeom = GeometryEngine.Offset(_selectedParcelGraphic.Geometry,
						OffsetDistanceSlider.Value, (OffsetType)OffsetTypeComboBox.SelectedItem,
						OffsetBevelRatioSlider.Value, OffsetFlattenErrorSlider.Value);
					if (offsetGeom != null)
					{
						_offsetOverlay.Graphics.Add(new Graphic { Geometry = offsetGeom });
					}
				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message, "Sample Error");
				}
			}
		}

		private async void ResetButton_Click(object sender, RoutedEventArgs e)
		{
			await SelectParcelForOffsetAsync();
		}

		private async void MyMapView_LayerLoaded(object sender, LayerLoadedEventArgs e)
		{

			if (_parcelOverlay != null && _parcelOverlay.Graphics.Count == 0)
			{
				try
				{
					ControlsContainer.Visibility = Visibility.Collapsed;
					LoadingParcelsContainer.Visibility = Visibility.Visible;

					QueryTask queryTask = new QueryTask(
						new Uri("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsParcelCharacteristics/MapServer/1"));

					// Get current viewpoints extent from the MapView
					var currentViewpoint = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry);
					var viewpointExtent = currentViewpoint.TargetGeometry.Extent;

					//Create a geometry to use as the extent within which parcels will be returned
					var contractRatio = viewpointExtent.Width / 6;

					var extentGeometry = new Envelope(
						-83.3188395774275,
						42.61428312652851,
						-83.31295664068958,
						42.61670913269855,
						SpatialReferences.Wgs84);

					Query query = new Query(extentGeometry);
					query.ReturnGeometry = true;
					query.OutSpatialReference = SpatialReferences.WebMercator;

					var results = await queryTask.ExecuteAsync(query, CancellationToken.None);
					foreach (Graphic g in results.FeatureSet.Features)
					{
						_parcelOverlay.Graphics.Add(g);
					}

					ControlsContainer.Visibility = Visibility.Visible;
				}
				catch (Exception ex)
				{
					MessageBox.Show("Error loading parcel data: " + ex.Message, "Sample Error");
				}
				finally
				{
					LoadingParcelsContainer.Visibility = Visibility.Collapsed;
				}
			}
			await SelectParcelForOffsetAsync();
		}
	}
}
Feedback on this topic?