Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Geodesic Densify

Download Samples Repository

Description

This sample demonstrates using GeometryEngine.GeodesicDensify to take an input shape and return a geodesic densified shape. Original vertices to create the original polygon or polyline are shown in red. The returned polygon shows the additional densified vertices in green. To use the sample, click the 'Densify' button and create a shape on the map. Double-click to end the polygon sketch and densify the shape and see the original and densified vertices.

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

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.GeodesicDensify"
             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/runtime/2013">
    <Grid x:Name="layoutGrid">
        <Grid.Resources>
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

            <esri:SimpleMarkerSymbol x:Key="OrigVertexSymbol" Color="Red" Size="12" />
            <esri:SimpleMarkerSymbol x:Key="NewVertexSymbol" Color="LightGreen" Size="8" />
            <esri:SimpleLineSymbol x:Key="LineSymbol" Color="Blue" Width="2" Style="Solid" />
            <esri:SimpleFillSymbol x:Key="FillSymbol" Color="#88000000" Style="Solid">
                <esri:SimpleFillSymbol.Outline>
                    <esri:SimpleLineSymbol Color="Black" Width="1" />
                </esri:SimpleFillSymbol.Outline>
            </esri:SimpleFillSymbol>
        </Grid.Resources>

        <esri:MapView x:Name="MyMapView" WrapAround="True">
			<esri:Map InitialViewpoint="-15000000,2000000,-7000000,8000000">
				<esri:ArcGISTiledMapServiceLayer
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="inputOverlay" />
				<esri:GraphicsOverlay ID="resultsOverlay" />
			</esri:MapView.GraphicsOverlays>
		</esri:MapView>

		<Border Background="White" BorderBrush="Black" BorderThickness="1"
				 HorizontalAlignment="Right" VerticalAlignment="Top"
				 Margin="30" Padding="20">
			<Border.Effect>
				<DropShadowEffect/>
			</Border.Effect>
			<StackPanel>
				<TextBlock Text="Click the 'Geodesic Densify' button to digitize and densify a polygon or polyline. Red points indicate digitized vertices. Green points show all vertices (original and new) in the densified shape."
                           Width="300" TextAlignment="Left" TextWrapping="Wrap" />

                <StackPanel Orientation="Horizontal" Margin="12" HorizontalAlignment="Center">
                    <TextBlock Text="Shape Type:" Margin="4,0" VerticalAlignment="Center" />
                    <ComboBox x:Name="comboShapeType" SelectedIndex="0" Width="75">
                        <esri:DrawShape>Polyline</esri:DrawShape>
                        <esri:DrawShape>Polygon</esri:DrawShape>
                    </ComboBox>
                </StackPanel>

                <Button Content="Geodesic Densify" Margin="8,8,8,0" HorizontalAlignment="Center"
                        Click="DensifyButton_Click" />

                <Border x:Name="resultsPanel" Margin="12,24,12,0" HorizontalAlignment="Center" Visibility="Collapsed"
                        BorderBrush="Gray" BorderThickness="2">
                    <StackPanel Margin="12,6,12,12">
                        <TextBlock Text="Geodesic Densify Statistics" Margin="0,0,0,8" HorizontalAlignment="Center" />
                        <ListView x:Name="resultsListView">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="100"/>
                                            <ColumnDefinition />
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Grid.Column="0" Text="{Binding Key}" Margin="6,0"/>
                                        <TextBlock Grid.Column="1" Text="{Binding Value, StringFormat={}{0:0.000}}" FontWeight="Bold" />
                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </StackPanel>
                </Border>
            </StackPanel>
        </Border>

        <Border Background="White" BorderBrush="Black" BorderThickness="2" Margin="25"
                HorizontalAlignment="Center" VerticalAlignment="Bottom"
                Visibility="{Binding ElementName=MyMapView, Path=Editor.IsActive, Converter={StaticResource BooleanToVisibilityConverter}}">
            <TextBlock Text="Draw a shape on the map." Margin="8" FontSize="14" />
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ArcGISRuntime.Samples.Desktop
{
	/// <summary>
	/// This sample demonstrates using GeometryEngine.GeodesicDensify to take an input shape and return a geodesic densified shape. Original vertices to create the original polygon or polyline are shown in red. The returned polygon shows the additional densified vertices in green. To use the sample, click the 'Densify' button and create a shape on the map. Double-click to end the polygon sketch and densify the shape and see the original and densified vertices.
	/// </summary>
	/// <title>Geodesic Densify</title>
	/// <category>Geometry</category>
	public partial class GeodesicDensify : UserControl
	{
		private const double METERS_TO_MILES = 0.000621371192;
		private const double SQUARE_METERS_TO_MILES = 3.86102159e-7;

		private Symbol _lineSymbol;
		private Symbol _fillSymbol;
		private Symbol _origVertexSymbol;
		private Symbol _newVertexSymbol;

		private GraphicsOverlay _inputOverlay;
		private GraphicsOverlay _resultsOverlay;

		/// <summary>Construct Densify sample control</summary>
		public GeodesicDensify()
		{
			InitializeComponent();

			_lineSymbol = layoutGrid.Resources["LineSymbol"] as Symbol;
			_fillSymbol = layoutGrid.Resources["FillSymbol"] as Symbol;
			_origVertexSymbol = layoutGrid.Resources["OrigVertexSymbol"] as Symbol;
			_newVertexSymbol = layoutGrid.Resources["NewVertexSymbol"] as Symbol;

			_inputOverlay = MyMapView.GraphicsOverlays["inputOverlay"];
			_resultsOverlay = MyMapView.GraphicsOverlays["resultsOverlay"];
		}

		// Draw and densify a user defined polygon
		private async void DensifyButton_Click(object sender, RoutedEventArgs e)
		{
			try
			{
				resultsPanel.Visibility = Visibility.Collapsed;
				_inputOverlay.Graphics.Clear();
				_resultsOverlay.Graphics.Clear();

				// Request polygon or polyline from the user
				DrawShape drawShape = (DrawShape)comboShapeType.SelectedValue;

				// Use polyline as default
				Symbol symbolToUse = _lineSymbol;
				if (drawShape == DrawShape.Polygon)
					symbolToUse = _fillSymbol;

				var original = await MyMapView.Editor.RequestShapeAsync(drawShape, symbolToUse);

				// Account for WrapAround
				var normalized = GeometryEngine.NormalizeCentralMeridian(original);

				// Add original shape vertices to input graphics layer
				var coordsOriginal = (normalized as Multipart).Parts.First().GetPoints();
				foreach (var mapPoint in coordsOriginal)
					_inputOverlay.Graphics.Add(new Graphic(mapPoint, _origVertexSymbol));

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

				// Densify the shape
				var densify = GeometryEngine.GeodesicDensify(normalized, viewpointExtent.Width / 100, LinearUnits.Meters);

				if (densify.GeometryType == GeometryType.Polygon)
					_inputOverlay.Graphics.Add(new Graphic(densify, _fillSymbol));
				else
					_inputOverlay.Graphics.Add(new Graphic(densify, _lineSymbol));

				// Add new vertices to result graphics layer
				var coordsDensify = (densify as Multipart).Parts.First().GetPoints();
				foreach (var mapPoint in coordsDensify)
					_resultsOverlay.Graphics.Add(new Graphic(mapPoint, _newVertexSymbol));

				// Results
				Dictionary<string, object> results = new Dictionary<string, object>();
				results["Length"] = GeometryEngine.GeodesicLength(densify) * METERS_TO_MILES;
				if (normalized is Polygon)
					results["Area"] = GeometryEngine.GeodesicArea(densify) * SQUARE_METERS_TO_MILES;
				else
					results["Area"] = "N/A";
				results["Vertices Before"] = coordsOriginal.Count();
				results["Vertices After"] = coordsDensify.Count();

				resultsListView.ItemsSource = results;
				resultsPanel.Visibility = Visibility.Visible;
			}
			catch (TaskCanceledException) { }
			catch (Exception ex)
			{
				MessageBox.Show("Densify Error: " + ex.Message, "Geodesic Densify Sample");
			}
		}
	}
}
Feedback on this topic?