itoma(1)：ベクトルタイルのためのArcGIS Rest API実装ツール unvt/itoma を試してみる

おはようございます。もう春ですね。
早起きしたので、昨日試してみたunvt/itomaの実験をQiitaでも記録しておこうと思います。

:::note
（追記）この記事には続きがあります。
itoma(2)：unvt/itoma をhttps対応させられるかな（できたようだ）
も興味がありましたらどうぞ！
:::

# はじめに
## unvt/itoma の開発・公開
2022年3月28日（NY時間）、国土地理院からベクトルタイルのためのArcGIS REST API 実装ツール [unvt/itoma](https://github.com/unvt/itoma)がFOSS4Gとして公開されました。（Tweetは[こちら](https://twitter.com/gsi_cyberjapan/status/1508588575117709312?cxt=HHwWgMDUwZ7Uyu8pAAAA)）

私のQiitaのページでもArcGIS Rest APIの実装については、いくつか記事を書いていたこともあり、このツールにとても期待しています。そこで、今回、[unvt/itoma](https://github.com/unvt/itoma)でどんなことができるか、実験してみましたので、メモをここにも書いておきます。なお、私はWindowsユーザーなので、簡単のため今回の実験はDocker（unvt/nanban）を使って実験しています。

## unvt/itomaで出来ること
最初に書いてしまいますが、こんなことができそうです。

* style.ymlファイルから、ベクトルタイルスタイルのプレビュー
    * Mapbox GL JS, MapLibre GL JS, ArcGIS API for JavaScriptでベクトルタイルスタイルの描画ができます。  
* ArcGIS REST API　に対応した以下のサービス（実行しているサーバー（例：ローカルホストとして）から、）
    * .../VectorTileServer/ からindex情報を返します。
    * .../VectorTileServer/resouces/styles/root.json　からスタイルJSONを返します。
    * .../VectorTileServer/tilemap/{z}/../../32/32 からtilemapを返します。（ZLが固定のようです）
        * ZL14までは全部１のものを返して、ZL15からはファイルがないというものを返します。
    * .../VectorTileServer/resouces/tileから、styleファイルに指定されているURLのtileを返す（strictオプション）
    * .../VectorTileServer/resouces/fontsから、styleファイルに指定されているURLのフォントを返す（strictオプション）
    * .../VectorTileServer/resouces/spritesから、styleファイルに指定されているURLのspritesを返す（strictオプション）


## itomaを使うにあたって必要なもの
itomaはmapboxスタイル仕様、もしくはMapLibreスタイル仕様に準拠したスタイルファイル（json形式）を直接読みません。この前に開発されているスタイルツール unvt/charites で利用しているYAMLファイル形式でスタイルを管理していますので、itomaを使う際には、charitesも一緒に使いましょう。（Dockerのunvt/nanbanには両方入っているので大丈夫！）

## 私の作業環境
* Windows 10 (Enterprise)
* Docker version 20.10.8, build 3967b7d
* つかったDocker container unvt/nanban
* 作業したレポジトリ　https://github.com/ubukawa/itoma-test

# 実際の実験

## Step 1： Docker unvt/nanban のスタート
今回の作業用レポジトリを git cloneしたあと、そこのディレクトリに移動してからDockerを始めます。unvt/nanbanにはunvt/itomaもunvt/charitesも入れてあります。

```
git clone https://github.com/ubukawa/itoma-test
cd itoma-test
Docker run -it --rm -v ${PWD}:/data -p 8080:8080 unvt/nanban
cd /data
```
itomaとうつと、itomaで出来るコマンドが出てきます。機能はserveだけのようですが、今度は itoma help serve とうつと、オプションを確認することができます。

![itoma-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/9749582a-41d3-8a26-2e4f-8b5d59b04161.png)

今回の作業レポジトリでは、testというフォルダのなかに地図のスタイルファイルstyle.ymlファイルがあるので、それを使いました。
なお、これは地理院地図Vector（仮称）のstd.jsonのスタイルからラベルを少し減らしたスタイル情報です。作り方に興味がある場合は、私の以前のメモ（[地理院地図ベクター（仮称）のスタイルをunvt/charitesで加工しArcGIS Onlineでみてみる（はじめの一歩）](https://qiita.com/T-ubu/items/87b17bb8752cb15c9d28)）をみてください。


## Step 2：itomaの実行、スタイルの読み込み 　そして観察
Step1でDockerをスタートしました。Dockerの-vオプションで作業フォルダを/dataとしてつなげていますし、-pオプションでポート8080もつないでいますので、次は、以下のようにitomaをスタートして観察してみます。

```
itoma serve test/style.yml
```

（なお、ここでYAMLファイルをもっていない場合は、unvt/nanbanにはcharitesも入っているので、charites convert のコマンドをうつと、jsonスタイルがyaml形式に変換されます。charitesのコンバートではlayersフォルダにたくさんのymlファイルができるので、スタイル用のフォルダを作ってから変換することをお勧めします。）

### 2-1. プレビュー画面の観察
itomaのserveが始まりました。ウェブブラウザでローカルホスト(8080ポート)を見ると以下のような画面でした。ライブラリを選べます。
![itoma-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/cbf8079c-91c5-ce4b-f6d7-97da00693cb9.png)

トークンをあまり気にしないで気軽にみられるMapLibreのライブラリでまず見てみました（下図）。ベクトルタイル地図を見られます。（開いたばかりだと緯度経度やズームレベルが０のところにいくので、日本近辺の座標をURLで指定してみています。）
![itoma-003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/060a14bb-1673-e69a-220d-7597407e4b9e.png)

次にArcGIS (ArcGIS API for Javascriptかなと思います）をクリックすると、どうやら様子が違います（下図）。あとで説明しますが、これは--strictオプションをつけると見られました。（CORSの関係かなと思いました） 
![itoma-004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/bc0f2058-42a7-7457-1ae0-e694373ff0fb.png)

同じArcGISでもitoma serveにstrictオプションをつけて、再度serveをするともう少し地物が見られました（下図）。
![itoma-005-strict.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/4db53ec4-00cb-8957-bc19-0a1d426e3f2c.png)

違いを見てみると、strictオプションをつけないと何やら下図のようにCORS関係と思われるファイルを参照していました。なお、strictオプションなしだと、tile、sprites、fontsはみなstyle.ymlで指定されているURLを参照しているので、今回のホストサーバーであるlocalhostとは異なるオリジン（ドメイン）を参照している状況でした。地理院地図Vector（仮称）はCORSができる設定のはずなので、ArcGIS API for Javascriptの方の都合でCORSができないのかなぁ、、などと少し思いました。（どなたかご存じでしょうか？）
![itoma-007-cors.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/e0ef9d45-1398-68f3-f763-69a59e3aa672.png)

一方で、strictオプションをつけると、itomaがルーティングをしてくれるようで、まるでlocalhostにtile, sprites, fontsがあるようにふるまってくれています（serveのhelpで説明が書いてあります）。このことでCORSが解決されているのかなと想像しました。
![itoma-006-strict.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/fc95f82b-e628-17b7-c607-2e05d005ffb1.png)
↑タイルのパスもlocalhost

![itoma-007-strict.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/32491d14-6cad-6c17-c4ad-55e130a3cabf.png)
↑フォントのパスもlocalhost


### 2-2. ArcGIS REST API関係のインターフェースの観察
2-1では、ArcGIS API for Javascriptでのプレビューをみましたが、過去の私の経験ではArcGIS API for JavascriptsでみたWeb地図のstyleとArcGIS Onlineでの読み込み地図で同じスタイルが若干違うように解釈されるケースがあったように思うので、ArcGIS REST API周りのインターフェースを観察して、ArcGIS Onlineで表示してみることが大切です。

#### index情報
2-1で観察したパスなどを参考にすると、（ホスト名）/arcgis/rest/services/itoma/VectorTileServerがArcGISのベクトルタイルサーバーに相当する役割を果たしているだろうと想像出来ます。
ですので、まずは、http://localhost:8080/arcgis/rest/services/itoma/VectorTileServer を開いてみました（下図）。ファイル指定もpjsonをしてみます。ArcGIS REST APIに準拠したjsonが返ってくることを確認しました。（なお、下図はstrictモードで見たものです。）
![itoma-008-index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/18df2a10-3e17-410c-129a-8d1e1bf745e9.png)

ソースコードを見ていて気がつきましたが、上記のパスの中での名前itomaは任意の名前に変更しても大丈夫です。パスの中の名前を読み取って、JSONファイルを返してくれています（下図）。これはArcGIS Onlineで読み込まれるベクトルタイルサーバーの名前は、パス中のそこの文字列で指定されるのでそうしているのかなと思います。
![itoma-010-anyname.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/336f6bb3-78b1-aea3-6b66-583ee81bbe46.png)

重ねて強調しますが、strictモードのとき、以下の図の様にstyle.ymlで指定しているURLのtile、fonts、spritesなどはArcGIS REST APIで定められたパス（.../VectorTileServerの下）から出ているようにされています。itomaがプロキシの役割を果たしてルーティングしています。(追記：通常モードの時もindex.jsonの書き方は同じでしたが、style.jsonのtile、sprites、glyphsなどには違いがありました。)
![itoma-008-style-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/6c484151-7dcf-d831-2c94-4f03a5cae0a6.png)

#### style 情報
（ホスト名）/arcgis/rest/services/itoma/VectorTileServer/resources/styles/root.json　のところからはスタイル情報が返ってきているはずです。確認したところ、きちんと見えました。

#### sprites, fonts
indexのところで紹介したとおり、（ホスト名）/arcgis/rest/services/itoma/VectorTileServer/resources/の中のそれぞれの場所から、style.ymlで指定したURLにルーティングされています。

#### Tilemap
TileMapはArcGIS Onlineがオーバーズーム（ベクトルタイルデータの最大ZLを超えてズームする）をするときに使う仕組みです。詳しくは私の前のメモ（[ArcGISベクトルタイルサーバーのベクトルタイルはどう使われているか（特にtilemapの反応について）](https://qiita.com/T-ubu/items/6360252ece6c792732c7)）やArcGIS REST APIを参照してください。

（ホスト名）/arcgis/rest/services/itoma/VectorTileServer/tilemap で問い合わせができますが、tilemap/ズームレベル/行（上端の位置）/列（左端の位置）/ 横幅 / 縦幅 として値が返ってきます。例えば、ZL1の、0,0タイルから始まる32×32のタイルの有無については以下の様に返ってきました。このズームレベルではタイルがあるということがわかります。（細かいことをいうと、ZL1ではタイルの数は2×2の4つなので、1,1,0,0,0,...,1,1,0,0,0,....というdataになるはずですが、タイルがあるということは伝わるかなと思います。※ZL1～4も同様に。）
![itoma-009-tilemap-zl1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/280fe441-77d5-637e-180e-0f3c10f0c2d3.png)

itomaではZL15以上のZLで、tilemapでタイルがないと返すようになっているようです（下図）。ここはソースタイルの実際のZLによらず固定されているのかなと思います。
![itoma-009-tilemap-zl15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/5318d94f-fae1-5b73-13d6-cd9960981d59.png)

ソースコードをみると、ここ（下図）でタイルが存在しないと返すZLを固定しているようです。将来、例えばserveのオプションで与えることで、実際に使うデータに応じたタイルの最大ZLを与えられるようにするともっと便利になりそうですね。（自分のデータでオーバーズーミングを出来る。）
![itoma-009-tilemap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/80a23a27-9efe-a731-eb96-9517c635f9d9.png)


### 2-3. ArcGIS　Onlineでの読み込み
次に、itomaのインターフェースを使って、ベクトルタイルをArcGIS Onlineで読み込むことをテストします。index.jsonの場所を2-2で確認していますので、ArcGIS Onlineのmapからレイヤの追加をしてみます。Add Layer from Webを選んでindexの場所 http://localhost:8080/arcgis/rest/services/itoma/VectorTileServer を指定します。

なお、具体的な方法については、前の記事（[ArcGIS onlineで地理院地図Vector（仮称）のベクトルタイル（ArcGISサーバー以外から供給されているもの）を表示してみる](https://qiita.com/T-ubu/items/ac4c1aef293e4b253111)）を参照してください。

![itoma-011-fail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/22f5e332-d158-2ce7-3fa6-539400a97c9f.png)

しかし、今回はlocalhostの場所を指定したところ、読み込みエラーになってしまいました。GitHubページにアップすると問題なく読み込めた他のスタイルでいくつか試しましたが同様の結果でした。
![itoma-011-fail-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/db37d96e-f0ed-4dba-d979-6c2b3c3a9f80.png)

これは別のところで経験があるのですが、localhostからだと読めない場合があります。ArcGISのページでも以下の記述があり、ウェブブラウザ側の問題のようです。http://localhost:8080 を信用出来るサイトとして登録しないといけません。（あるいはポートを80にして試してみてもいいかもしれません。）

https://enterprise.arcgis.com/en/portal/latest/administer/windows/common-problems-and-solutions.htm

http://localhost を信用出来るサイトとして設定しようと思って検索して調べたのですが、メニューが今のchromeで出来ないようなので、とりあえずここで止まっています。

#### 追記：
Chromeでサイトのセキュリティ設定は出来たのですが、読めませんでした。Edgeについては、httpだと信頼出来るサイトとして登録できません（下図）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/7faed24b-eb0e-566c-6197-11b5d4438d2c.png)

とやっていたのですが、観察していてようやく理由がわかりました。
ArcGIS Onlineで追加するとき、httpでサーバーを指定しても、なぜかベクトルタイルのスタイルリクエストのときにはhttpsでリクエストしているので（下図）、それでスタイルが返ってこなくて見られないようでした。これはArcGIS Onlineのバージョンによるのかもしれませんが、ArcGIS Onlineの仕組みによるので私は手がだせません。（もしかすると、itomaのindex.jsonでスタイルファイルへのパスを相対パスでなくて絶対パスで書いたらhttpが参照できるかもしれないなぁ、とも思います。）

でも、itomaがhttpsで動かせるようになるとArcGIS Onlineでもプレビューを見られるようになりそうですね。(itomaはnodejsのexpressベースで開発されているので、多分ソースコードの所を少し加工すればhttpsでもホストできると思います。実際のサーバーとhttps用のcertificateがある環境で拡張できるか、将来実験したいです。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/724e9309-c334-ad0e-7cf1-3ecbd995c299.png)




# まとめ
## 今回の振り返り
unvt/itomaを動かしてどのようなことができるか確認しました。Readmeにはあまり書いていませんが、itoma serveを実行することで、ArcGIS REST APIに対応しており、index.json、スタイルjson、sprites、fonts、tilemapなどを配信していることを確認しました。

## 今後の作業
ウェブブラウザの設定の関係で、http://localhost:8080 からのコンテンツをArcGIS Onlineで読み込めなかったので、時間があるときに引き続きテストします（追記：テストしました。上に追記を書きました。）。
また、unvt/itomaについて、私からはReadmeの説明書きの追記で貢献ができるかもしれないと思いました。

## 将来に向けて
ArcGIS用にスタイルやタイルを作っても、ArcGIS Onlineで消費するためにはArcGIS REST APIのインターフェースを継続して実行しておく必要があると思います。その意味で、unvt/itomaの機能をどうやってhttpsから配信していくか、itomaを継続的に長時間実行するには何を使えばいいか、今後探って行きたいです。

また、追記に書きましたが、httpsでサーバーを立てることがArcGSI Onliインターフェイスを完全にするためには必要ですね。

これまでのところ、私は[unvt/marble](https://github.com/unvt/marble)を使ってArcGIS用のインターフェースをもつサーバーを立てていました。itomaが使っているプロキシの考え方や、コードなどはこれまでに使っていたサーバーなどにも参考にできるところがたくさんあるのではないかなと思います。

# 謝辞
unvt/itomaを開発され、またこれをFOSS4Gとして開発してくれた国土地理院に感謝します。また、開発に携わったGeoloniaの皆様に感謝します。


# References
* unvt/itoma　https://github.com/unvt/itoma
* unvt/nanban　https://github.com/unvt/nanban
* ArcGIS REST API
* https://enterprise.arcgis.com/en/portal/latest/administer/windows/common-problems-and-solutions.htm
* 私の前の記事
    * [地理院地図ベクター（仮称）のスタイルをunvt/charitesで加工しArcGIS Onlineでみてみる（はじめの一歩）](https://qiita.com/T-ubu/items/87b17bb8752cb15c9d28)
    * [ArcGISベクトルタイルサーバーのベクトルタイルはどう使われているか（特にtilemapの反応について）](https://qiita.com/T-ubu/items/6360252ece6c792732c7)
    * [ArcGIS onlineで地理院地図Vector（仮称）のベクトルタイル（ArcGISサーバー以外から供給されているもの）を表示してみる](https://qiita.com/T-ubu/items/ac4c1aef293e4b253111)