CtrlK
BlogDocsLog inGet started
Tessl Logo

arcgis-cim-symbols

Create advanced cartographic symbols using CIM (Cartographic Information Model). Use for complex multi-layer symbols, animated markers, custom line patterns, and data-driven symbology.

79

Quality

75%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Optimize this skill with Tessl

npx tessl skill review --optimize ./contexts/4.34/skills/arcgis-cim-symbols/SKILL.md
SKILL.md
Quality
Evals
Security

ArcGIS CIM Symbols

Use this skill for creating advanced cartographic symbols with CIM (Cartographic Information Model).

CIM Symbol Basics

CIM symbols provide advanced cartographic capabilities:

  • Multi-layer symbols
  • Complex marker graphics
  • Custom line patterns
  • Animated symbols
  • Data-driven symbol properties

Basic CIM Symbol

const graphic = new Graphic({
  geometry: point,
  symbol: {
    type: "cim",
    data: {
      type: "CIMSymbolReference",
      symbol: {
        type: "CIMPointSymbol",
        symbolLayers: [{
          type: "CIMVectorMarker",
          enable: true,
          size: 20,
          frame: { xmin: 0, ymin: 0, xmax: 10, ymax: 10 },
          markerGraphics: [{
            type: "CIMMarkerGraphic",
            geometry: {
              rings: [[[0,0], [10,0], [10,10], [0,10], [0,0]]]
            },
            symbol: {
              type: "CIMPolygonSymbol",
              symbolLayers: [{
                type: "CIMSolidFill",
                enable: true,
                color: [255, 0, 0, 255]
              }]
            }
          }]
        }]
      }
    }
  }
});

CIM Point Symbols

Numbered Marker

function getNumberedMarkerCIM(number) {
  return {
    type: "CIMSymbolReference",
    primitiveOverrides: [{
      type: "CIMPrimitiveOverride",
      primitiveName: "textGraphic",
      propertyName: "TextString",
      valueExpressionInfo: {
        type: "CIMExpressionInfo",
        expression: "$feature.text",
        returnType: "Default"
      }
    }],
    symbol: {
      type: "CIMPointSymbol",
      symbolLayers: [
        // Text layer (on top)
        {
          type: "CIMVectorMarker",
          enable: true,
          size: 32,
          frame: { xmin: -5, ymin: -5, xmax: 5, ymax: 5 },
          markerGraphics: [{
            type: "CIMMarkerGraphic",
            primitiveName: "textGraphic",
            geometry: { x: 0, y: 0 },
            symbol: {
              type: "CIMTextSymbol",
              fontFamilyName: "Arial",
              fontStyleName: "Bold",
              height: 4,
              horizontalAlignment: "Center",
              verticalAlignment: "Center",
              symbol: {
                type: "CIMPolygonSymbol",
                symbolLayers: [{
                  type: "CIMSolidFill",
                  enable: true,
                  color: [255, 255, 255, 255]
                }]
              }
            },
            textString: String(number)
          }]
        },
        // Circle background
        {
          type: "CIMVectorMarker",
          enable: true,
          size: 24,
          frame: { xmin: 0, ymin: 0, xmax: 10, ymax: 10 },
          markerGraphics: [{
            type: "CIMMarkerGraphic",
            geometry: {
              rings: [/* circle coordinates */]
            },
            symbol: {
              type: "CIMPolygonSymbol",
              symbolLayers: [{
                type: "CIMSolidFill",
                enable: true,
                color: [0, 100, 200, 255]
              }]
            }
          }]
        }
      ]
    }
  };
}

Pin Marker

const pinMarkerCIM = {
  type: "CIMSymbolReference",
  symbol: {
    type: "CIMPointSymbol",
    symbolLayers: [{
      type: "CIMVectorMarker",
      enable: true,
      anchorPoint: { x: 0, y: -0.5 },
      anchorPointUnits: "Relative",
      size: 40,
      frame: { xmin: 0, ymin: 0, xmax: 20, ymax: 30 },
      markerGraphics: [{
        type: "CIMMarkerGraphic",
        geometry: {
          rings: [[
            [10, 30], [0, 15], [0, 10],
            [10, 0], [20, 10], [20, 15], [10, 30]
          ]]
        },
        symbol: {
          type: "CIMPolygonSymbol",
          symbolLayers: [
            {
              type: "CIMSolidStroke",
              enable: true,
              width: 1,
              color: [50, 50, 50, 255]
            },
            {
              type: "CIMSolidFill",
              enable: true,
              color: [255, 100, 100, 255]
            }
          ]
        }
      }]
    }]
  }
};

