Skip to content

ProSnippets Symbology

UmaHarano edited this page Nov 6, 2023 · 14 revisions

All ProSnippets listed here are also used by the following sample code: Symbology sample code

Language:              C#  
Subject:               Map-Authoring  
Contributor:           ArcGIS Pro SDK Team <arcgisprosdk@esri.com>  
Organization:          esri, http://www.esri.com  
Date:                  10/9/2023  
ArcGIS Pro:            3.2  
Visual Studio:         2022  
.NET Target Framework: .Net 6  

LineSymbology

Markers placed at a 45 degree angle

Create a line symbol with the markers placed at a 45 degree angle.
LineSymbolAngleMarker

internal static Task<CIMLineSymbol> CreateMyMarkerLineSymbolAsync()
{
  return QueuedTask.Run<CIMLineSymbol>(() =>
  {
    //Create a marker from the "|" character.  This is the marker that will be used to render the line layer.
    var lineMarker = SymbolFactory.Instance.ConstructMarker(124, "Agency FB", "Regular", 12);

    //Default line symbol which will be modified 
    var blackSolidLineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 2, SimpleLineStyle.Solid);

    //Modifying the marker to align with line
    //First define "markerplacement"
    CIMMarkerPlacementAlongLineSameSize markerPlacement = new CIMMarkerPlacementAlongLineSameSize()
    {
      AngleToLine = true,
      PlacementTemplate = new double[] { 5 }
    };
    //assign the markerplacement to the marker
    lineMarker.MarkerPlacement = markerPlacement;
    //angle the marker if needed
    lineMarker.Rotation = 45;

    //assign the marker as a layer to the line symbol
    blackSolidLineSymbol.SymbolLayers[0] = lineMarker;

    return blackSolidLineSymbol;
  });
}

Dash line with two markers - Method I

Create a line symbol with a dash and two markers.

This line symbol comprises three symbol layers listed below:

  1. A solid stroke that has dashes.
  2. A circle marker.
  3. A square marker. LineSymbolTwoMarkers
internal static Task<CIMLineSymbol> CreateLineDashTwoMarkersAync()
{
  return QueuedTask.Run<CIMLineSymbol>(() =>
  {

    var dash2MarkersLine = new CIMLineSymbol();

    var mySymbolLyrs = new CIMSymbolLayer[]
          {
                new CIMSolidStroke()
                {
                    Color = ColorFactory.Instance.BlackRGB,
                    Enable = true,
                    ColorLocked = true,
                    CapStyle = LineCapStyle.Round,
                    JoinStyle = LineJoinStyle.Round,
                    LineStyle3D = Simple3DLineStyle.Strip,
                    MiterLimit = 10,
                    Width = 1,
                    CloseCaps3D = false,
                    Effects = new CIMGeometricEffect[]
                    {
                        new CIMGeometricEffectDashes()
                        {
                            CustomEndingOffset = 0,
                            DashTemplate = new double[] {20, 10, 20, 10},
                            LineDashEnding = LineDashEnding.HalfPattern,
                            OffsetAlongLine = 0,
                            ControlPointEnding = LineDashEnding.NoConstraint
                        },
                        new CIMGeometricEffectOffset()
                        {
                            Method = GeometricEffectOffsetMethod.Bevelled,
                            Offset = 0,
                            Option = GeometricEffectOffsetOption.Fast
                        }
                    },
                },
                CreateCircleMarkerPerSpecs(),
                CreateSquareMarkerPerSpecs()
      };
    dash2MarkersLine.SymbolLayers = mySymbolLyrs;
    return dash2MarkersLine;
  });
}
private static CIMMarker CreateCircleMarkerPerSpecs()
{
  var circleMarker = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.BlackRGB, 5, SimpleMarkerStyle.Circle) as CIMVectorMarker;
  //Modifying the marker to align with line
  //First define "markerplacement"
  CIMMarkerPlacementAlongLineSameSize markerPlacement = new CIMMarkerPlacementAlongLineSameSize()
  {
    AngleToLine = true,
    Offset = 0,
    Endings = PlacementEndings.Custom,
    OffsetAlongLine = 15,
    PlacementTemplate = new double[] { 60 }
  };
  //assign the markerplacement to the marker
  circleMarker.MarkerPlacement = markerPlacement;
  return circleMarker;
}
private static CIMMarker CreateSquareMarkerPerSpecs()
{
  var squareMarker = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.BlueRGB, 5, SimpleMarkerStyle.Square) as CIMVectorMarker;
  CIMMarkerPlacementAlongLineSameSize markerPlacement2 = new CIMMarkerPlacementAlongLineSameSize()
  {
    AngleToLine = true,
    Endings = PlacementEndings.Custom,
    OffsetAlongLine = 45,
    PlacementTemplate = new double[] { 60 },
  };
  squareMarker.MarkerPlacement = markerPlacement2;
  return squareMarker;
}

