mcpField
A
arcgis-map-tools

arcgis-map-tools

github.com/saschabrunnerch開発2365 回インストール29 週間前に更新
リポジトリ

arcgis-map-tools について

arcgis-map-tools は、ArcGIS Maps SDK for JavaScript で地図 UI を構築するための開発スキルです。地図の操作、計測、ルート検索、エクスポートの実装例を扱います。

主な機能

  1. 01レイヤーのスワイプ比較
  2. 022D・3D の距離と面積の計測
  3. 03座標変換とブックマーク
  4. 04ルート案内とプログラムによる経路検索
  5. 05地図の印刷とスクリーンショット出力
  6. 06標高プロファイルとフィーチャの識別

活用シーン

  1. 01地図レイヤーをインタラクティブに比較
  2. 02地図に計測・座標ツールを追加
  3. 03ルート案内と地図フィーチャの確認
  4. 04レポートや共有用に地図を出力

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/saschabrunnerch/arcgis-maps-sdk-js-ai-context --skill arcgis-map-tools

インストール後、Claude Code で/arcgis-map-toolsを入力して読み込まれたか確認します。

詳細

ArcGIS マップツール

スワイプ比較、計測ツール、座標変換、ブックマーク、印刷、ルート検索、フィーチャの識別にこのスキルを使用します。

インポートパターン

ESM の直接インポート
import Measurement from "@arcgis/core/widgets/Measurement.js";
import DistanceMeasurement2D from "@arcgis/core/widgets/DistanceMeasurement2D.js";
import AreaMeasurement2D from "@arcgis/core/widgets/AreaMeasurement2D.js";
import Print from "@arcgis/core/widgets/Print.js";
import Directions from "@arcgis/core/widgets/Directions.js";
import * as route from "@arcgis/core/rest/route.js";
import * as identify from "@arcgis/core/rest/identify.js";
import * as print from "@arcgis/core/rest/print.js";
動的インポート(CDN)
const Measurement = await $arcgis.import("@arcgis/core/widgets/Measurement.js");
const Print = await $arcgis.import("@arcgis/core/widgets/Print.js");
const [route, RouteParameters] = await $arcgis.import([
  "@arcgis/core/rest/route.js",
  "@arcgis/core/rest/support/RouteParameters.js",
]);

スワイプウィジェット

レイヤー間をスワイプして比較します。

スワイプコンポーネント
<arcgis-map zoom="15" center="-154.88, 19.46">
  <arcgis-zoom slot="top-left"></arcgis-zoom>
  <arcgis-swipe swipe-position="32"></arcgis-swipe>
</arcgis-map>

<script type="module">
  import Map from "@arcgis/core/Map.js";
  import TileLayer from "@arcgis/core/layers/TileLayer.js";

  const viewElement = document.querySelector("arcgis-map");
  const arcgisSwipe = document.querySelector("arcgis-swipe");

  const layer1 = new TileLayer({ url: "..." });
  const layer2 = new TileLayer({ url: "..." });

  viewElement.map = new Map({
    basemap: "satellite",
    layers: [layer1, layer2],
  });

  // Configure swipe when ready
  arcgisSwipe.addEventListener("arcgisPropertyChange", (e) => {
    if (e.detail.name === "state" && arcgisSwipe.state === "ready") {
      arcgisSwipe.leadingLayers.add(layer1);
      arcgisSwipe.trailingLayers.add(layer2);
    }
  });
</script>
スワイプウィジェット(コア API)
import Swipe from "@arcgis/core/widgets/Swipe.js";

const swipe = new Swipe({
  view: view,
  leadingLayers: [layer1],
  trailingLayers: [layer2],
  position: 50,
  direction: "horizontal", // or "vertical"
});

view.ui.add(swipe);

計測

計測コンポーネント

<arcgis-map>
  <arcgis-distance-measurement-2d
    slot="top-right"
  ></arcgis-distance-measurement-2d>
  <arcgis-area-measurement-2d slot="top-right"></arcgis-area-measurement-2d>
</arcgis-map>


<arcgis-scene>
  <arcgis-direct-line-measurement-3d
    slot="top-right"
  ></arcgis-direct-line-measurement-3d>
  <arcgis-area-measurement-3d slot="top-right"></arcgis-area-measurement-3d>
</arcgis-scene>
計測ウィジェット(コア API)
import Measurement from "@arcgis/core/widgets/Measurement.js";

const measurement = new Measurement({ view: view });
view.ui.add(measurement, "bottom-right");

// Activate distance measurement
measurement.activeTool = view.type === "2d" ? "distance" : "direct-line";

// Activate area measurement
measurement.activeTool = "area";

// Clear measurements
measurement.clear();
2D 計測ウィジェット(コア API)
import DistanceMeasurement2D from "@arcgis/core/widgets/DistanceMeasurement2D.js";
import AreaMeasurement2D from "@arcgis/core/widgets/AreaMeasurement2D.js";

const distanceWidget = new DistanceMeasurement2D({
  view: view,
  unit: "kilometers",
});
view.ui.add(distanceWidget, "top-right");

