ArcGIS Blog

Mapping

ArcGIS Maps SDK for JavaScript

Create points, lines, and polygons using CIMSymbols

By Anne Fitz

As of the 4.16 release, the ArcGIS API for JavaScript now supports point, line and polygon CIM symbols in 2D MapViews. CIM symbols are high-quality, scalable vector symbols for displaying features and graphics that are precisely displayed at any zoom level without blurriness. The best thing about CIM symbols is that they are completely customizable. They can incorporate multiple symbol layers and can be updated dynamically.

Quick links:
What is CIM | How is CIM used | Examples

CIM lines and polygons
Some examples of lines and polygons you can create in the ArcGIS API for JavaScript using the CIMSymbol class.

What is “CIM”?

CIM is the Esri Cartographic Information Model, which is a map content specification used to persist and transfer cartographic descriptions of GIS datasets. CIM is already being used to create symbology in ArcGIS Pro, so we wanted to bring that advanced symbology to the ArcGIS API for JavaScript. To learn more about CIM and how it works, check out the CIM Specification.

How is CIM used in the ArcGIS API for JavaScript?

CIMSymbol

A CIMSymbol is created by setting the CIMSymbolReference JSON on the CIMSymbol.data property. While there are examples for how to create CIM symbols in the API Reference and Sample Code in the ArcGIS API for JavaScript documentation, the bulk of the documentation lies within the CIM Specification.

// require(["esri/symbols/CIMSymbol"], function(CIMSymbol)
const cimSymbol = new CIMSymbol({
   data: {
      type: "CIMSymbolReference",
      symbol: {
         type: "CIMLineSymbol",
         symbolLayers: [{ ... }]
      },
      primitiveOverrides: [{ ... }]
   }
});

CIMSymbol.data.symbol

The symbol property on CIMSymbolReference can be of type CIMPointSymbol, CIMLineSymbol, CIMPolygonSymbol, or CIMTextSymbol. Each symbol is made up of one or more symbolLayers. CIMTextSymbol is an exception—it has native properties but no symbol layers.

symbolLayers are the building blocks of CIM symbols, they combine to make rich graphical depictions. There are three main types of symbol layers (similar to the simple symbols provided in the API): CIMMarker, CIMStroke, and CIMFill. A SimpleLineSymbol in the API would be equivalent to a CIMSolidStroke symbol layer, a SimpleFillSymbol would be equivalent to CIMSolidFill, and so on. CIMSymbol is unique because you can combine symbol layers to create custom symbols. For example, you could create a CIMLineSymbol with a CIMSolidStroke and CIMMarker symbol to place markers along a line.

Note: CIMLineSymbol and CIMPolygonSymbol are not currently supported in a 3D SceneView.

CIMSymbol.data.primitiveOverrides

The primitiveOverrides property on CIMSymbolReference allows you to use an Arcade expression to override specific properties on the symbol.

WebStyleSymbols

WebStyleSymbols contain a library of pre-defined 2D CIM symbols that you can conveniently reference in your apps. Visit the Esri Web Style Symbols (2D) guide page to see what WebStyleSymbols are currently available in the JavaScript API. The CIM JSON is available for each WebStyleSymbol in the guide page.

WebStyleSymbol to CIM
Using the Web Style Symbol (2D) guide page, you can easily copy the CIM JSON for the symbol.

Let’s see the CIMSymbol in action!

Now that we’ve learned more about what CIM is and how it’s used in the ArcGIS API for JavaScript, let’s see what it looks like when we use CIM symbols in an application.

Arrows along a line

Let’s say we want to symbolize one-way streets, using arrows to designate the direction of traffic flow. Previously, this would be incredibly difficult to accomplish, but now (as of the 4.16 release), we can create a CIMLineSymbol with two symbol layers – a stroke symbol layer to show the location of the streets, and another symbol layer to place arrow markers on top of the line. Let’s take a look at what that looks like:

CIMSymbol.data = {
   type: "CIMSymbolReference",
   symbol: {
      type: "CIMLineSymbol",
      symbolLayers: [
        {
           // black 1px line symbol
           type: "CIMSolidStroke",
           enable: true,
           width: 1,
           color: [0, 0, 0, 255]
        },
        {
           // arrow symbol
           type: "CIMVectorMarker",
           enable: true,
           size: 5,
           markerPlacement: {
              // places same size markers along the line
              type: "CIMMarkerPlacementAlongLineSameSize", 
              endings: "WithMarkers",
              placementTemplate: [19.5] // determines space between each arrow
           },
           frame: {
              xmin: -5,
              ymin: -5,
              xmax: 5,
              ymax: 5
           },
           markerGraphics: [
              {
                 type: "CIMMarkerGraphic",
                 geometry: {
                    rings: [
                      [
                        [-8, -5.47],
                        [-8, 5.6],
                        [1.96, -0.03],
                        [-8, -5.47]
                      ]
                    ]
                 },
                 symbol: {
                    // black fill for the arrow symbol
                    type: "CIMPolygonSymbol",
                    symbolLayers: [
                       {
                          type: "CIMSolidFill",
                          enable: true,
                          color: [0, 0, 0, 255]
                       }
                    ]
                 }
              }
           ]
        }
      ]
   }
}

The resulting symbology on the layer will look like this:

CIM arrows along a line
A CIMSymbol is used to represent traffic flow as a black line with an arrow head.

More examples

COVID-19 Cases over 14 DaysThis app creates a CIMPointSymbol for each county based on the number of COVID-19 cases reported in the past 14 days. The size and geometry of the CIMSymbol is determined based on the number of COVID-19 cases, creating an interesting “spike” visualization highlighting regions with the largest outbreaks.

Covid-19 CIM
This app uses CIMSymbols to show the number of COVID-19 cases per 1k people in the past 14 days.

Lake Tahoe – Tahoe Rim Trail: This app uses CIM symbols in several different ways.

  • A CIMLineSymbol visualizes the Tahoe Rim Trail. This line symbol is comprised of three different symbol layers, creating the effect of a cased line with dashes.
  • A CIMPolygonSymbol visualizes the boundary of Lake Tahoe.
  • Each trailhead is rendered as a WebStyleSymbol. We can use WebStyleSymbol.fetchCIMSymbol() to convert a WebStyleSymbol to a CIMSymbol and then use the cimSymbolUtils class to get and set the size and rotation on these symbols.
Lake Tahoe CIM
Use CIMSymbols to visualize the Tahoe Rim Trail.

Wurman dotsThis app shows how to use CIM symbols with a primitive override. The override uses Arcade to determine the size of the CIMPointSymbol’s inner circle.

Wurman Dots
Wurman Dots mapping style displayed using CIMSymbols.

CIMSymbol is still in beta. Some properties listed in the CIM Specification are not yet supported in the ArcGIS API for JavaScript. If you are confused why your symbol isn’t appearing as you would expect, make sure to check out the known limitations to see what is or is not supported.

This post includes contributions from Fang Li.

Share this article

Subscribe
Notify of
4 Comments
Oldest
Newest
Inline Feedbacks
View all comments