Dash line with two markers - Method II

Create a line symbol with a dash and two markers.
In this pattern of creating this symbol, a CIMVectorMarker object is created as a new CIMSymbolLayer. The circle and square markers created by ContructMarker method is then assigned to the MarkerGraphics property of the CIMVectorMarker. When using this method, the CIMVectorMarker's Frame property needs to be set to the CIMMarker object's Frame. Similarly, the CIMVectorMarker's Size property needs to be set to the CIMMarker object's size.

This line symbol comprises three symbol layers listed below:

  1. A solid stroke that has dashes.
  2. A circle marker.
  3. A square marker. LineSymbolTwoMarkers
internal static Task<CIMLineSymbol> CreateLineDashTwoMarkers2Async()
{
  return QueuedTask.Run<CIMLineSymbol>(() =>
  {
    //default line symbol that will get modified.
    var dash2MarkersLine = new CIMLineSymbol();
    //circle marker to be used in our line symbol as a layer
    var circleMarker = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.BlackRGB, 5, SimpleMarkerStyle.Circle) as CIMVectorMarker;
    //circle marker to be used in our line symbol as a layer
    var squareMarker = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.BlueRGB, 5, SimpleMarkerStyle.Square) as CIMVectorMarker;
    //Create the array of layers that make the new line symbol
    CIMSymbolLayer[] mySymbolLyrs =
          {
                new CIMSolidStroke() //dash line
                {
                    Color = ColorFactory.Instance.BlackRGB,
                    Enable = true,
                    ColorLocked = true,
                    CapStyle = LineCapStyle.Round,
                    JoinStyle = LineJoinStyle.Round,
                    LineStyle3D = Simple3DLineStyle.Strip,
                    MiterLimit = 10,
                    Width = 1,
                    CloseCaps3D = false,
                    Effects = new CIMGeometricEffect[]
                    {
                        new CIMGeometricEffectDashes()
                        {
                            CustomEndingOffset = 0,
                            DashTemplate = new double[] {20, 10, 20, 10},
                            LineDashEnding = LineDashEnding.HalfPattern,
                            OffsetAlongLine = 0,
                            ControlPointEnding = LineDashEnding.NoConstraint
                        },
                        new CIMGeometricEffectOffset()
                        {
                            Method = GeometricEffectOffsetMethod.Bevelled,
                            Offset = 0,
                            Option = GeometricEffectOffsetOption.Fast
                        }
                    }
                },
                new CIMVectorMarker() //circle marker
                {
                    MarkerGraphics = circleMarker.MarkerGraphics,
                    Frame = circleMarker.Frame, //need to match the CIMVector marker's frame to the circleMarker's frame.
                    Size = circleMarker.Size,    //need to match the CIMVector marker's size to the circleMarker's size.                    
                   MarkerPlacement = new CIMMarkerPlacementAlongLineSameSize()
                   {
                       AngleToLine = true,
                       Offset = 0,
                       Endings = PlacementEndings.Custom,
                       OffsetAlongLine = 15,
                       PlacementTemplate = new double[] {60},
                   }

                },
                new CIMVectorMarker() //square marker
                {
                   MarkerGraphics = squareMarker.MarkerGraphics,
                   Frame = squareMarker.Frame, //need to match the CIMVector marker's frame to the squareMarker frame.
                   Size = squareMarker.Size, //need to match the CIMVector marker's size to the squareMarker size.
                   MarkerPlacement = new CIMMarkerPlacementAlongLineSameSize()
                   {
                       AngleToLine = true,
                       Endings = PlacementEndings.Custom,
                       OffsetAlongLine = 45,
                       PlacementTemplate = new double[] {60},
                   }
                }
      };
    dash2MarkersLine.SymbolLayers = mySymbolLyrs;
    return dash2MarkersLine;
  });

}