CIM Line Symbols

Arrow Line

const arrowLineCIM = {
  type: "CIMSymbolReference",
  symbol: {
    type: "CIMLineSymbol",
    symbolLayers: [
      // Arrow head at end
      {
        type: "CIMVectorMarker",
        enable: true,
        size: 12,
        markerPlacement: {
          type: "CIMMarkerPlacementAtExtremities",
          extremityPlacement: "JustEnd",
          angleToLine: true
        },
        frame: { xmin: 0, ymin: 0, xmax: 10, ymax: 10 },
        markerGraphics: [{
          type: "CIMMarkerGraphic",
          geometry: {
            rings: [[[0, 0], [10, 5], [0, 10], [3, 5], [0, 0]]]
          },
          symbol: {
            type: "CIMPolygonSymbol",
            symbolLayers: [{
              type: "CIMSolidFill",
              enable: true,
              color: [0, 0, 0, 255]
            }]
          }
        }]
      },
      // Line stroke
      {
        type: "CIMSolidStroke",
        enable: true,
        width: 2,
        color: [0, 0, 0, 255]
      }
    ]
  }
};

Dashed Line with Pattern

const dashedLineCIM = {
  type: "CIMSymbolReference",
  symbol: {
    type: "CIMLineSymbol",
    symbolLayers: [{
      type: "CIMSolidStroke",
      enable: true,
      width: 3,
      color: [0, 100, 200, 255],
      effects: [{
        type: "CIMGeometricEffectDashes",
        dashTemplate: [8, 4, 2, 4], // dash, gap, dash, gap
        lineDashEnding: "NoConstraint"
      }]
    }]
  }
};

CIM Polygon Symbols

Hatched Fill

const hatchedFillCIM = {
  type: "CIMSymbolReference",
  symbol: {
    type: "CIMPolygonSymbol",
    symbolLayers: [
      // Hatch pattern
      {
        type: "CIMHatchFill",
        enable: true,
        lineSymbol: {
          type: "CIMLineSymbol",
          symbolLayers: [{
            type: "CIMSolidStroke",
            enable: true,
            width: 1,
            color: [0, 0, 0, 255]
          }]
        },
        rotation: 45,
        separation: 5
      },
      // Background fill
      {
        type: "CIMSolidFill",
        enable: true,
        color: [255, 255, 200, 255]
      },
      // Outline
      {
        type: "CIMSolidStroke",
        enable: true,
        width: 2,
        color: [0, 0, 0, 255]
      }
    ]
  }
};

Marker Placement

Along Line

const markerAlongLine = {
  type: "CIMVectorMarker",
  enable: true,
  size: 10,
  markerPlacement: {
    type: "CIMMarkerPlacementAlongLineSameSize",
    placementTemplate: [20], // Every 20 points
    angleToLine: true
  },
  // ... marker graphics
};

At Vertices

const markerAtVertices = {
  type: "CIMVectorMarker",
  enable: true,
  size: 8,
  markerPlacement: {
    type: "CIMMarkerPlacementAtRatioPositions",
    positionArray: [0, 0.5, 1], // Start, middle, end
    angleToLine: true
  },
  // ... marker graphics
};

Animated CIM Symbols

// Animation is controlled via animatedSymbolProperties on symbol layers
const animatedCIM = {
  type: "CIMSymbolReference",
  symbol: {
    type: "CIMPointSymbol",
    symbolLayers: [{
      type: "CIMVectorMarker",
      enable: true,
      size: 20,
      // Animation properties
      animatedSymbolProperties: {
        type: "CIMAnimatedSymbolProperties",
        playAnimation: true,
        reverseAnimation: false,
        randomizeStartTime: true,
        startTimeOffset: 0,
        duration: 3, // Seconds
        repeatType: "Loop" // Loop, Oscillate, None
      },
      // ... marker graphics
    }]
  }
};

