arcgis-layers について
ArcGIS Maps SDK for JavaScript で地図を開発する人向けのレイヤー操作ガイドです。多様なデータソースとレイヤーの設定、管理、フィーチャクエリに加え、3D やストリーミングレイヤーも扱います。
主な機能
- 01多様な ArcGIS レイヤー型の例
- 02URL や Portal アイテムからの設定
- 03レイヤーの追加、削除、並べ替え、スタイル設定
- 04属性と空間フィーチャのクエリ
- 053D、画像、ストリーミングデータの読み込み
活用シーン
- 01地図への GeoJSON や CSV データの追加
- 02属性や範囲によるフィーチャの絞り込みと検索
- 03レイヤーの表示状態と順序の管理
- 043D またはリアルタイム地図データの表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-layersインストール後、Claude Code で/arcgis-layersを入力して読み込まれたか確認します。
同梱ファイルAGENTS.md
詳細
ArcGIS レイヤー
ArcGIS マップでデータレイヤーを追加、設定、またはクエリする際に、このスキルを使用してください。
インポートパターン
ESM による直接インポート
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
import GeoJSONLayer from "@arcgis/core/layers/GeoJSONLayer.js";
動的インポート(CDN)
const FeatureLayer = await $arcgis.import(
"@arcgis/core/layers/FeatureLayer.js",
);
const [GraphicsLayer, Graphic] = await $arcgis.import([
"@arcgis/core/layers/GraphicsLayer.js",
"@arcgis/core/Graphic.js",
]);
レイヤータイプの概要
| レイヤータイプ | 用途 | ジオメトリ |
|---|---|---|
| FeatureLayer | 最も一般的 — フィーチャサービス、編集可能なデータ | ポイント、ライン、ポリゴン |
| GraphicsLayer | クライアント側の一時的なグラフィックス | 任意 |
| GeoJSONLayer | GeoJSON ファイル/URL | ポイント、ライン、ポリゴン |
| CSVLayer | 座標を含む CSV ファイル | ポイント |
| TileLayer | キャッシュされたマップタイル | ラスター |
| VectorTileLayer | ベクタータイル(Mapbox スタイル) | ベクター |
| ImageryTileLayer | ラスター画像 | ラスター |
| SceneLayer | 3D 建物、メッシュ | 3D オブジェクト |
| IntegratedMeshLayer | 写真測量メッシュ | 3D メッシュ |
| PointCloudLayer | LiDAR 点群 | ポイント |
| ParquetLayer | Apache Parquet ファイル | ポイント、ライン、ポリゴン |
| StreamLayer | リアルタイムの WebSocket データ | ポイント、ライン、ポリゴン |
FeatureLayer
URL から
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0",
outFields: ["*"],
popupTemplate: {
title: "{Tree_ID}",
content: "Height: {Crown_Height} ft",
},
});
map.add(featureLayer);
ポータルアイテムから
const featureLayer = new FeatureLayer({
portalItem: {
id: "51c851fef66143959986b473b345b7ca",
},
outFields: ["*"],
});
クライアント側(メモリ内)
const featureLayer = new FeatureLayer({
source: graphics, // Array of Graphic objects
fields: [
{ name: "ObjectID", type: "oid" },
{ name: "name", type: "string" },
{ name: "value", type: "double" },
],
objectIdField: "ObjectID",
geometryType: "point",
spatialReference: { wkid: 4326 },
renderer: {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
},
});
設定オプション
const featureLayer = new FeatureLayer({
url: "...",
outFields: ["*"], // Fields to include (* = all)
definitionExpression: "population > 10000", // SQL filter
minScale: 500000, // Hide when zoomed out beyond this
maxScale: 0, // Hide when zoomed in beyond this
visible: true, // Initial visibility
opacity: 0.8, // Transparency (0-1)
title: "Cities", // Display name
blendMode: "normal", // Blend mode for compositing
orderBy: [{ field: "population" }], // Feature draw order
featureReduction: null, // Clustering / binning config
labelingInfo: [...], // Labels
renderer: {...}, // Symbology
popupTemplate: {...}, // Popup configuration
elevationInfo: { // 3D elevation mode
mode: "relative-to-ground"
}
});
GraphicsLayer
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
import Graphic from "@arcgis/core/Graphic.js";
const graphicsLayer = new GraphicsLayer();
map.add(graphicsLayer);
// Add a point
const pointGraphic = new Graphic({
geometry: {
type: "point",
longitude: -118.24,
latitude: 34.05,
},
symbol: {
type: "simple-marker",
color: "red",
size: 12,
},
attributes: { name: "Los Angeles" },
popupTemplate: { title: "{name}" },
});
graphicsLayer.add(pointGraphic);
// Add multiple graphics
graphicsLayer.addMany([graphic1, graphic2, graphic3]);
// Remove graphics
graphicsLayer.remove(pointGraphic);
graphicsLayer.removeAll();
GeoJSONLayer
import GeoJSONLayer from "@arcgis/core/layers/GeoJSONLayer.js";
const geojsonLayer = new GeoJSONLayer({
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson",
copyright: "USGS Earthquakes",
popupTemplate: {
title: "Earthquake Info",
content: "Magnitude {mag} hit {place} on {time}",
fieldInfos: [
{
fieldName: "time",
format: { dateFormat: "short-date-short-time" },
},
],
},
renderer: {
type: "simple",
symbol: { type: "simple-marker", color: "orange" },
visualVariables: [
{
type: "size",
field: "mag",
stops: [
{ value: 2.5, size: "4px" },
{ value: 8, size: "40px" },
],
},
],
},
orderBy: [{ field: "mag" }], // Draw smaller on top
});
map.add(geojsonLayer);
CSVLayer
import CSVLayer from "@arcgis/core/layers/CSVLayer.js";
const csvLayer = new CSVLayer({
url: "https://example.com/data.csv",
latitudeField: "latitude", // Column name for lat
longitudeField: "longitude", // Column name for lon
delimiter: ",",
popupTemplate: {
title: "{name}",
content: "{description}",
},
});
TileLayer(キャッシュされたタイル)
import TileLayer from "@arcgis/core/layers/TileLayer.js";
const tileLayer = new TileLayer({
url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
});
map.add(tileLayer);
VectorTileLayer
import VectorTileLayer from "@arcgis/core/layers/VectorTileLayer.js";
// From portal item
const vtl = new VectorTileLayer({
portalItem: { id: "VECTOR_TILE_ITEM_ID" },
});
// From URL
const vtl2 = new VectorTileLayer({
url: "https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer",
});
ImageryTileLayer
import ImageryTileLayer from "@arcgis/core/layers/ImageryTileLayer.js";
const imageryLayer = new ImageryTileLayer({
url: "https://tiledimageservices.arcgis.com/...",
});
// From Cloud Optimized GeoTIFF (COG)
const cogLayer = new ImageryTileLayer({
url: "https://example.com/image.tif",
});
3D レイヤー
SceneLayer(3D 建物)
import SceneLayer from "@arcgis/core/layers/SceneLayer.js";
const sceneLayer = new SceneLayer({
portalItem: { id: "2e0761b9a4274b8db52c4bf34356911e" },
popupEnabled: false,
});
// Add to SceneView map
map.add(sceneLayer);
// Custom 3D symbology
sceneLayer.renderer = {
type: "simple",
symbol: {
type: "mesh-3d",
symbolLayers: [
{
type: "fill",
material: { color: [244, 247, 134] },
},
],
},
};
IntegratedMeshLayer
import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";
const meshLayer = new IntegratedMeshLayer({
url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer",
});
PointCloudLayer
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";
const pcLayer = new PointCloudLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
});
特殊なレイヤー
WMS、WFS、KML、MapImageLayer、CatalogLayer については、
arcgis-advanced-layersを参照してください。
StreamLayer(リアルタイム)
import StreamLayer from "@arcgis/core/layers/StreamLayer.js";
const streamLayer = new StreamLayer({
url: "wss://example.com/stream/service",
purgeOptions: {
displayCount: 10000,
},
});
ParquetLayer(ファイルベース)
import ParquetLayer from "@arcgis/core/layers/ParquetLayer.js";
const parquetLayer = new ParquetLayer({
urls: ["https://example.com/data.parquet"],
title: "Parquet Data",
renderer: {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
},
popupTemplate: {
title: "{name}",
content: [
{
type: "fields",
fieldInfos: [{ fieldName: "field1", label: "Field 1" }],
},
],
},
});
// Query feature count
const count = await parquetLayer.queryFeatureCount();
GeoRSSLayer
import GeoRSSLayer from "@arcgis/core/layers/GeoRSSLayer.js";
const georssLayer = new GeoRSSLayer({
url: "https://example.com/feed.xml",
});
map.add(georssLayer);
// Zoom to layer extent
await view.whenLayerView(georssLayer);
view.goTo(georssLayer.fullExtent);
WebTileLayer
import WebTileLayer from "@arcgis/core/layers/WebTileLayer.js";
// OpenStreetMap tiles
const osmLayer = new WebTileLayer({
urlTemplate: "https://{subDomain}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subDomains: ["a", "b", "c"],
copyright: "OpenStreetMap contributors",
});
// Custom tile service
const customTileLayer = new WebTileLayer({
urlTemplate: "https://tiles.example.com/{level}/{col}/{row}.png",
});
map.add(osmLayer);
MapNotesLayer
import MapNotesLayer from "@arcgis/core/layers/MapNotesLayer.js";
// Layer for sketches and annotations
const notesLayer = new MapNotesLayer();
map.add(notesLayer);
// Access sublayers
const pointLayer = notesLayer.pointLayer;
const polylineLayer = notesLayer.polylineLayer;
const polygonLayer = notesLayer.polygonLayer;
const textLayer = notesLayer.textLayer;
// Add a text annotation
const textGraphic = new Graphic({
geometry: point,
symbol: {
type: "text",
text: "Note here",
color: [255, 255, 255],
haloColor: [0, 0, 0],
haloSize: 2,
font: { family: "Arial", size: 14 },
},
});
textLayer.add(textGraphic);
レイヤーの管理
レイヤーの追加
// Add single layer
map.add(layer);
// Add at specific index (0 = bottom)
map.add(layer, 0);
// Add multiple layers
map.addMany([layer1, layer2, layer3]);
// Add to Map Component
const viewElement = document.querySelector("arcgis-map");
viewElement.map.add(layer);
レイヤーの削除
map.remove(layer);
map.removeMany([layer1, layer2]);
map.removeAll();
レイヤーの順序
// Reorder layer
map.reorder(layer, newIndex);
// Get layer position
const index = map.layers.indexOf(layer);
// Find layer by id
const layer = map.findLayerById("myLayerId");
// Find layer by title
const layer = map.layers.find((l) => l.title === "Cities");
表示設定と不透明度
layer.visible = false;
layer.opacity = 0.5; // 0-1
// Watch visibility changes
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
reactiveUtils.watch(
() => layer.visible,
(newValue) => console.log("Visibility changed:", newValue),
);
フィーチャのクエリ
基本的なクエリ
// Create query from layer settings
const query = featureLayer.createQuery();
query.where = "population > 100000";
query.outFields = ["name", "population"];
query.returnGeometry = true;
const result = await featureLayer.queryFeatures(query);
console.log(result.features); // Array of Graphic objects
ページネーションを使用したクエリ
const query = featureLayer.createQuery();
query.start = 0; // Start index
query.num = 20; // Number of features
query.orderByFields = ["population DESC"];
const result = await featureLayer.queryFeatures(query);
空間クエリ
const query = featureLayer.createQuery();
query.geometry = view.extent; // Or any geometry
query.spatialRelationship = "intersects"; // contains, crosses, etc.
query.returnGeometry = true;
const result = await featureLayer.queryFeatures(query);
件数クエリ
const count = await featureLayer.queryFeatureCount();
console.log("Total features:", count);
範囲クエリ
const result = await featureLayer.queryExtent();
console.log("Feature count:", result.count);
await view.goTo(result.extent);
統計クエリ
const query = featureLayer.createQuery();
query.outStatistics = [
{
statisticType: "sum",
onStatisticField: "population",
outStatisticFieldName: "totalPop",
},
{
statisticType: "avg",
onStatisticField: "population",
outStatisticFieldName: "avgPop",
},
];
const result = await featureLayer.queryFeatures(query);
console.log(result.features[0].attributes.totalPop);
LayerView からのクエリ(クライアント側)
const layerView = await view.whenLayerView(featureLayer);
// Query only currently visible features
const query = layerView.createQuery();
query.geometry = view.extent;
const result = await layerView.queryFeatures(query);
クエリメソッドのリファレンス
| メソッド | 戻り値 | 使用する場面 |
|---|---|---|
queryFeatures(query) | FeatureSet(グラフィックス) | 実際のフィーチャデータが必要な場合 |
queryObjectIds(query) | number[](OID) | ハイライト表示用に ID だけが必要な場合 |
queryFeatureCount(query) | number | データを取得せずに件数が必要な場合 |
queryExtent(query) | { count, extent } | 一致するフィーチャにズームしたい場合 |
queryRelatedFeatures(params) | 関連フィーチャセット | 関連するテーブルレコードが必要な場合 |
queryAttachments(params) | AttachmentInfo[] | ファイル添付が必要な場合 |
サーバー側クエリとクライアント側クエリ
| 項目 | featureLayer.queryFeatures() | layerView.queryFeatures() |
|---|---|---|
| 実行場所 | サーバー | クライアント(ブラウザー) |
| データ範囲 | サービス内のすべてのフィーチャ | ビュー/キャッシュ内のフィーチャのみ |
| ネットワークコスト | 呼び出しごとに HTTP リクエスト | ネットワーク通信なし(読み込み済み) |
| 使用する場面 | 全データセット、ページネーション、統計情報が必要な場合 | 表示中のフィーチャを素早くフィルタリングする場合 |
レイヤーの読み込み
// Wait for layer to load
await featureLayer.load();
console.log("Fields:", featureLayer.fields);
console.log("Extent:", featureLayer.fullExtent);
// Wait for layer view
const layerView = await view.whenLayerView(featureLayer);
// Check if updating
reactiveUtils.watch(
() => layerView.updating,
(updating) => {
if (!updating) {
console.log("Layer view finished updating");
}
},
);
定義式(フィルター)
// SQL WHERE clause filter
featureLayer.definitionExpression = "state = 'California'";
// Clear filter
featureLayer.definitionExpression = null;
// Dynamic filter
function filterByYear(year) {
featureLayer.definitionExpression = `year = ${year}`;
}
TypeScript の使用方法
type プロパティを持つレイヤー設定では、自動型変換がサポートされています。TypeScript で型安全性を確保するには、as const を使用します。
// Use 'as const' for type safety
const featureLayer = new FeatureLayer({
source: graphics,
fields: [
{ name: "ObjectID", type: "oid" },
{ name: "name", type: "string" },
],
geometryType: "point",
renderer: {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
} as const,
});
複雑なレイヤー設定では、型注釈を使用します。
const renderer: __esri.SimpleRendererProperties = {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
};
layer.renderer = renderer;
ヒント: 自動型変換と明示的なクラスの使い分けについて詳しくは、
arcgis-core-mapsを参照してください。
参考サンプル
intro-layers- レイヤーの操作方法の紹介layers-featurelayer- FeatureLayer の設定と使用方法layers-geojson- GeoJSON データをレイヤーとして読み込む方法featurelayer-query- FeatureLayer のフィーチャをクエリする方法get-started-graphics- Graphics と GraphicsLayer の操作方法
関連スキル
- マップとビューの設定については、
arcgis-core-mapsを参照してください。 - レンダラー、シンボル、視覚変数については、
arcgis-visualizationを参照してください。 - ポップアップの設定については、
arcgis-popup-templatesを参照してください。 - applyEdits を使用したフィーチャの編集については、
arcgis-editingを参照してください。 - WMS、WFS、KML、MapImageLayer、CatalogLayer については、
arcgis-advanced-layersを参照してください。 - 3D 固有のレイヤー設定については、
arcgis-3d-layersを参照してください。
よくある落とし穴
-
GeoJSON の CORS エラー:GeoJSON の URL では CORS が有効になっている必要があります。有効でない場合は、プロキシを使用してください。
-
outFields の指定漏れ:
outFieldsが指定されていない場合、クエリは属性値を返しません。// Anti-pattern: querying without outFields const results = await featureLayer.queryFeatures({ where: "population > 100000", returnGeometry: true, }); console.log(results.features[0].attributes.name); // undefined// Correct: specify outFields to include desired attributes const results = await featureLayer.queryFeatures({ where: "population > 100000", returnGeometry: true, outFields: ["name", "population", "state"], }); console.log(results.features[0].attributes.name); // "Los Angeles"影響: フィーチャの属性が
undefinedまたはnullとして返されます。クエリは成功しますが、レスポンスに使用可能な属性データが含まれないため、気づきにくいデータの不具合につながります。 -
レイヤーの読み込みを待たない:レイヤーのメタデータ(フィールド、範囲、レンダラー)は、レイヤーの読み込みが完了するまで使用できません。
// Anti-pattern: accessing properties before load const layer = new FeatureLayer({ url: "https://services.arcgis.com/.../FeatureServer/0", }); console.log(layer.fields); // null - layer has not loaded yet console.log(layer.fullExtent); // null// Correct: await layer.load() first const layer = new FeatureLayer({ url: "https://services.arcgis.com/.../FeatureServer/0", }); await layer.load(); console.log(layer.fields); // Array of Field objects console.log(layer.fullExtent); // Extent object影響:
fieldsがnullまたは空の配列になり、fullExtentがnullになります。また、レイヤーのメタデータに依存するコードがエラーをスローするか、何も通知せずに失敗します。 -
MapView と SceneView に対するレイヤーの選択ミス:一部のレイヤー(SceneLayer、IntegratedMeshLayer、PointCloudLayer)は 3D でのみ動作します。
-
空間参照の不一致:投影サポートがない状態で、ビューとは異なる空間参照を持つレイヤーを追加すると発生します。
// Anti-pattern: adding a layer in a different SR without handling projection const view = new MapView({ spatialReference: { wkid: 4326 }, // WGS84 }); const layer = new FeatureLayer({ url: "https://services.arcgis.com/.../FeatureServer/0", // Data in Web Mercator (3857) }); view.map.add(layer); // Features may render in wrong location// Correct: match spatial references or load the projection engine import * as projection from "@arcgis/core/geometry/projection.js"; await projection.load(); const view = new MapView({ spatialReference: { wkid: 4326 }, }); const layer = new FeatureLayer({ url: "https://services.arcgis.com/.../FeatureServer/0", }); view.map.add(layer); // Projection engine handles the transformation影響: フィーチャが誤った位置に表示されたり、数千キロメートルずれて表示されたり、空間参照に互換性がない場合はまったく表示されなかったりします。