关于 arcgis-cim-symbols
arcgis-cim-symbols 是 ArcGIS Maps SDK for JavaScript 中使用 CIM 创建高级制图符号的开发参考 Skill,适用于需要定制地图表达的开发者。它提供点、线、面符号、动画、数据驱动属性及符号转换的示例。
主要功能
- 01多图层点、线和面符号
- 02自定义矢量标记与线型
- 03动画符号及标记位置设置
- 04通过 Arcade 表达式驱动符号属性
- 05符号工具函数与格式转换
适用场景
- 01创建带箭头或虚线样式的线符号
- 02为面要素设置网纹填充
- 03根据要素属性控制颜色、大小或文字
- 04制作动画或多层组合地图符号
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-cim-symbols安装后在 Claude Code 中输入/arcgis-cim-symbols确认已加载。
详细介绍
ArcGIS CIM 符号
使用此技能通过 CIM(制图信息模型)创建高级制图符号。
导入模式
直接 ESM 导入
import CIMSymbol from "@arcgis/core/symbols/CIMSymbol.js";
import * as cimSymbolUtils from "@arcgis/core/symbols/support/cimSymbolUtils.js";
import * as cimConversionUtils from "@arcgis/core/symbols/support/cimConversionUtils.js";
CDN 动态导入
const CIMSymbol = await $arcgis.import("@arcgis/core/symbols/CIMSymbol.js");
const cimSymbolUtils = await $arcgis.import(
"@arcgis/core/symbols/support/cimSymbolUtils.js",
);
const cimConversionUtils = await $arcgis.import(
"@arcgis/core/symbols/support/cimConversionUtils.js",
);
注意: 以下示例使用自动类型转换。使用 CDN 时,将
import X from "path"替换为const X = await $arcgis.import("path")。
CIM 符号概述
CIM 符号提供了超越标准符号的高级制图功能:
- 多图层符号(堆叠的标记、填充和描边图层)
- 复杂的自定义标记图形(基于矢量的形状)
- 自定义线型和箭头
- 可控制持续时间和循环的动画符号
- 通过图元覆盖(Arcade 表达式)实现数据驱动的符号属性
CIM 符号结构
CIMSymbol (type: "cim")
└── data (CIMSymbolReference)
├── symbol (CIMPointSymbol | CIMLineSymbol | CIMPolygonSymbol)
│ └── symbolLayers[] (CIMVectorMarker | CIMSolidFill | CIMSolidStroke | CIMHatchFill | ...)
│ └── markerGraphics[] (CIMMarkerGraphic - for vector markers)
│ ├── geometry (point, polyline, polygon rings)
│ └── symbol (nested CIM symbol for the graphic)
└── primitiveOverrides[] (CIMPrimitiveOverride - data-driven)
CIM 点符号
基本 CIM 点符号
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],
},
],
},
},
],
},
],
},
},
},
});
编号标记(多图层)
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],
},
],
},
},
],
},
],
},
};
}
图钉标记
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 线符号
箭头线
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],
},
],
},
};
带线型的虚线
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 面符号
网纹填充
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],
},
],
},
};
标记放置类型
| 放置类型 | 用途 |
|---|---|
CIMMarkerPlacementAtExtremities | 在线的起点/终点放置箭头 |
CIMMarkerPlacementAlongLineSameSize | 沿线重复放置标记 |
CIMMarkerPlacementAtRatioPositions | 在特定位置(0-1)放置标记 |
CIMMarkerPlacementInsidePolygon | 用标记填充面内部 |
沿线放置
const markerAlongLine = {
type: "CIMVectorMarker",
enable: true,
size: 10,
markerPlacement: {
type: "CIMMarkerPlacementAlongLineSameSize",
placementTemplate: [20], // Every 20 points
angleToLine: true,
},
// ... marker graphics
};
按比例位置放置
const markerAtPositions = {
type: "CIMVectorMarker",
enable: true,
size: 8,
markerPlacement: {
type: "CIMMarkerPlacementAtRatioPositions",
positionArray: [0, 0.5, 1], // Start, middle, end
angleToLine: true,
},
// ... marker graphics
};
动画 CIM 符号
const animatedCIM = {
type: "CIMSymbolReference",
symbol: {
type: "CIMPointSymbol",
symbolLayers: [
{
type: "CIMVectorMarker",
enable: true,
size: 20,
animatedSymbolProperties: {
type: "CIMAnimatedSymbolProperties",
playAnimation: true,
reverseAnimation: false,
randomizeStartTime: true,
startTimeOffset: 0,
duration: 3, // Seconds
repeatType: "Loop", // Loop, Oscillate, None
},
// ... marker graphics
},
],
},
};
数据驱动属性(图元覆盖)
图元覆盖允许使用 Arcade 表达式,根据要素属性驱动任意 CIM 属性。
从属性获取颜色
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
},
],
},
},
],
},
],
},
};
从属性获取大小
primitiveOverrides: [
{
type: "CIMPrimitiveOverride",
primitiveName: "mainMarker",
propertyName: "Size",
valueExpressionInfo: {
type: "CIMExpressionInfo",
expression: "Sqrt($feature.population) * 0.01",
returnType: "Default",
},
},
];
常见覆盖属性
| 属性名称 | 目标 | 表达式返回值 |
|---|---|---|
"Color" | 填充/描边颜色 | [R, G, B, A] 数组 |
"Size" | 标记大小 | 数字 |
"TextString" | 文本内容 | 字符串 |
"Rotation" | 标记角度 | 数字(度) |
CIM 实用函数
cimSymbolUtils
import * as cimSymbolUtils from "@arcgis/core/symbols/support/cimSymbolUtils.js";
// Get CIM color for a symbol layer
const color = cimSymbolUtils.getCIMSymbolColor(cimSymbol);
// Set color on CIM symbol
cimSymbolUtils.applyCIMSymbolColor(cimSymbol, [255, 0, 0, 255]);
// Get/set rotation
const rotation = cimSymbolUtils.getCIMSymbolRotation(cimSymbol);
cimSymbolUtils.applyCIMSymbolRotation(cimSymbol, 45);
// Get/set size
const size = cimSymbolUtils.getCIMSymbolSize(cimSymbol);
cimSymbolUtils.applyCIMSymbolSize(cimSymbol, 24);
cimConversionUtils
import * as cimConversionUtils from "@arcgis/core/symbols/support/cimConversionUtils.js";
// Convert simple symbol to CIM equivalent
const cimData = cimConversionUtils.fromSimpleMarkerSymbol(simpleMarkerSymbol);
const cimData = cimConversionUtils.fromSimpleLineSymbol(simpleLineSymbol);
const cimData = cimConversionUtils.fromSimpleFillSymbol(simpleFillSymbol);
CIM 颜色与描边参考
颜色
// RGBA array [R, G, B, A] - each value 0-255
color: [255, 0, 0, 255]; // Red, fully opaque
color: [0, 0, 255, 128]; // Blue, 50% transparent
描边属性
{
type: "CIMSolidStroke",
enable: true,
width: 2,
color: [0, 0, 0, 255],
capStyle: "Round", // Butt, Round, Square
joinStyle: "Round", // Bevel, Miter, Round
miterLimit: 10
}
锚点
{
anchorPoint: { x: 0, y: 0 }, // Center
anchorPoint: { x: 0, y: -0.5 }, // Bottom center
anchorPointUnits: "Relative" // Relative or Absolute
}
在渲染器中使用 CIM
layer.renderer = {
type: "simple",
symbol: {
type: "cim",
data: arrowLineCIM, // Any CIMSymbolReference object
},
};
参考示例
cim-symbols- 创建基本 CIM 符号cim-animations- 动画 CIM 符号cim-line-arrows- 用于线要素的箭头符号cim-lines-and-polygons- CIM 线和面图案cim-primitive-overrides- 数据驱动的 CIM 属性cim-marker-placement- 沿线放置标记
常见问题
-
框架坐标:框架定义标记图形的坐标空间。几何坐标必须位于框架范围内。
-
图层顺序:符号图层在数组中按从下到上的顺序渲染。背景元素应放在前景元素之前。
-
图元名称:在整个符号中必须唯一,覆盖才能生效。每个
primitiveName都会与对应的primitiveOverrides条目匹配。 -
颜色格式:始终使用
[R, G, B, A],取值范围为 0-255。与标准符号不同,CIM 不接受颜色名称或十六进制字符串。 -
几何环:面环必须闭合(第一个点 = 最后一个点)。未闭合的环会导致渲染错误。
-
Enable 属性:每个符号图层都必须设置
enable: true,否则不会渲染。
相关技能
arcgis-visualization- 标准渲染器和符号arcgis-smart-mapping- 自动生成的渲染器arcgis-core-maps- 地图和视图设置
评论
支持 Markdown