// Scale animation
const scaleAnimation = {
  type: "CIMVectorMarker",
  animatedSymbolProperties: {
    type: "CIMAnimatedSymbolProperties",
    playAnimation: true,
    duration: 2,
    repeatType: "Oscillate"
  },
  scaleSymbolsProportionally: true,
  // ... marker definition
};

Data-Driven Properties

Color from Attribute

const dataDrivenCIM = {
  type: "CIMSymbolReference",
  primitiveOverrides: [{
    type: "CIMPrimitiveOverride",
    primitiveName: "fillLayer",
    propertyName: "Color",
    valueExpressionInfo: {
      type: "CIMExpressionInfo",
      expression: `
        var val = $feature.value;
        if (val < 50) return [255, 0, 0, 255];
        if (val < 100) return [255, 255, 0, 255];
        return [0, 255, 0, 255];
      `,
      returnType: "Default"
    }
  }],
  symbol: {
    type: "CIMPointSymbol",
    symbolLayers: [{
      type: "CIMVectorMarker",
      markerGraphics: [{
        type: "CIMMarkerGraphic",
        symbol: {
          type: "CIMPolygonSymbol",
          symbolLayers: [{
            type: "CIMSolidFill",
            primitiveName: "fillLayer",
            enable: true,
            color: [128, 128, 128, 255] // Default
          }]
        }
      }]
    }]
  }
};

Size from Attribute

primitiveOverrides: [{
  type: "CIMPrimitiveOverride",
  primitiveName: "mainMarker",
  propertyName: "Size",
  valueExpressionInfo: {
    type: "CIMExpressionInfo",
    expression: "Sqrt($feature.population) * 0.01",
    returnType: "Default"
  }
}]

Common CIM Properties

Colors

// RGBA array [R, G, B, A] where each value is 0-255
color: [255, 0, 0, 255]  // Red, fully opaque
color: [0, 0, 255, 128]  // Blue, 50% transparent

Stroke Properties

{
  type: "CIMSolidStroke",
  enable: true,
  width: 2,
  color: [0, 0, 0, 255],
  capStyle: "Round",      // Butt, Round, Square
  joinStyle: "Round",     // Bevel, Miter, Round
  miterLimit: 10
}

Anchor Points

{
  anchorPoint: { x: 0, y: 0 },        // Center
  anchorPoint: { x: 0, y: -0.5 },     // Bottom center
  anchorPointUnits: "Relative"        // Relative or Absolute
}

TypeScript Usage

CIM symbols are plain objects by design (following CIM specification). For TypeScript safety, use as const or type annotations:

Using as const

const cimSymbol = {
  type: "cim",
  data: {
    type: "CIMSymbolReference",
    symbol: {
      type: "CIMPointSymbol",
      symbolLayers: [{
        type: "CIMVectorMarker",
        enable: true,
        size: 20,
        // ... rest of symbol definition
      }]
    }
  }
} as const;

Using Type Annotation

const cimSymbol: __esri.CIMSymbolProperties = {
  type: "cim",
  data: {
    type: "CIMSymbolReference",
    symbol: {
      type: "CIMPointSymbol",
      symbolLayers: [{
        type: "CIMVectorMarker",
        enable: true,
        size: 20,
        // ... rest of symbol definition
      }]
    }
  }
};

Note: CIM symbols are configuration objects and work well with autocasting. Use as const to keep discriminated union types narrow in TypeScript. See arcgis-core-maps skill for detailed guidance on autocasting.

Reference Samples

  • cim-symbols - Basic CIM symbol creation
  • cim-animations - Animated CIM symbols
  • cim-line-arrows - Arrow symbols for line features
  • cim-primitive-overrides - CIM primitive override patterns
  • cim-marker-placement - Marker placement along lines

Common Pitfalls

  1. Frame coordinates: Frame defines the coordinate space for marker graphics

  2. Layer order: Symbol layers render bottom to top in the array

  3. Primitive names: Must be unique within symbol for overrides to work

  4. Color format: Always use [R, G, B, A] with values 0-255

  5. Geometry rings: Rings must be closed (first point = last point)

Repository
SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.