Overview

You will learn: how to apply symbol colors and styles to features based on attribute values.

With the ArcGIS Runtime SDK for .NET you can apply custom symbol colors and styles to improve the visualization of feature layers by defining a Renderer. The first step is to define the renderer symbols, colors, and field values, and then apply it to the layer. The renderer is responsible for applying the symbols to appropriate features when the layer draws. There are many different types of symbols and renderers to choose from. Please visit the symbols and renderers documentation to learn more.

In this lab you will apply different renderers to the trailheads (points), trails (lines), and open spaces (polygon) feature layers.

Steps

Create a new ArcGIS Runtime App Visual Studio Project

  1. Start Visual Studio.

  2. Choose File > New > Project and select any of the ArcGIS Runtime App templates.

Display features in the Trailheads layer with an image (picture marker symbol)

  1. Open the MapViewModel.cs code file in your project.

  2. Find the definition for the Map property in the class. Notice that the default map is currently set to display a streets basemap. Remove the code that initializes the map (right of the '=', in other words).

    private Map _map;
    
  3. Add the following function to the MapViewModel class:

    private FeatureLayer CreateSymbolizedTrailHeads()
    {
    
    }
    
  4. Start the function by creating a new picture marker symbol (from an image URL). Use the marker symbol to create a new simple renderer.

    var trailHeadsImageUri = new Uri("http://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png");
    PictureMarkerSymbol trailHeadsSymbol = new PictureMarkerSymbol(trailHeadsImageUri);
    SimpleRenderer trailHeadsRenderer = new SimpleRenderer(trailHeadsSymbol);
    
  5. Create a FeatureLayer to display the Los Angeles trailheads feature service. Apply the render and return the new layer.

    var trailHeadsFeaturesUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0");
    FeatureLayer trailHeadsLayer = new FeatureLayer(trailHeadsFeaturesUri);
    trailHeadsLayer.Renderer = trailHeadsRenderer;
    
    return trailHeadsLayer;
    

Style the Trails layer by unique values

  1. Add the following function to the MapViewModel class that will symbolize trails with a UniqueValueRenderer.

    private FeatureLayer CreateSymbolizedTrails()
    {
    
    }
    
  2. Start the function by creating line symbols for trails that allow and those that don't allow bikes. Create new UniqueValue objects to define an attribute value and symbol to apply.

    SimpleLineSymbol bikeTrailSym = new SimpleLineSymbol(SimpleLineSymbolStyle.Dot, System.Windows.Media.Colors.Blue, 2.0);
    SimpleLineSymbol noBikeTrailSym = new SimpleLineSymbol(SimpleLineSymbolStyle.Dot, System.Windows.Media.Colors.Red, 2.0);
    UniqueValue trailsForBike = new UniqueValue("Bike trails", "Bike", bikeTrailSym, "Yes");
    UniqueValue trailsNoBike = new UniqueValue("No bike trails", "No Bike", noBikeTrailSym, "No");
    
  3. Create a new UniqueValueRenderer and define the attribute ("USE_BIKE") that contains the values to render. Add the UniqueValues created previously.

    UniqueValueRenderer trailsUniqueValueRenderer = new UniqueValueRenderer();
    trailsUniqueValueRenderer.FieldNames.Add("USE_BIKE");
    trailsUniqueValueRenderer.UniqueValues.Add(trailsForBike);
    trailsUniqueValueRenderer.UniqueValues.Add(trailsNoBike);
    
  4. Create a new FeatureLayer to display the trails features. Apply the unique values renderer and return the new layer.

    var trailsFeaturesUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0");
    FeatureLayer trailsFeatureLayer = new FeatureLayer(trailsFeaturesUri);
    trailsFeatureLayer.Renderer = trailsUniqueValueRenderer;
    
    return trailsFeatureLayer;
    

