Esri と Mapbox の連携について

## 1. はじめに
本エントリーは [FOSS4G Advent Calendar 2019 22日目](https://qiita.com/advent-calendar/2018/foss4g)のエントリーです。

Mapbox が7月のソフトバンクワールドの発表をきっかけに日本でのビジネスの展開を初めました。GIS の業界も大きくなっているのを感じており、私としてはワクワクしています。

GIS でのマーケットリーダーでもある Esri も Mapbox に負けないぐらい面白いことをやっています。今回は、Esri と Mapbox との連携を幾つか試してみたので、連携した内容について紹介したいと思います。

## 2. Mapbox とは
2010 年からサービスは開始されており、特徴は地図の高いカスタマイズ性で、facebook、Pinterest、Evernote、Uber 等といった著名な企業の Web サイト等でも活用されています。
最近日本で話題となったのは、Yahoo! Map にも Mapbox の技術が使用されたことです。

- [Yahoo! MAPの地図表示システムをMapbox社製に変更しました](https://map.yahoo.co.jp/blog/archives/20191015_map_mapbox.html)

- [Web版Yahoo!地図の地図表示システムもMapbox社製に変更](https://map.yahoo.co.jp/blog/archives/20191030_map_mapboxweb.html)

また、Mapbox は、2014年にバイナリベクトルタイルの仕様 「[vector-tile-spec](https://docs.mapbox.com/vector-tiles/specification/)」 を策定しています。2015年には [Esri](https://www.esri.com/arcgis-blog/products/mapping/mapping/vector-tiles-preview/) も Mapbox の仕様をサポートするようなっています。

## 3. Vector-tile-spec と Protocol Buffers

ご存知の方も多いかと思いますが、バイナリベクトルタイルには、Google の [Protocol Buffers](https://ja.wikipedia.org/wiki/Protocol_Buffers) の技術を使用しています。これは、データをシリアライズし、高速な通信を実現できる点が特長となっています。また、これは昔からある技術で、最近では、マイクロサービスのシステム間通信で [gRPC](https://grpc.io/) という、RPC (Remote Procedure Call) を実現する手段として、Protocol Buffers が使われています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/13f474f9-0181-2d45-1405-bee38c6b3d35.png)

## 4. Mapbox GL JS との連携
Esri も背景地図として多くの [Esri ベクタータイル](https://www.esri.com/arcgis-blog/products/arcgis-online/announcements/whats-new-in-esri-vector-basemaps-february-2019/)を配信しています。また、これらの背景地図は、実は色々なところで利用されています。1つ目の例では Esri のベクタータイルを Mapbox GL JS を使って表示したので、その例について紹介します。

まず、[Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/overview/) は、WebGL を使用して、ベクタータイルや Mapbox スタイルから地図を描画する JavaScript のライブラリです。

今回の連携では、地図のスタイルを変更して、変更したスタイルファイルを参照して Mapbox GL JS で表示させました。地図のスタイル変更では、[Vector Tile Style Editor](https://www.esri.com/arcgis-blog/products/developers/mapping/design-custom-basemaps-with-the-new-arcgis-vector-tile-style-editor/) を使用しました。
こちらは、Mapbox Studio と同じように自由に地図のスタイルを変更することができます。Vector Tile Style Editor を試してみたい方は、[Style a vector basemap：Use the ArcGIS Vector Style Editor to create basemaps with custom styles](https://developers.arcgis.com/labs/arcgisonline/style-a-vector-basemap/) を参照してください。

連携は、下記のイメージ図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/40c18978-05da-236a-5c9b-65992eb0da8a.png)
連携方法として、ArcGIS Online もしくは、Vector Tile Style Editor からスタイルをダウンロードして、そのファイルを使用する方法と、Esri のベクタータイルのスタイルを直接参照することもできます。

- Esri ベクタータイルのスタイルの例
 - http://www.arcgis.com/sharing/rest/content/items/3e1a00aeae81496587988075fe529f71/resources/styles/root.json"

Mapbox GL JS から参照する場合の例を以下に示します。fetch を使ってスタイルを読み取って Mapbox GL JS に設定しています。この例では、あらかじめスタイルはダウンロードし、S3 にアップして、そちらを参照するようにしました。

```JavaScript 

/**
 * 各データを設定
 */
const DATA_URL = {
  STYLE_DATA:
    "https://test-kamiya.s3-ap-northeast-1.amazonaws.com/mapbox_gl_js/style.json"
};

fetch(DATA_URL.STYLE_DATA).then(response => {
  return response.json().then(style => {
    // next fetch metadata for the raw tiles
    const metadataUrl = style.sources.esri.url;

    fetch(metadataUrl).then(response => {
      return response.json().then(metadata => {
        const ready = format(style, metadata, DATA_URL.STYLE_DATA);
        /**
         * 地図の初期読み込み
         */
        var map = new mapboxgl.Map({
          container: "map", // container id
          style: ready,
          center: locations[locationIdx].camera.center,
          zoom: locations[locationIdx].camera.zoom,
          bearing: locations[locationIdx].camera.bearing,
          pitch: locations[locationIdx].camera.pitch,
          hash: true,
          needsRedraw: false,
          customAttribution:
            "&copy; Esri, HERE, Garmin, FAO, NOAA, USGS by Esri"
        });
        map.addControl(new mapboxgl.NavigationControl());
        let scale = new mapboxgl.ScaleControl({
          maxWidth: 200,
          unit: "metric"
        });
        map.addControl(scale);
      });
    });
  });
});

function format(style, metadata, styleUrl) {
  // ArcGIS Pro published vector services dont prepend tile or tileMap urls with a /
  style.sources.esri = {
    type: "vector",
    scheme: "xyz",
    tilejson: metadata.tilejson || "2.0.0",
    format: (metadata.tileInfo && metadata.tileInfo.format) || "pbf",
    /* mapbox-gl-js does not respect the indexing of esri tiles
    because we cache to different zoom levels depending on feature density, in rural areas 404s will still be encountered.
    more info: https://github.com/mapbox/mapbox-gl-js/pull/1377
    */
    // index: metadata.tileMap ? style.sources.esri.url + '/' + metadata.tileMap : null,
    //maxzoom: 15,
    tiles: [style.sources.esri.url + metadata.tiles[0]],
    description: metadata.description,
    name: metadata.name
  };
  return style;
}
```

実際の動きを確認したい場合は [CodePen](https://codepen.io/takahirokamiya/pen/gObPWzP) にアップしましたので、こちらで確認できます。

## 5. Mapbox Studio との連携
２つの目の例では、Mapbox Studio で設定した地図を [ArcGIS Online](https://www.arcgis.com/index.html) に設定して、ArcGIS Online から参照できるように連携してみました。
Mapbox Studio は、地図のカスタマイズができ、色、表示内容、表示の大きさ等の編集が可能となっています。

ちなみに ArcGIS Online は、Facebook や Google のアカウントとも連携していますので、すぐに利用することができます。また、[ArcGIS for Developers](https://developers.arcgis.com/) では、無料枠の Essentials Plan でも ArcGIS Online を利用することができます。ArcGIS for Developers では、Mapbox と同じように API や SDK も提供していますので、ArcGIS プラットフォームと連携した開発などもすぐに行うことができます。

連携は、下記のイメージ図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/6b65841c-d64a-7607-69bf-439bf2a12632.png)

まず、Mapbox Sudio で設定した地図は、Share & develop から Third party の項目があり、そこから WMTS や ArcGIS Online の設定などがあります。今回は、ArcGIS Online を選択して、該当の URL をコピーします。
<img width="1377" alt="Mapbox Studio" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/36586261-7a42-4383-e7c3-b17e36d15ff1.png">

そして、次にコピーした URL を 設定するため、ArcGIS Online の [Map viewer](https://www.arcgis.com/home/webmap/viewer.html?useExisting=1) を表示して、追加の「Web からレイヤーを追加」でタイル レイヤーを選択します。ArcGIS Online では、WMS や WMTS 等の OGC など多くのサービスと連携することができます。
<img width="1318" alt="ArcGIS Online" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/884150ab-a764-4512-4385-705c842873fa.png">

そして、先ほど Mapbox Studio からコピーしたURLを以下のように設定します。
<img width="787" alt="Image 2019-12-15 at 11.23.18 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/cea78340-9247-8a05-d136-b5602c44125a.png">
レイヤーを追加することで、ArcGIS Online でも以下のように Mapbox の地図を簡単に表示することができます。
<img width="1318" alt="ArcGIS Online" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/4c199363-51a2-3889-cea4-786b58b891fa.png">

いかかがでしょうか。簡単に連携が確認できるかと思います。

## 6. 最後に
Mapbox と Esri を連携することで、両者のサービスを提供できれば面白いかなと思ったりもしました。Mapbox もそうですが、Esri もプラットフォームとして、多くの規格や仕様に対応しているため、簡単に連携することができました。
今後も Mapbox の技術はキャッチアップしつつ、Esri ともっと面白い連携ができるか探っていきたいと思います。