mcpField
A
arcgis-arcade

arcgis-arcade

github.com/saschabrunnerchデータ・データベース2360 回インストール29 週間前に更新
リポジトリ

arcgis-arcade について

arcgis-arcade は、ArcGIS の Arcade 式を作成するためのスキルです。ポップアップ、レンダラー、ラベル、計算を設定する開発者向けに、式の例や実行方法、注意点をまとめています。

主な機能

  1. 01ポップアップ式
  2. 02レンダラーと可視化の式
  3. 03ラベルとフィールド計算
  4. 04Arcade 関数の例
  5. 05プログラム実行とデバッグ

活用シーン

  1. 01動的なポップアップ内容の作成
  2. 02データに基づくフィーチャ描画
  3. 03カスタム地図ラベルの定義
  4. 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 の実行

よくある落とし穴

  1. 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);
    
  2. 型変換:型が混在する場合は、Number() または Text() を使用して明示的に変換してください。

  3. 大文字と小文字の区別:Arcade の関数名は大文字と小文字を区別しませんが、フィールド名はソースデータと完全に一致させる必要があります。

  4. パフォーマンス:レンダラーやラベルの複雑な式は、フィーチャーごと、フレームごとに評価されます。大規模なデータセットでは、式をシンプルにしてください。

  5. デバッグ:式のデバッグには Console() 関数を使用してください。出力はブラウザーの開発者コンソールに表示されます。

  6. FeatureSet クエリ:FeatureSet() と Filter() はサーバーサイドのクエリを実行します。レイヤーに多数のフィーチャーがある場合、ポップアップ式内では処理が遅くなることがあります。

関連スキル

  • ポップアップテンプレートの設定については arcgis-popup-templates を参照してください
  • レンダラーとシンボルの設定については arcgis-visualization を参照してください
  • データ駆動型の可視化については arcgis-smart-mapping を参照してください
  • <arcgis-arcade-editor> コンポーネントについては arcgis-coding-components を参照してください

コメント