MeshSymbology

Mesh material fill symbol

Create a mesh symbol that can be applied to a multi-patch feature layer.

A mesh symbol is a CIMMeshSymbol object. Define an array of CIMSymbolLayers which contains a CIMMaterialSymbol layer with the specified properties such as Color, etc. Assign this array of CIMSymbolLayers to the CIMMeshSymbol. MeshSymbolOrange

public static Task<CIMMeshSymbol> CreateMeshSymbolAsync()
{
    return QueuedTask.Run<CIMMeshSymbol>(() =>
   {
       CIMSymbolLayer[] materialSymbolLayer =
      {
            new CIMMaterialSymbolLayer()
            {
                Color = ColorFactory.Instance.CreateRGBColor(230,152,0),
                MaterialMode = MaterialMode.Multiply
            }
       };
       var myMeshSymbol = new CIMMeshSymbol()
       {
           SymbolLayers = materialSymbolLayer
       };
       return myMeshSymbol;
   });
}

Mesh procedural texture symbol

Creates Mesh procedural symbol with various textures. MeshProceduralTexture Note: The rule package used in this method can be obtained from the Sample Data included in the arcgis-pro-sdk-community-samples repository.

private static readonly string _rulePkgPath = @"C:\Data\RulePackages\MultipatchTextures.rpk";
public static Task<CIMMeshSymbol> CreateProceduralMeshSymbolAsync()
{
    return QueuedTask.Run<CIMMeshSymbol>(() =>
    {                  
        CIMSymbolLayer[] proceduralSymbolLyr =
        {
            new CIMProceduralSymbolLayer()
            {
                PrimitiveName = "Textures",
                RulePackage = _rulePkgPath,
                RulePackageName = "Textures",
            }
        };
        var myMeshSymbol = new CIMMeshSymbol()
        {
            SymbolLayers = proceduralSymbolLyr
        };

        return myMeshSymbol;
    });
}

PointSymbology

Custom fill and outline

Creates a point symbol with custom fill and outline PointSymbolMarker

internal static Task<CIMPointSymbol> CreatePointSymbolAsync()
{
  return QueuedTask.Run<CIMPointSymbol>(() =>
  {
    var circlePtSymbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.BlueRGB, 6, SimpleMarkerStyle.Circle);
    //Modifying this point symbol with the attributes we want.
    //getting the marker that is used to render the symbol
    var marker = circlePtSymbol.SymbolLayers[0] as CIMVectorMarker;
    //Getting the polygon symbol layers components in the marker
    var polySymbol = marker.MarkerGraphics[0].Symbol as CIMPolygonSymbol;
    //modifying the polygon's outline and width per requirements
    polySymbol.SymbolLayers[0] = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2, SimpleLineStyle.Solid); //This is the outline
    polySymbol.SymbolLayers[1] = SymbolFactory.Instance.ConstructSolidFill(ColorFactory.Instance.BlueRGB); //This is the fill
    return circlePtSymbol;
  });

}

Point Symbol from a font

Create a point symbol from a character in a font file PointSymbolFont

internal static Task<CIMPointSymbol> CreateMarkerSymbolAsync()
{
  //Construct point symbol from marker
  return QueuedTask.Run<CIMPointSymbol>(() =>
  {
    //creating the marker from the Font selected
    var cimMarker = SymbolFactory.Instance.ConstructMarker(47, "Wingdings 3", "Regular", 12);
    return SymbolFactory.Instance.ConstructPointSymbol(cimMarker);
  });

}

PolygonSymbology

Diagonal cross hatch fill

Create a polygon symbol with a diagonal cross hatch fill.
PolygonSymbolDiagonalCrossHatch

