Click or drag to resize
Code Example - FeatureLayer_Labeling

Demonstrates labeling highway names in a FeatureLayer.

Code Example
Feature Layer Labeling

This section contains selected code files from a Visual Studio project that emphasize specific ArcGIS Runtime SDK (Windows Desktop) features. For example: some code examples may accomplish the bulk of the work as a configuration property in the .xaml file and hence only the .xaml file will be shown in detail below. In other code examples, the .xaml is used to define the configuration of graphical elements for the application but the application logic is performed in the code behind, hence you may see both the .xaml and .cs/.vb files shown in detail below.

XAML
<Window x:Class="FeatureLayer_Labeling.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="600" Width="800" 
    xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">

    <Grid>

        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Vertical">

                <!-- TextBlock to provide the instructions on how to use the sample code. It will be 
                populated with instructions in the code-behind when the application loads. -->
                <TextBlock Height="58" HorizontalAlignment="Left" Name="TextBlock1" VerticalAlignment="Top" 
                           Width="770" TextWrapping="Wrap"  Margin="10,2,0,0" />

            </StackPanel>
            <StackPanel Orientation="Vertical">

                <!-- Button to perform labeling of highways from a FreatureLayer via code-behind. -->
                <Button Content="Label Highways" x:Name="Button1" Click="Button1_Click" Width="780" HorizontalAlignment="Left"/>

            </StackPanel>

            <StackPanel Orientation="Horizontal">

                <!-- A MapView Control to display various GIS layers. -->
                <esri:MapView x:Name="MapView1" Width="780" Height="480" VerticalAlignment="Top" Margin="2,2,2,2">
                    <!-- Add a Map. -->
                    <esri:Map x:Name="Map1">

                        <!-- Add a backdrop ArcGISTiledMapServiceLayer. -->
                        <esri:ArcGISTiledMapServiceLayer ID="BaseLayer" ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer"/>

                    </esri:Map>

                </esri:MapView>

            </StackPanel>
        </StackPanel>
    </Grid>

</Window>

SPECIAL NOTE: The XAML displayed above comes from a C# project. If you are a VB.NET developer, you will need to modify the text for the x:Class namespace from "FeatureLayer_Labeling.MainWindow" to be just "MainWindow".