Style the Parks and Open Spaces layer by numeric values

  1. Add the following function to the MapViewModel class to symbolize open spaces with a ClassBreaksRenderer.

    private FeatureLayer CreateSymbolizedOpenSpaces()
    {
    
    }
    
  2. Start the function by creating fill symbols for three classes of open space area. Each fill symbol uses the same outline symbol and solid fill, but has a different color.

    // The colors below are defined for WPF. Other platforms use different namespaces: UWP=Windows.UI.ColorHelper, Xamarin=System.Drawing.Color
    SimpleLineSymbol fillOutlineSym = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Windows.Media.Colors.DarkGray, 0.5);
    SimpleFillSymbol acreageClassOneSym = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, System.Windows.Media.Color.FromArgb(255, 45, 128, 120), fillOutlineSym);
    SimpleFillSymbol acreageClassTwoSym = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, System.Windows.Media.Color.FromArgb(255, 173, 212, 106), fillOutlineSym);
    SimpleFillSymbol acreageClassThreeSym = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, System.Windows.Media.Color.FromArgb(255, 226, 235, 211), fillOutlineSym);
    
  3. Create three class breaks based on ranges of open space area. Assign a different fill symbol for each class, provide a description and label, and define the minimum and maximum values for each range. Add the class breaks to a list.

    ClassBreak acreageClassOneBreak = new ClassBreak("Under 1,629", "0 - 1629", 0.0, 1629.0, acreageClassOneSym);
    ClassBreak acreageClassTwoBreak = new ClassBreak("1,629 to 3,754", "1629 - 3754", 1629.0, 3754.0, acreageClassTwoSym);
    ClassBreak acreageClassThreeBreak = new ClassBreak("3,754 to 11,438", "3754 - 11438", 3754.0, 11438.0, acreageClassThreeSym);
    
    List<ClassBreak> acreageBreaks = new List<ClassBreak> { acreageClassOneBreak, acreageClassTwoBreak, acreageClassThreeBreak};
    
  4. Create the class breaks renderer on the "GIS_ACRES" field with the list of breaks. Create the open space layer, assign the renderer, then return the new layer.

    ClassBreaksRenderer openSpacesClassBreaksRenderer = new ClassBreaksRenderer("GIS_ACRES", acreageBreaks);
    
    var openSpacesFeaturesUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0");
    FeatureLayer openSpacesFeatureLayer = new FeatureLayer(openSpacesFeaturesUri);
    
    openSpacesFeatureLayer.Renderer = openSpacesClassBreaksRenderer;
    
    return openSpacesFeatureLayer;
    

Create a new map and add the symbolized layers

  1. In the MapViewModel constructor, call each of the functions created previously to get the symbolized layers.

    public MapViewModel()
    {
       FeatureLayer openSpacesLayer = CreateSymbolizedOpenSpaces();
       FeatureLayer trailsLayer = CreateSymbolizedTrails();
       FeatureLayer trailheadsLayer = CreateSymbolizedTrailHeads();
    }
    
  2. Create a new map centered on the Los Angeles trails, add the layers, then assign the new map to the Map property of the view model.

    Map trailMap = new Map(BasemapType.TopographicVector, 34.07986, -118.71921, 12);
    trailMap.OperationalLayers.Add(openSpacesLayer);
    trailMap.OperationalLayers.Add(trailsLayer);
    trailMap.OperationalLayers.Add(trailheadsLayer);
    
    Map = trailMap;
    
  3. Run your app to test your code. When the app opens, you should see trailheads symbolized with a picture marker, trails symbolized according to accessibility by bikes, and open spaces according to acreage.

Congratulations, you're done!

Check out and compare with our completed solution project.

Challenge

Explore multiple unique values

A UniqueValueRenderer can use more than one field to define unique values to display. The Trails layer was rendered with values in "USE_BIKE". The feature table, however, has additional fields to describe if the trail allows pets ("PET_ACC"), horses ("USE_EQU"), or all-terrain vehicles ("USE_ATV"). Experiment with rendering the trails layer with unique values that are combinations of values from these attributes (trails that allow both bikes and pets, for example).