arcgis-arcade について
arcgis-arcade は、ArcGIS の Arcade 式を作成するためのスキルです。ポップアップ、レンダラー、ラベル、計算を設定する開発者向けに、式の例や実行方法、注意点をまとめています。
主な機能
- 01ポップアップ式
- 02レンダラーと可視化の式
- 03ラベルとフィールド計算
- 04Arcade 関数の例
- 05プログラム実行とデバッグ
活用シーン
- 01動的なポップアップ内容の作成
- 02データに基づくフィーチャ描画
- 03カスタム地図ラベルの定義
- 04フィールド計算やフォーム検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-arcadeインストール後、Claude Code で/arcgis-arcadeを入力して読み込まれたか確認します。
詳細
ArcGIS Arcade 式
ポップアップ、レンダラー、ラベル、計算で Arcade 式を記述する際に、このスキルを使用します。
インポートパターン
ESM の直接インポート
import * as arcade from "@arcgis/core/arcade.js";
動的インポート(CDN)
const arcade = await $arcgis.import("@arcgis/core/arcade.js");
Arcade の基本
Arcade は ArcGIS の式言語です。次の用途で使用されます。
- 動的なポップアップコンテンツ
- データ駆動型レンダリング
- カスタムラベル
- フィールド計算
- フォームの検証
基本構文
// Variables
var population = $feature.population;
var area = $feature.area_sqkm;
// Calculations
var density = population / area;
// Return result
return Round(density, 2);
PopupTemplates での Arcade
式情報
const popupTemplate = {
title: "{name}",
expressionInfos: [
{
name: "population-density",
title: "Population Density",
expression: "Round($feature.population / $feature.area_sqkm, 2)",
},
{
name: "formatted-date",
title: "Formatted Date",
expression: "Text($feature.created_date, 'MMMM D, YYYY')",
},
],
content: "Density: {expression/population-density} people/km²",
};
複雑な式
const popupTemplate = {
title: "{name}",
expressionInfos: [
{
name: "predominant-category",
title: "Predominant Category",
expression: `
var fields = [
{ value: $feature.category_a, alias: "Category A" },
{ value: $feature.category_b, alias: "Category B" },
{ value: $feature.category_c, alias: "Category C" }
];
var maxValue = -Infinity;
var maxCategory = "";
for (var i in fields) {
if (fields[i].value > maxValue) {
maxValue = fields[i].value;
maxCategory = fields[i].alias;
}
}
return maxCategory;
`,
},
],
content: [
{
type: "text",
text: "The predominant category is: {expression/predominant-category}",
},
{
type: "fields",
fieldInfos: [
{
fieldName: "expression/predominant-category",
},
],
},
],
};
レンダラーでの Arcade
値式
const renderer = {
type: "unique-value",
valueExpression: `
var labor = $feature.labor_force;
var notLabor = $feature.not_in_labor_force;
if (labor > notLabor) {
return "In labor force";
} else {
return "Not in labor force";
}
`,
valueExpressionTitle: "Labor Force Status",
uniqueValueInfos: [
{
value: "In labor force",
symbol: { type: "simple-fill", color: "blue" },
},
{
value: "Not in labor force",
symbol: { type: "simple-fill", color: "orange" },
},
],
};
視覚変数の式
const renderer = {
type: "simple",
symbol: { type: "simple-marker", color: "red" },
visualVariables: [
{
type: "size",
valueExpression: "Sqrt($feature.population) * 0.1",
valueExpressionTitle: "Population (scaled)",
stops: [
{ value: 10, size: 4 },
{ value: 100, size: 40 },
],
},
{
type: "opacity",
valueExpression: "($feature.value / $feature.max_value) * 100",
valueExpressionTitle: "Percentage of max",
stops: [
{ value: 20, opacity: 0.2 },
{ value: 80, opacity: 1 },
],
},
],
};
ラベルでの Arcade
layer.labelingInfo = [
{
symbol: {
type: "text",
color: "black",
font: { size: 10 },
},
labelExpressionInfo: {
expression: `
var name = $feature.name;
var pop = $feature.population;
if (pop > 1000000) {
return name + " (" + Round(pop/1000000, 1) + "M)";
} else if (pop > 1000) {
return name + " (" + Round(pop/1000, 0) + "K)";
}
return name;
`,
},
where: "population > 50000",
},
];
よく使う Arcade 関数
数学関数
Round(3.14159, 2) // 3.14
Floor(3.9) // 3
Ceil(3.1) // 4
Abs(-5) // 5
Sqrt(16) // 4
Pow(2, 3) // 8
Min(1, 2, 3) // 1
Max(1, 2, 3) // 3
Sum([1, 2, 3]) // 6
Mean([1, 2, 3]) // 2
テキスト関数
Upper("hello") // "HELLO"
Lower("HELLO") // "hello"
Trim(" hello ") // "hello"
Left("hello", 2) // "he"
Right("hello", 2) // "lo"
Mid("hello", 2, 2) // "ll"
Find("l", "hello") // 2
Replace("hello", "l", "L") // "heLLo"
Split("a,b,c", ",") // ["a", "b", "c"]
Concatenate(["a", "b"]) // "ab"
日付関数
Now() // Current date/time
Today() // Current date
Year($feature.date_field) // Extract year
Month($feature.date_field) // Extract month (1-12)
Day($feature.date_field) // Extract day
DateDiff(Now(), $feature.date, "days") // Days between dates
Text($feature.date, "MMMM D, YYYY") // Format date
ジオメトリ関数
Area($feature, "square-kilometers")
Length($feature, "kilometers")
Centroid($feature)
Buffer($feature, 100, "meters")
Intersects($feature, $otherFeature)
Contains($feature, $point)
条件関数
// IIf (inline if)
IIf($feature.value > 100, "High", "Low")
// When (multiple conditions)
When(
$feature.type == "A", "Type A",
$feature.type == "B", "Type B",
"Other"
)
// Decode (value matching)
Decode($feature.code,
1, "One",
2, "Two",
3, "Three",
"Unknown"
)
配列関数
var arr = [1, 2, 3, 4, 5];
Count(arr) // 5
First(arr) // 1
Last(arr) // 5
IndexOf(arr, 3) // 2
Includes(arr, 3) // true
Push(arr, 6) // [1, 2, 3, 4, 5, 6]
Reverse(arr) // [5, 4, 3, 2, 1]
Sort(arr) // [1, 2, 3, 4, 5]
Slice(arr, 1, 3) // [2, 3]
フィーチャーへのアクセス
// Current feature
$feature.fieldName
// All features in layer (for aggregation)
var allFeatures = FeatureSet($layer);
var filtered = Filter(allFeatures, "type = 'A'");
var total = Sum(filtered, "value");
// Related records
var related = FeatureSetByRelationshipName($feature, "relationshipName");
// Global variables
$map // Reference to map
$view // Reference to view
$datastore // Reference to data store
Arcade をプログラムから実行する
import * as arcade from "@arcgis/core/arcade.js";
// Create profile
const profile = {
variables: [
{
name: "$feature",
type: "feature",
},
],
};
// Compile expression
const executor = await arcade.createArcadeExecutor(
"Round($feature.value * 100, 2)",
profile,
);
// Execute with feature
const result = await executor.executeAsync({
$feature: graphic,
});
console.log("Result:", result);
Note: v5.0 では、
ExecuteContext.lruCacheは非推奨です。代わりにExecuteContext.cacheを使用してください。
HTML(スクリプトタグ)での Arcade
<script type="text/plain" id="my-expression">
var total = $feature.value_a + $feature.value_b;
var percentage = Round((total / $feature.max_value) * 100, 1);
return percentage + "%";
</script>
<script type="module">
const expression = document.getElementById("my-expression").text;
const popupTemplate = {
expressionInfos: [
{
name: "my-calc",
expression: expression,
},
],
content: "Value: {expression/my-calc}",
};
</script>
Arcade 式のプロファイル
Arcade のプロファイルによって、公開されるグローバル変数や関数は異なります。
| プロファイル | グローバル変数 | 用途 |
|---|---|---|
popup | $feature、$layer、$map、$datastore | ポップアップコンテンツ |
visualization | $feature、$view | レンダラー、視覚変数 |
labeling | $feature、$view | ラベル式 |
field-calculate | $feature、$layer | フィールド計算 |
form-calculation | $feature、$layer、$originalFeature | フォームの計算式 |
constraint | $feature、$layer、$originalFeature | フォームの検証 |
alias | $feature、$layer | クラスターポップアップのエイリアス |
参考サンプル
popuptemplate-arcade- PopupTemplates での Arcade 式popuptemplate-arcade-expression-content- ポップアップ内の Arcade 式コンテンツvisualization-arcade- Arcade による可視化arcade-execute-chart- チャートでの Arcade の実行
よくある落とし穴
-
Null 値:算術演算を行う前に、
IsEmpty($feature.field)で必ず Null 値を確認してください。Null 値を除算したり加算したりすると、結果も Null になります。// Anti-pattern: no null check return $feature.population / $feature.area;// Correct: check for null if (IsEmpty($feature.area) || $feature.area == 0) { return "N/A"; } return Round($feature.population / $feature.area, 2); -
型変換:型が混在する場合は、
Number()またはText()を使用して明示的に変換してください。 -
大文字と小文字の区別:Arcade の関数名は大文字と小文字を区別しませんが、フィールド名はソースデータと完全に一致させる必要があります。
-
パフォーマンス:レンダラーやラベルの複雑な式は、フィーチャーごと、フレームごとに評価されます。大規模なデータセットでは、式をシンプルにしてください。
-
デバッグ:式のデバッグには
Console()関数を使用してください。出力はブラウザーの開発者コンソールに表示されます。 -
FeatureSet クエリ:
FeatureSet()とFilter()はサーバーサイドのクエリを実行します。レイヤーに多数のフィーチャーがある場合、ポップアップ式内では処理が遅くなることがあります。
関連スキル
- ポップアップテンプレートの設定については
arcgis-popup-templatesを参照してください - レンダラーとシンボルの設定については
arcgis-visualizationを参照してください - データ駆動型の可視化については
arcgis-smart-mappingを参照してください <arcgis-arcade-editor>コンポーネントについてはarcgis-coding-componentsを参照してください