Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Mensuration

Download Samples Repository

Description

This sample demonstrates the use of the mensuration (measure) operations on an ArcGIS image service. Choose a measure operation and units to be returned in the results.

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

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.Mensuration"
             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>
            <esri:SimpleMarkerSymbol x:Key="PointSymbol" Style="Circle" Size="12" Color="Red" />
            <esri:SimpleLineSymbol x:Key="LineSymbol" Style="Solid" Color="Red" Width="2" />
            <esri:SimpleFillSymbol x:Key="PolygonSymbol" Color="#AAFF0000" Style="Solid">
                <esri:SimpleFillSymbol.Outline>
                    <esri:SimpleLineSymbol Color="Red" Width="1" Style="Solid" />
                </esri:SimpleFillSymbol.Outline>
            </esri:SimpleFillSymbol>
        </Grid.Resources>

        <esri:MapView x:Name="MyMapView">
			<esri:Map InitialViewpoint="-8838052,5409956,-8836538,5410660,3857">
                <esri:ArcGISTiledMapServiceLayer x:Name="imageServiceLayer"  
                    ServiceUri="http://sampleserver6.arcgisonline.com/arcgis/rest/services/Toronto/ImageServer" />
            </esri:Map>

			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="graphicsOverlay" />
			</esri:MapView.GraphicsOverlays>
		</esri:MapView>

		<Border Background="White" BorderBrush="Black" BorderThickness="1"
				HorizontalAlignment="Right" VerticalAlignment="Top"
				Margin="30" Padding="20"
				Width="350">
			<Border.Effect>
				<DropShadowEffect/>
			</Border.Effect>
			<StackPanel>
                <TextBlock TextAlignment="Center" Text="Choose a measure operation and units" 
                           FontWeight="Bold" Height="16" Margin="5" />

                <UniformGrid Columns="3">
                    <Button Tag="Area / Perimeter" Click="AreaPerimeterButton_Click" Margin="2">
                        <TextBlock Text="Area / Perimeter" TextWrapping="Wrap" TextAlignment="Center" />
                    </Button>

                    <Button Tag="Centroid" Content="Centroid" Click="CentroidButton_Click" Margin="2" />

                    <Button Tag="Distance / Azimuth" Click="DistanceAzimuthButton_Click" Margin="2">
                        <TextBlock Text="Distance / Azimuth" TextWrapping="Wrap" TextAlignment="Center" />
                    </Button>

                    <Button Tag="Height Base to Top" Click="HeightBaseToTopButton_Click" Margin="2">
                        <TextBlock Text="Height Base to Top" TextWrapping="Wrap" TextAlignment="Center" />
                    </Button>

                    <Button Tag="Height Base to Top Shadow" Click="HeightBaseToTopShadowButton_Click" Margin="2">
                        <TextBlock Text="Height Base to Top Shadow" TextWrapping="Wrap" TextAlignment="Center" />
                    </Button>

                    <Button Tag="Height Top to Top Shadow" Click="HeightTopToTopShadowButton_Click" Margin="2">
                        <TextBlock Text="Height Top to Top Shadow" TextWrapping="Wrap" TextAlignment="Center"/>
                    </Button>

                    <Button Tag="Point" Content="Point" Click="PointButton_Click" Margin="2" />
                    <Button Tag="Clear" Content="Clear" Click="ClearButton_Click" Margin="2" />
                </UniformGrid>

                <Grid Background="White" Margin="20,20,20,0">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="80" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Row="0" Grid.Column="0" Text="Linear Units" VerticalAlignment="Center" HorizontalAlignment="Right" />
                    <ComboBox x:Name="comboLinearUnit" Grid.Row="0" Grid.Column="1" DisplayMemberPath="Name" Margin="8,4" />

                    <TextBlock Grid.Row="1" Grid.Column="0" Text="Angular Units" VerticalAlignment="Center" HorizontalAlignment="Right" />
                    <ComboBox x:Name="comboAngularUnit" Grid.Row="1" Grid.Column="1" DisplayMemberPath="Name" Margin="8,4" />

                    <TextBlock Grid.Row="2" Grid.Column="0" Text="Area Units" VerticalAlignment="Center" HorizontalAlignment="Right" />
                    <ComboBox x:Name="comboAreaUnit" Grid.Row="2" Grid.Column="1" DisplayMemberPath="Name" Margin="8,4" />
                </Grid>
            </StackPanel>
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.Tasks.Imagery;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ArcGISRuntime.Samples.Desktop
{
    /// <summary>
    /// This sample demonstrates the use of the mensuration (measure) operations on an ArcGIS image service. Choose a measure operation and units to be returned in the results.
    /// </summary>
    /// <title>Mensuration</title>
    /// <category>Tasks</category>
    /// <subcategory>Imagery</subcategory>
    public partial class Mensuration : UserControl
    {
        private Symbol _pointSymbol;
        private Symbol _lineSymbol;
        private Symbol _polygonSymbol;
		private GraphicsOverlay _graphicsOverlay;
        private MensurationTask _mensurationTask;

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

            _pointSymbol = layoutGrid.Resources["PointSymbol"] as Symbol;
            _lineSymbol = layoutGrid.Resources["LineSymbol"] as Symbol;
            _polygonSymbol = layoutGrid.Resources["PolygonSymbol"] as Symbol;

			_graphicsOverlay = MyMapView.GraphicsOverlays["graphicsOverlay"];

            comboLinearUnit.ItemsSource = typeof(LinearUnits).GetProperties().Select(p => p.GetValue(null, null))
                .Except(new LinearUnit[] { LinearUnits.NauticalMiles } ).ToList();
            comboLinearUnit.SelectedItem = LinearUnits.Meters;

            comboAngularUnit.ItemsSource = new AngularUnit[] { AngularUnits.Degrees, AngularUnits.Radians };
            comboAngularUnit.SelectedItem = AngularUnits.Degrees;

            comboAreaUnit.ItemsSource = typeof(AreaUnits).GetProperties().Select(p => p.GetValue(null, null)).ToList();
            comboAreaUnit.SelectedItem = AreaUnits.SquareMeters;

            _mensurationTask = new MensurationTask(new Uri(imageServiceLayer.ServiceUri));
        }

        private async void AreaPerimeterButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var polygon = await RequestUserShape(DrawShape.Polygon, _polygonSymbol) as Polygon;

				// Requesting shape cancelled
				if (polygon == null)
					return;

                var parameters = new MensurationAreaParameters()
                {
                    LinearUnit = comboLinearUnit.SelectedItem as LinearUnit,
                    AreaUnit = comboAreaUnit.SelectedItem as AreaUnit,
                };

                var result = await _mensurationTask.AreaAndPerimeterAsync(polygon, parameters);
                ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private async void CentroidButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var polygon = await RequestUserShape(DrawShape.Polygon, _polygonSymbol) as Polygon;
				
				// Requesting shape cancelled
				if (polygon == null)
					return;

                var result = await _mensurationTask.CentroidAsync(polygon, new MensurationPointParameters());
                ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private async void DistanceAzimuthButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var line = await RequestUserShape(DrawShape.LineSegment, _lineSymbol) as Polyline;

				// Requesting shape cancelled
				if (line == null)
					return;

                var parameters = new MensurationLengthParameters()
                {
                    AngularUnit = comboAngularUnit.SelectedItem as AngularUnit,
                    LinearUnit = comboLinearUnit.SelectedItem as LinearUnit
                };

				var result = await _mensurationTask.DistanceAndAngleAsync(
					line.Parts.First().StartPoint,
					line.Parts.First().EndPoint, parameters);
                ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private async void HeightBaseToTopButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var line = await RequestUserShape(DrawShape.LineSegment, _lineSymbol) as Polyline;

				// Requesting shape cancelled
				if (line == null)
					return;

                var parameters = new MensurationHeightParameters()
                {
                    LinearUnit = comboLinearUnit.SelectedItem as LinearUnit
                };

				var result = await _mensurationTask.HeightFromBaseAndTopAsync(
					line.Parts.First().StartPoint, 
					line.Parts.First().EndPoint, parameters);


				ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private async void HeightBaseToTopShadowButton_Click(object sender, RoutedEventArgs e)
        {
			try
			{
				var line = await RequestUserShape(DrawShape.LineSegment, _lineSymbol) as Polyline;
				
				// Requesting shape cancelled
				if (line == null)
					return;

				var parameters = new MensurationHeightParameters()
				{
					LinearUnit = comboLinearUnit.SelectedItem as LinearUnit
				};

				var result = await _mensurationTask.HeightFromBaseAndTopShadowAsync(
					line.Parts.First().StartPoint,
					line.Parts.First().EndPoint, parameters);

				ShowResults(result, ((Button)sender).Tag.ToString());
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Mensuration Error");
			}
        }

        private async void HeightTopToTopShadowButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var line = await RequestUserShape(DrawShape.LineSegment, _lineSymbol) as Polyline;

				// Requesting shape cancelled
				if (line == null)
					return;

                var parameters = new MensurationHeightParameters()
                {
                    LinearUnit = comboLinearUnit.SelectedItem as LinearUnit
                };

				var result = await _mensurationTask.HeightFromTopAndTopShadowAsync(
					line.Parts.First().StartPoint, 
					line.Parts.First().EndPoint, parameters);

                ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private async void PointButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				var point = await RequestUserShape(DrawShape.Point, _pointSymbol) as MapPoint;

				// Requesting shape cancelled
				if (point == null)
					return;

                var result = await _mensurationTask.PointAsync(point, new MensurationPointParameters());
                ShowResults(result, ((Button)sender).Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Mensuration Error");
            }
        }

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
			_graphicsOverlay.Graphics.Clear();
        }

        // Retrieve the given shape type from the user
        private async Task<Geometry> RequestUserShape(DrawShape drawShape, Symbol symbol)
        {
            try
            {
				_graphicsOverlay.Graphics.Clear();

                var shape = await MyMapView.Editor.RequestShapeAsync(drawShape, symbol);

				_graphicsOverlay.Graphics.Add(new Graphic(shape, symbol));
                return shape;
            }
			catch (TaskCanceledException) 
			{
				return null;
			}
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Shape Drawing Error");
                return null;
            }
        }

        // Show results from mensuration task in string format
        private void ShowResults(object result, string caption = "")
        {
            StringBuilder sb = new StringBuilder();

            if (result is MensurationPointResult)
            {
                MensurationPointResult pointResult = (MensurationPointResult)result;

                if (pointResult.Point != null)
                {
                    sb.Append(pointResult.Point);
                    sb.Append("\n");
                }
            }
            else if (result is MensurationHeightResult)
            {
                var heightResult = (MensurationHeightResult)result;

                if (heightResult.Height != null)
                {
                    sb.Append("Height\n");
                    sb.AppendFormat("Value:\t\t{0}\n", heightResult.Height.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", heightResult.Height.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", heightResult.Height.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", heightResult.Height.LinearUnit);
                    sb.Append("\n");
                }
            }
            else if (result is MensurationLengthResult)
            {
                var lengthResult = (MensurationLengthResult)result;

                if (lengthResult.Distance != null)
                {
                    sb.Append("Distance\n");
                    sb.AppendFormat("Value:\t\t{0}\n", lengthResult.Distance.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", lengthResult.Distance.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", lengthResult.Distance.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", lengthResult.Distance.LinearUnit);
                    sb.Append("\n");
                }
                if (lengthResult.AzimuthAngle != null)
                {
                    sb.Append("Azimuth Angle\n");
                    sb.AppendFormat("Value:\t\t{0}\n", lengthResult.AzimuthAngle.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", lengthResult.AzimuthAngle.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", lengthResult.AzimuthAngle.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", lengthResult.AzimuthAngle.AngularUnit);
                    sb.Append("\n");
                }
                if (lengthResult.ElevationAngle != null)
                {
                    sb.Append("Elevation Angle\n");
                    sb.AppendFormat("Value:\t\t{0}\n", lengthResult.ElevationAngle.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", lengthResult.ElevationAngle.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", lengthResult.ElevationAngle.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", lengthResult.ElevationAngle.AngularUnit);
                    sb.Append("\n");
                }
            }
            else if (result is MensurationAreaResult)
            {
                var areaResult = (MensurationAreaResult)result;

                if (areaResult.Area != null)
                {
                    sb.Append("Area\n");
                    sb.AppendFormat("Value:\t\t{0}\n", areaResult.Area.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", areaResult.Area.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", areaResult.Area.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", areaResult.Area.AreaUnit);
                    sb.Append("\n");
                }

                if (areaResult.Perimeter != null)
                {
                    sb.Append("Perimeter\n");
                    sb.AppendFormat("Value:\t\t{0}\n", areaResult.Perimeter.Value);
                    sb.AppendFormat("Display Value:\t{0}\n", areaResult.Perimeter.DisplayValue);
                    sb.AppendFormat("Uncertainty:\t{0}\n", areaResult.Perimeter.Uncertainty);
                    sb.AppendFormat("Unit:\t\t{0}\n", areaResult.Perimeter.LinearUnit);
                    sb.Append("\n");
                }
            }

            MessageBox.Show(sb.ToString(), caption);
        }
    }
}
Feedback on this topic?