public static Task<CIMPolygonSymbol> CreateDiagonalCrossPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    var trans = 50.0;//semi transparent
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(0, 0, 0, trans), 2.0, SimpleLineStyle.Solid);

    //Stroke for the fill
    var solid = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(255, 0, 0, trans), 1.0, SimpleLineStyle.Solid);

    //Mimic cross hatch
    CIMFill[] diagonalCross =
              {
                new CIMHatchFill() {
                    Enable = true,
                    Rotation = 45.0,
                    Separation = 5.0,
                    LineSymbol = new CIMLineSymbol() { SymbolLayers = new CIMSymbolLayer[1] { solid } }
                },
                new CIMHatchFill() {
                    Enable = true,
                    Rotation = -45.0,
                    Separation = 5.0,
                    LineSymbol = new CIMLineSymbol() { SymbolLayers = new CIMSymbolLayer[1] { solid } }
                }
      };
    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
      {
                outline
      };
    foreach (var fill in diagonalCross)
      symbolLayers.Add(fill);
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Cross hatch

Create a polygon symbol using the ConstructHatchFill method .
PolygonSymbolDiagonalCrossHatch

private static Task<CIMPolygonSymbol> CreateHatchFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    CIMStroke lineStroke = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(51, 51, 51, 60), 4, SimpleLineStyle.Solid);
    //gradient
    var hatchFill = SymbolFactory.Instance.ConstructHatchFill(lineStroke, 45, 6, 0);

    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
    {
      hatchFill
    };
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Dash dot fill

Create a polygon symbol with a dash dot fill.
PolygonSymbolDashDot

public static Task<CIMPolygonSymbol> CreateDashDotFillAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    var trans = 50.0;//semi transparent
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(0, 0, 0, trans), 2.0, SimpleLineStyle.Solid);

    //Stroke for the fill            
    var dashDot = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.RedRGB, 1.0, SimpleLineStyle.DashDotDot);
    //Mimic cross hatch
    CIMFill[] solidColorHatch =
          {

             new CIMHatchFill()
            {
                Enable = true,
                Rotation = 0.0,
                Separation = 2.5,
                LineSymbol = new CIMLineSymbol(){SymbolLayers = new CIMSymbolLayer[1] {dashDot } }
            },
             new CIMSolidFill()
            {
                Enable = true,
                Color = ColorFactory.Instance.CreateRGBColor(255, 255, 0)
            },
  };
    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>();
    symbolLayers.Add(outline);
    foreach (var fill in solidColorHatch)
      symbolLayers.Add(fill);
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Gradient color fill using CIMGradientFill

Create a polygon symbol with a gradient color fill.
PolygonSymbolGradientColor

  1. Create a solid colored stroke with 50% transparency
  2. Create a fill using gradient colors red through green
  3. Apply both the stroke and fill as a symbol layer array to the new PolygonSymbol
public static Task<CIMPolygonSymbol> CreateGradientFillAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    var trans = 50.0;//semi transparent
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(0, 0, 0, trans), 2.0, SimpleLineStyle.Solid);
    //Mimic cross hatch
    CIMFill solidColorHatch =
           new CIMGradientFill()
       {
         ColorRamp = ColorFactory.Instance.ConstructColorRamp(ColorRampAlgorithm.LinearContinuous,
                                  ColorFactory.Instance.RedRGB, ColorFactory.Instance.GreenRGB)
       };
    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
      {
                outline,
                solidColorHatch
      };

    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Gradient fill between two colors

Create a polygon symbol using the ConstructGradientFill method. Constructs a gradient fill between two colors passed to the method.
PolygonSymbolTwoColors

public static Task<CIMPolygonSymbol> CreateGradientTwoColorsPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //gradient fill between 2 colors
    var gradientFill = SymbolFactory.Instance.ConstructGradientFill(CIMColor.CreateRGBColor(235, 64, 52), CIMColor.NoColor(), GradientFillMethod.Linear);
    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
      {
                gradientFill
      };
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });

}

Gradient fill using Color ramp

Create a polygon symbol using the ConstructGradientFill method. Constructs a gradient fill using the specified color ramp.
PolygonSymbolColorRamp

public static Task<CIMPolygonSymbol> CreateGradientColorRampPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //outine
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(49, 49, 49), 2.0, SimpleLineStyle.Solid);

    //gradient fill using a color ramp
    var gradientFill = SymbolFactory.Instance.ConstructGradientFill(GetColorRamp(), GradientFillMethod.Linear);

    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
      {
                outline,
                gradientFill
      };
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });

}

Picture fill

