ArcGISのスタイルを体験する
はじめに
この記事ではArcGISにおけるスタイルの挙動を確認します。具体的にはArcGIS Maps SDK for JavaScriptを使って地図を表示し、どのようにスタイルを使うのかを見ていきます。
この記事は以下の企画の子記事です。他サービスの記事へのリンクがあるので、ぜひ合わせてご参照ください。
地図を表示する
チュートリアルのDisplay a mapを参考にまずは地図を表示してみましょう。
まず、以下のライブラリを読み込みます。
<link rel="stylesheet" href="https://js.arcgis.com/4.26/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.26/"></script>
CSSを設定します。
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
次に地図を表示する場所を作ります。
<div id="map"></div>
JavaScriptのコードは以下のようになります。まず、アクセストークンをesriConfig.apiKey
に設定します。次にMapクラスのコンストラクタでオプションを設定します。ここではベースマップの種類を指定しています。さらにMapViewクラスで描画に関する設定を行います。ArcGISは他のライブラリと違い、地図のデータに関する機能(Map
)と表示に関する機能(MapView
)が分離されています。こうすることで表示部分をSceneView
に変えると3D表示に切り替えることができたりします。
require(["esri/config", "esri/Map", "esri/views/MapView"], (
esriConfig,
Map,
MapView
) => {
esriConfig.apiKey = YOUR_API_KEY_HERE;
const map = new Map({
basemap: "arcgis-topographic"
});
const view = new MapView({
container: "map",
map: map,
zoom: 4,
center: [15, 65]
});
});
結果は以下のとおりです。
ローダー
ところで、require
という関数を初めて見たので調べました。これはAMD(Asynchronous Module Definition)と呼ばれるライブラリのローダーの機能でした(spec)。require
の引数にロードしたい機能名を配列で渡すと、コールバック関数の引数にその実体が渡されるようです。
ただし、ArcGISのGitHubのREADMEを見ると、AMDモジュールではなくESモジュールの仕様が推奨されています。そこで、ESモジュールで記述する方法も試してみます。まず、<script src="https://js.arcgis.com/4.26/"></script>
は不要なので消します。次にJavaScriptのコードを以下のように記述します。
import config from "https://js.arcgis.com/4.26/@arcgis/core/config.js";
import Map from "https://js.arcgis.com/4.26/@arcgis/core/Map.js";
import MapView from "https://js.arcgis.com/4.26/@arcgis/core/views/MapView.js";
config.apiKey = YOUR_API_KEY_HERE;
const map = new Map({
basemap: "arcgis-topographic"
});
const view = new MapView({
container: "map",
map: map,
zoom: 4,
center: [15, 65]
});
詳しい解説はこちらをご参照ください。この解説によるとCDNによる読み込みはパフォーマンスが良くないそうなのでご注意ください。
The ES modules CDN is for testing only, it is not optimized for performance. For best performance in a production application, build the @arcgis/core modules locally.
結果は以下のとおりです。
以降の説明ではESモジュールで実装します。
スタイルの変更
ArcGISではベースマップの上に自由にレイヤーを重ねることで独自の地図を作成します。そこで、このベースマップのスタイルを編集する方法を確認します。ArcGISはMapbox StyleとEsri Web Mapの二種類のJSONスタイルをサポートしています。
ArcGISはVector Tile Style Editorというサービスを提供しており、これを利用することでWeb上のUIで直感的にスタイルを編集できます。また、編集したスタイルはEsriのサーバにホストされ、ArcGIS Maps SDK for JavaScriptから使用できます。
Vector Tile Style Editor (VTSE)でスタイルを編集
それでは早速、高速道路の色を赤色に変更してみましょう。
「Start editing」ボタンをクリックして開始します。最近作成したスタイルの一覧画面に遷移しますが、そこで右上の「+New style」ボタンをクリックします。デザインのベースとなる地図を選択しますが、ここでは「World Topographic Map (for Developers)」を使用しました。
東京周辺をズームし、高速道路をクリックします。当該レイヤー(Road/Freeway Motorway/0 (Line))が選択された状態になるので、AppearanceのColorを#ff00000
に変更します。即座にプレビューの地図に反映されます。
左にあるメニューで「Save as」をクリックし保存します。Share with:
でEveryone (Public)
を選択することでJavaScriptから使用できるようになります。
スタイルの使用
それでは早速先程のスタイルを使ってみましょう。VectorTileLayer
およびBasemap
クラスを使用するのでインポートします。
import VectorTileLayer from "https://js.arcgis.com/4.26/@arcgis/core/layers/VectorTileLayer.js";
import Basemap from "https://js.arcgis.com/4.26/@arcgis/core/Basemap.js";
まず、作成したスタイルからVectorTileLayer
を作成します。VTSEの編集画面のURLに含まれる32文字のHEX値がid
です。
const vectorTileLayer = new VectorTileLayer({
portalItem: {
id: "2fa2c405a9674404a56a4db80d22341e"
}
});
つぎにVectorTileLayer
からBasemap
を作成します。
const basemap = new Basemap({
baseLayers: [vectorTileLayer]
});
そしてそのBasemap
をMap
に渡せばOKです。
const map = new Map({
basemap: basemap
});
結果は以下のとおりです。
Mapbox形式のスタイルを読み込んでいるのにVectorTileLayerという名称で少し混乱したかもしれません(私は混乱しました)。複数レイヤー集まったものがスタイルなのに、それにレイヤーという名称で良いのか?という違和感です。
しかし、ArcGIS Maps SDK for JavaScriptではスタイルを一つのレイヤーとして扱います。ベースマップとして使われるレイヤーはbasemap layer
、ユーザーが作成したデータ等を表示するレイヤーをoperational layer
とよび、それぞれ管理されます。
つまり、スタイル編集時に作成したレイヤーはJavaScriptのコード上ではレイヤーとして扱えないということになります。
スタイルを動的に変更
Mapクラスのリファレンスを見たところ、BasemapはMapオブジェクト
の作成時に指定し、その後変更するためのメソットがありませんでした。そこで、セレクタ選択時にMapオブジェクト
を作成し直します。
IDS
はWorld Topographic Map (for Developers)とVTSEで編集したスタイルのIDを入れます。createMap
関数は先程同様、VectorTileLayer
、Basemap
、Map
を作成します。セレクタが選択されると、それに応じてcreateMap
が呼び出されます。
const IDS = {
default: "42df0d22517e49ad84edcee4c093857d",
custom: "2fa2c405a9674404a56a4db80d22341e"
};
const selector = document.getElementById("selector");
const createMap = (id) => {
const vectorTileLayer = new VectorTileLayer({
portalItem: {
id
}
});
const basemap = new Basemap({
baseLayers: [vectorTileLayer]
});
const map = new Map({
basemap: basemap
});
const view = new MapView({
container: "map",
map: map,
zoom: 12,
center: [139.768435, 35.681054]
});
}
selector.addEventListener("change", (id) => {
createMap(IDS[selector.value]);
});
createMap(IDS['default']);
結果は以下のとおりです。
また、Basemapの変更には専用のUIが用意されているのでこれらを使用するのが便利です。
ソース + レイヤー = スタイル(番外編)
Mapboxの記事にもあった、スタイルを手動で作成する方法を試してみます。VectorTileLayer
はJSONのスタイルを直接受け取ることもできるので、以下のように記述するだけでOKです。スタイルの記法自体はMapboxと同じです。
const vectorTileLayer = new VectorTileLayer({
style: {
version: 8,
sources: {
esri: {
type: "vector",
tiles: [
`https://basemaps-api.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf?token=${config.apiKey}`
]
}
},
layers: [
{
id: "road",
type: "line",
source: "esri",
"source-layer": "Road",
paint: {
"line-color": "#00ff00",
"line-width": 3
}
}
]
}
});
結果は以下のとおりです。
まとめ
ArcGISではMapboxのスタイルが採用され、VTSEを用いて直感的に編集することができます。Mapbox Studioと似たツールでわかりやすいです。スタイル自体はJavaScriptのコード上では一つのレイヤーとして扱われる点はMapboxと異なるので注意が必要です。
他にもWebダッシュボード等のツール・ドキュメント・サンプルも豊富で使い勝手の良いサービスだと思いました。
Discussion