const areaWidget = new AreaMeasurement2D({
  view: view,
  unit: "square-kilometers",
});
view.ui.add(areaWidget, "top-right");
3D 計測ウィジェット(コア API)
import DirectLineMeasurement3D from "@arcgis/core/widgets/DirectLineMeasurement3D.js";
import AreaMeasurement3D from "@arcgis/core/widgets/AreaMeasurement3D.js";

const lineWidget = new DirectLineMeasurement3D({
  view: sceneView,
  unit: "meters",
});

const areaWidget = new AreaMeasurement3D({
  view: sceneView,
  unit: "square-meters",
});

座標変換

座標変換コンポーネント
<arcgis-map basemap="satellite" center="-117.195, 34.057" zoom="13">
  <arcgis-coordinate-conversion
    slot="bottom-left"
  ></arcgis-coordinate-conversion>
</arcgis-map>
座標変換ウィジェット(コア API)
import CoordinateConversion from "@arcgis/core/widgets/CoordinateConversion.js";

const ccWidget = new CoordinateConversion({ view: view });
view.ui.add(ccWidget, "bottom-left");

ブックマーク

ブックマークコンポーネント
<arcgis-map item-id="YOUR_WEBMAP_ID">
  <arcgis-expand slot="top-right" expand-tooltip="Bookmarks">
    <arcgis-bookmarks></arcgis-bookmarks>
  </arcgis-expand>
</arcgis-map>
ブックマークウィジェット(コア API)
import Bookmarks from "@arcgis/core/widgets/Bookmarks.js";

const bookmarks = new Bookmarks({
  view: view,
  editingEnabled: true,
  visibleElements: {
    addBookmarkButton: true,
    editBookmarkButton: true,
  },
});

view.ui.add(bookmarks, "top-right");

ルート案内ウィジェット

ルート案内コンポーネント
<arcgis-map>
  <arcgis-directions slot="top-right"></arcgis-directions>
</arcgis-map>
ルート案内ウィジェット(コア API)
import Directions from "@arcgis/core/widgets/Directions.js";

const directions = new Directions({
  view: view,
});

view.ui.add(directions, "top-right");

ルート検索(プログラムによる実行)

基本的なルート
import * as route from "@arcgis/core/rest/route.js";
import RouteParameters from "@arcgis/core/rest/support/RouteParameters.js";
import FeatureSet from "@arcgis/core/rest/support/FeatureSet.js";
import Graphic from "@arcgis/core/Graphic.js";
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";

const routeUrl =
  "https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";

const routeLayer = new GraphicsLayer();
map.add(routeLayer);

const routeParams = new RouteParameters({
  apiKey: "YOUR_API_KEY",
  stops: new FeatureSet(),
  outSpatialReference: { wkid: 3857 },
});

// Add stop on click
view.on("click", async (event) => {
  const stop = new Graphic({
    geometry: event.mapPoint,
    symbol: {
      type: "simple-marker",
      style: "cross",
      size: 15,
    },
  });
  routeLayer.add(stop);
  routeParams.stops.features.push(stop);

  if (routeParams.stops.features.length >= 2) {
    const result = await route.solve(routeUrl, routeParams);
    const routeResult = result.routeResults[0].route;
    routeResult.symbol = {
      type: "simple-line",
      color: [0, 0, 255, 0.5],
      width: 5,
    };
    routeLayer.add(routeResult);
  }
});
ルート案内付きのルート
const routeParams = new RouteParameters({
  apiKey: "YOUR_API_KEY",
  stops: new FeatureSet({ features: stopGraphics }),
  returnDirections: true,
  directionsLanguage: "en",
  returnRoutes: true,
  returnStops: true,
  impedanceAttribute: "TravelTime",
  outSpatialReference: { wkid: 4326 },
});

const result = await route.solve(routeUrl, routeParams);

const directions = result.routeResults[0].directions;
directions.features.forEach((feature) => {
  console.log(feature.attributes.text);
});

印刷

印刷コンポーネント
<arcgis-map item-id="YOUR_WEBMAP_ID">
  <arcgis-expand slot="top-right" expand-tooltip="Print">
    <arcgis-print></arcgis-print>
  </arcgis-expand>
</arcgis-map>
印刷ウィジェット(コア API)
import Print from "@arcgis/core/widgets/Print.js";

const print = new Print({
  view: view,
  printServiceUrl:
    "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task",
  allowedFormats: ["pdf", "png32", "jpg"],
  allowedLayouts: ["a4-landscape", "a4-portrait", "letter-ansi-a-landscape"],
  templateOptions: {
    title: "Default Map Title",
    author: "Default Author",
  },
});

view.ui.add(print, "top-right");
印刷サービス(プログラムによる実行)
import * as print from "@arcgis/core/rest/print.js";
import PrintTemplate from "@arcgis/core/rest/support/PrintTemplate.js";
import PrintParameters from "@arcgis/core/rest/support/PrintParameters.js";

const printUrl =
  "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";