namespace FeatureLayer_Labeling
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            // This call is required by the designer.
            InitializeComponent();

            // Add any initialization after the InitializeComponent() call.


            // Add the instructions on how to use this example code to the TextBlock.
            TextBlock1.Text = "When the application loads, click the 'Label Highways' button to label highways in the USA. Zoom in/out and pan around " + 
                "to see how the labeling engine adjusts the labels on the FeatureLayer.";

            // Create a SpatialReference that matches that of the MapView.
            Esri.ArcGISRuntime.Geometry.SpatialReference mySpatialReference = new Esri.ArcGISRuntime.Geometry.SpatialReference(102100);

            // Create a new Envelope based up the SpatialReference.   
            Esri.ArcGISRuntime.Geometry.Envelope myEnvelope = new Esri.ArcGISRuntime.Geometry.Envelope(-9872085.6, 3817789.3, -8688879.9, 4545915.8, mySpatialReference);

            // Set the initial map's startup extent  zoomed into the east-central US.
            MapView1.Map.InitialViewpoint = new Esri.ArcGISRuntime.Controls.Viewpoint(myEnvelope);
        }

        private void Button1_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function will add a Highways FeatureLayer to the Map via code behind and label the roads.

            // Creating and adding the FeatureLayer to the Map.
            // ------------------------------------------------

            // Create a new Uri that point to an FeatureLayer.
            System.Uri myUri = new System.Uri("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/1");

            // Create a new ServiceFeatureTable and set it's ServiceUri and Where clause Properties.
            Esri.ArcGISRuntime.Data.ServiceFeatureTable myServiceFeatureTable = new Esri.ArcGISRuntime.Data.ServiceFeatureTable();
            myServiceFeatureTable.ServiceUri = myUri.ToString();

            // Returns all the fields in the FeatureLayer.
            // NOTE: If the Attribute Field that needs to be labeled via the AttributeLabelClass.TextExpression is not returned, then no labeling will occur.
            myServiceFeatureTable.OutFields = Esri.ArcGISRuntime.Tasks.Query.OutFields.All;

            // Create a new instance of an FeatureLayer and set it's Id and FeatureTable Properties.
            Esri.ArcGISRuntime.Layers.FeatureLayer myFeatureLayer = new Esri.ArcGISRuntime.Layers.FeatureLayer();
            myFeatureLayer.ID = "Highways";
            myFeatureLayer.FeatureTable = myServiceFeatureTable;

            // Define an SimpleLineSymbol for the highways.
            Esri.ArcGISRuntime.Symbology.SimpleLineSymbol mySimpleLineSymbol = new Esri.ArcGISRuntime.Symbology.SimpleLineSymbol();
            mySimpleLineSymbol.Color = System.Windows.Media.Colors.Black;
            mySimpleLineSymbol.Style = Esri.ArcGISRuntime.Symbology.SimpleLineStyle.Solid;
            mySimpleLineSymbol.Width = 1;

            // Create a SimpleRenderer to hold the SimpleLineSymbol.
            Esri.ArcGISRuntime.Symbology.SimpleRenderer mySimpleRenderer = new Esri.ArcGISRuntime.Symbology.SimpleRenderer();
            mySimpleRenderer.Symbol = mySimpleLineSymbol;

            // Apply the SimpleRenderer to the FeatureLayer.
            myFeatureLayer.Renderer = mySimpleRenderer;

            // Add the FeatureLayer to the Map.
            MapView1.Map.Layers.Add(myFeatureLayer);


            // Creating and adding the Labeling option to the FeatureLayer.
            // ------------------------------------------------------------

            // Create an AttributeLabelClass. This contains the meat of the instructions for doing labeling. 
            Esri.ArcGISRuntime.Layers.AttributeLabelClass myAttributeLabelClass = new Esri.ArcGISRuntime.Layers.AttributeLabelClass();

            // This option is quite useful for labeling PolyLine networks (i.e. roads, railroads, etc.). We will remove duplicate highway names to avoid clutters labels.
            // By default this value is set to .PreserveDuplicates.
            myAttributeLabelClass.DuplicateLabels = Esri.ArcGISRuntime.Layers.DuplicateLabels.RemoveWithinLabelClass;

            // Allow the labeling to show in the map; so set this Property to True. 
            // By default this value is set to True.
            myAttributeLabelClass.IsVisible = true;

            // Not interested in wrapping the text of the highway name on a second line. 
            // NOTE: If this option were set to True, use the other .WordWrapLength Property to determine when to wrap the text on the 2nd line.
            // By default this value is set to False.
            myAttributeLabelClass.IsWordWrapEnabled = false;

            // Define the placement of the Attribute text relative to the SimpleLineSymbol defined earlier for the Highways FeatureLayer.
            // By default this value is set to .PointAboveCenter.
            myAttributeLabelClass.LabelPlacement = Esri.ArcGISRuntime.Layers.LabelPlacement.LineAboveAlong;

            // If multiple labels conflict for placement (i.e. they overlap), this defines how to handle displaying the conflicts.
            // By default this value is set to .FixedPositionOrRemove.
            myAttributeLabelClass.LabelPosition = Esri.ArcGISRuntime.Layers.LabelPosition.FixedPositionOrRemove;

            // Prioritizes which label appears in one AttributeLabelClass -vs- another AttributeLabelClass. Since the labeling in this code 
            // example is just for one AttributeLabelClass, we will keep the default value. 
            // By default this value is set to .Medium.
            myAttributeLabelClass.LabelPriority = Esri.ArcGISRuntime.Layers.LabelPriority.Medium;

            // Define the MaxScale at which the Attribute labels appear. Typically, the closer you zoom in on the map then they appear.
            // By default this value is 0, which means labeling occurs at all scales.
            myAttributeLabelClass.MaxScale = 0;

            // Define the MinScale at which the Attribute labels appear. Typically, the father you zoom out on the map then they disappear. 
            // By default this value is 0, which means labeling occurs at all scales.
            myAttributeLabelClass.MinScale = 0;

            // Define the text that will appear for the labeling. In this case we want to append the letter 'I' (for Interstate) with the 
            // route number ([rte_num1]) of that highway segment. Examples: 'I - 95', 'I - 10', etc. The [rte_num1] Attribute field 
            // was given back as part of the FeatureLayer's ServiceFeatureTable.OutFields Property set earlier.
            // IMPORTANT: This value must be provided or else no labeling will occur!
            // NOTE: There are numerous ways to define how text that appears via the labeling engine. It is best to review the REST documentation
            // for your MapServer to know that exact syntax. For this code example review the REST doc:
            myAttributeLabelClass.TextExpression = "\"" + "I - " + "\"" + " CONCAT [rte_num1]";

            // The Highways FeatureLayer has several records where the route number ([rte_num1]) is blank. We don't want to have weird labeling
            // to occur that looks like 'I - ' because the route number is missing. So restrict the data using a where clause on the to non-empty
            // route number values; hence .WhereClause = "[rte_num1] <> ' '".
            // By default all records are returned (i.e. 1=1, True=True, etc.) and are only restricted when this value is set.
            myAttributeLabelClass.WhereClause = "[rte_num1] <> ' '";

            // If we were going wrap text on two lines; define that the 2nd line would begin on any word after the 10th character in the 1st line.
            // NOTE: You would need to set the .IsWordWrapEnabled = True.
            // By default this value is not set (meaning the entire string will be on one line).
            myAttributeLabelClass.WordWrapLength = 999;

            // Create a new TextSymbol to define the appearance of the text that is displayed.
            Esri.ArcGISRuntime.Symbology.TextSymbol myTextSymbol = new Esri.ArcGISRuntime.Symbology.TextSymbol();
            myTextSymbol.Color = System.Windows.Media.Colors.Black; // The color of the labeling text.
            myTextSymbol.BorderLineColor = System.Windows.Media.Colors.Yellow; // If you want a outline glow surrounding the labeling text.
            myTextSymbol.BorderLineSize = 3; // How big you want the outline glow around the labeling text.

            // Create a new SymbolFont to define the appearance of the text that is displayed.
            Esri.ArcGISRuntime.Symbology.SymbolFont mySymbolFont = new Esri.ArcGISRuntime.Symbology.SymbolFont();
            mySymbolFont.FontFamily = "Verdana"; // Use whatever FontFamily you have on your system. Ex: "Arial" "Verdana" "Times New Roman" "Courier New" "Cooper Black"
            mySymbolFont.FontSize = 12; // Define the point size of the labeling.
            mySymbolFont.FontStyle = Esri.ArcGISRuntime.Symbology.SymbolFontStyle.Normal; // Define the FontStyle. Others include: .Italics
            mySymbolFont.TextDecoration = Esri.ArcGISRuntime.Symbology.SymbolTextDecoration.None; // Supply a TextDecoration if desired. Others include: .LineThrough, .Underline.
            mySymbolFont.FontWeight = Esri.ArcGISRuntime.Symbology.SymbolFontWeight.Bold; // Supply a SymbolFontWeight if desired. Others include: .Normal.
            myTextSymbol.Font = mySymbolFont; // Apply the SymbolFont to the TextSymbol.Font Property.

            // Apply the TextSymbol to the AttributeLabelClass.Symbol Property.
            // IMPORTANT: This value must be provided or else no labeling will occur! 
            myAttributeLabelClass.Symbol = myTextSymbol;

            // Create a new AttributeLabelClassCollection to hold one or more AttributeLabelClass'es.
            Esri.ArcGISRuntime.Layers.AttributeLabelClassCollection myAttributeLabelClassCollection = new Esri.ArcGISRuntime.Layers.AttributeLabelClassCollection();
            myAttributeLabelClassCollection.Add(myAttributeLabelClass);

            // Create a new LabelProperties to hold the AttributeLabelClassCollection. Make sure it is enabled (i.e. Visible).
            Esri.ArcGISRuntime.Layers.LabelProperties myLabelProperties = new Esri.ArcGISRuntime.Layers.LabelProperties();
            myLabelProperties.IsEnabled = true;
            myLabelProperties.LabelClasses = myAttributeLabelClassCollection;

            // Apply the LabelProperties to the FeatureLayer.Labeling Property.
            myFeatureLayer.Labeling = myLabelProperties;

            // Enable labeling on the GraphicsLayer as well.
            myFeatureLayer.Labeling.IsEnabled = true;
        }
    }
}