Constructs a picture fill with the specified parameters. ConstructPictureFill

private static Task<CIMPolygonSymbol> CreatePictureFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(110, 110, 110), 2.0, SimpleLineStyle.Solid);
    //picture
    var imgPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Images\CaliforniaEmblem.png");
    var pictureFill = SymbolFactory.Instance.ConstructPictureFill(imgPath, 64);

    List<CIMSymbolLayer> symbolLayers = new()
    {
      outline,
      pictureFill
    };
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Animation water

Constructs a water fill of specific color, waterbody size and wave strength. This fill can be used on polygon feature classes in a Scene view only. ConstructWaterFill

private static Task<CIMPolygonSymbol> CreateWaterFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    CIMStroke outline = SymbolFactory.Instance.ConstructStroke(CIMColor.CreateRGBColor(49, 49, 49, 50.0), 2.0, SimpleLineStyle.Solid);
    var waterFill = SymbolFactory.Instance.ConstructWaterFill(CIMColor.CreateRGBColor(3, 223, 252), WaterbodySize.Large, WaveStrength.Rippled);
    List<CIMSymbolLayer> symbolLayers = new List<CIMSymbolLayer>
      {
                outline,
                waterFill
      };
    return new CIMPolygonSymbol() { SymbolLayers = symbolLayers.ToArray() };
  });
}

Pen and Ink: Ripple

Constructs a polygon symbol in the specified color representing a pen and ink ripple water fill. See https://www.esri.com/arcgis-blog/products/arcgis-pro/mapping/please-steal-this-pen-and-ink-style/ polygonRipple.png

private static Task<CIMPolygonSymbol> CreateRippleFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //Ripple pen and ink
    var penInkRipple = SymbolFactory.Instance.ConstructPolygonSymbolWithPenInkRipple(CIMColor.CreateRGBColor(13, 24, 54));
    return penInkRipple;
  });
}

Pen and Ink: Stipple

Constructs a polygon symbol in the specified color representing a pen and ink stipple effect. See https://www.esri.com/arcgis-blog/products/arcgis-pro/mapping/please-steal-this-pen-and-ink-style/ polygonStipple.png

private static Task<CIMPolygonSymbol> CreateStippleFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //Stipple pen and ink
    var penInkRipple = SymbolFactory.Instance.ConstructPolygonSymbolWithPenInkStipple(CIMColor.CreateRGBColor(78, 133, 105), true);
    return penInkRipple;
  });
}

Pen and Ink: Cross Hatch

Constructs a polygon symbol in the specified color representing a pen and ink cross hatch effect. See https://www.esri.com/arcgis-blog/products/arcgis-pro/mapping/please-steal-this-pen-and-ink-style/ polygonPNHatch.png

private static Task<CIMPolygonSymbol> CreatePenInkCrossHatchFillPolygonAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //Cross Hatch pen and ink
    var penkInkCrossHatch = SymbolFactory.Instance.ConstructPolygonSymbolWithPenInkCrossHatch(CIMColor.CreateRGBColor(168, 49, 22), true);
    return penkInkCrossHatch;
  });
}

Procedural Symbol

Create a procedural symbol that can be applied to a polygon building footprint layer ProceduralSymbol Note: The rule package used in this method can be obtained from the Sample Data included in the arcgis-pro-sdk-community-samples repository.

private static readonly string _rulePkgPath = @"C:\Data\RulePackages\Venice_2014.rpk";
public static Task<CIMPolygonSymbol> CreateProceduralPolygonSymbolAsync()
{
  return QueuedTask.Run<CIMPolygonSymbol>(() =>
  {
    //Polygon symbol to hold the procedural layer
    var myPolygonSymbol = SymbolFactory.Instance.ConstructPolygonSymbol();

    //Array of layers to hold a procedural symbol layer
    CIMSymbolLayer[] proceduralSymbolLyr =
          {
                new CIMProceduralSymbolLayer()
                {
                    PrimitiveName = "Venice Rule package 2014",
                    RulePackage = _rulePkgPath,
                    RulePackageName = "Venice_2014",
                }
      };
    myPolygonSymbol.SymbolLayers = proceduralSymbolLyr;
    return myPolygonSymbol;
  });
}
Clone this wiki locally