const template = new PrintTemplate({
  format: "pdf", // pdf, png32, png8, jpg, gif, eps, svg, svgz
  layout: "a4-landscape", // Or custom layout name
  exportOptions: { dpi: 300 },
  layoutOptions: {
    titleText: "My Map",
    authorText: "Author Name",
    copyrightText: "Copyright 2025",
    scalebarUnit: "Kilometers",
  },
});

const params = new PrintParameters({
  view: view,
  template: template,
});

const result = await print.execute(printUrl, params);
console.log("PDF URL:", result.url);
印刷形式
形式説明
pdfAdobe PDF
png32透明度付き PNG(32 ビット)
png8PNG 8 ビット
jpgJPEG
gifGIF
epsEncapsulated PostScript
svgScalable Vector Graphics
svgz圧縮 SVG
マップのみのエクスポート(レイアウトなし)
const template = new PrintTemplate({
  format: "png32",
  layout: "map-only",
  exportOptions: {
    width: 1920,
    height: 1080,
    dpi: 96,
  },
});
代替手段としてのスクリーンショット

印刷サービスを使わずにすばやくエクスポートするには:

const screenshot = await view.takeScreenshot({
  format: "png",
  width: 1920,
  height: 1080,
  quality: 90,
});

// Download
const link = document.createElement("a");
link.download = "map-screenshot.png";
link.href = screenshot.dataUrl;
link.click();

標高プロファイル

標高プロファイルコンポーネント
<arcgis-scene>
  <arcgis-elevation-profile slot="top-right"></arcgis-elevation-profile>
</arcgis-scene>
標高プロファイルウィジェット(コア API)
import ElevationProfile from "@arcgis/core/widgets/ElevationProfile.js";

const elevationProfile = new ElevationProfile({
  view: view,
  profiles: [{ type: "ground" }, { type: "view" }],
});

view.ui.add(elevationProfile, "top-right");

識別

MapImageLayer 上での識別
import * as identify from "@arcgis/core/rest/identify.js";
import IdentifyParameters from "@arcgis/core/rest/support/IdentifyParameters.js";

const identifyURL =
  "https://sampleserver6.arcgisonline.com/arcgis/rest/services/MtBaldy_BaseMap/MapServer";

const params = new IdentifyParameters({
  tolerance: 3,
  layerIds: [0, 1, 2, 3, 4],
  layerOption: "top", // "top", "visible", "all"
  width: view.width,
  height: view.height,
});

view.on("click", async (event) => {
  params.geometry = event.mapPoint;
  params.mapExtent = view.extent;

  const response = await identify.identify(identifyURL, params);

  const features = response.results.map((result) => {
    const feature = result.feature;
    feature.attributes.layerName = result.layerName;
    feature.popupTemplate = {
      title: result.layerName,
      content: "{*}",
    };
    return feature;
  });

  if (features.length > 0) {
    view.openPopup({
      features: features,
      location: event.mapPoint,
    });
  }
});

検索

検索サービス
import * as find from "@arcgis/core/rest/find.js";
import FindParameters from "@arcgis/core/rest/support/FindParameters.js";

const findUrl =
  "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer";

const params = new FindParameters({
  searchText: "California",
  layerIds: [0, 1, 2],
  searchFields: ["STATE_NAME", "NAME"],
  returnGeometry: true,
});

const result = await find.find(findUrl, params);

result.results.forEach((r) => {
  console.log(r.feature.attributes);
});

参考サンプル

  • widgets-measurement - 距離と面積の計測ツール
  • widgets-measurement-3d - 3D 計測ツール
  • widgets-print - マップのエクスポート用印刷ウィジェット
  • widgets-directions - ルート検索用ルート案内ウィジェット
  • swipe - レイヤー比較用スワイプウィジェット
  • coordinate-conversion - 座標変換ユーティリティ
  • bookmarks - ブックマークナビゲーション
  • elevation-profile - 標高プロファイルウィジェット

よくある落とし穴

  1. ルート検索の API キー:ルートサービスには、有効な API キーまたは認証済みユーザーが必要です。

  2. 識別の許容値:ズームレベルに応じて適切な許容値を設定してください。ズームレベルが高いときに許容値が低いと、フィーチャを見逃す場合があります。

  3. スワイプレイヤーの順序:先行レイヤーと後続レイヤーは、スワイプウィジェットに割り当てる前にマップのレイヤーコレクションに含める必要があります。

  4. 計測単位:2D ビューと 3D ビューでは、異なる計測ウィジェットを使用してください。統合された Measurement ウィジェットは、view.type に基づいて自動的に選択します。

  5. 印刷サービスの URL:デフォルトの Esri 印刷サービス URL には認証が必要な場合があります。カスタム印刷サービスでは、独自の URL を設定する必要があります。

  6. マップ内の座標変換:スロットを指定して <arcgis-map> の子として配置するか、外部に配置する場合は reference-element を使用する必要があります。

関連スキル

  • 基本的な UI ウィジェットと Calcite レイアウトについては、arcgis-widgets-ui を参照してください
  • 専門的なウィジェットについては、arcgis-widgets-advanced を参照してください
  • REST API のクエリおよび解析ツールについては、arcgis-rest-services を参照してください
  • サーバー側の解析操作については、arcgis-spatial-analysis を参照してください

コメント