地理院タイル周りの３つのメタデータとその応用を考える

## はじめに

国土地理院の地理院地図や地理院タイルに関して、技術情報が[情報普及課の GitHub アカウント](https://github.com/gsi-cyberjapan) から公開されているのですが、その中にはメタデータの仕様（案）が含まれています。

今回はそのうち、以下の３つのメタデータの関係性を見てみます。

* ウェブ地図レイヤ定義 layers.txt（[layers-dot-txt-spec](https://github.com/gsi-cyberjapan/layers-dot-txt-spec)）
* ココタイル（[cocotile-spec](https://github.com/gsi-cyberjapan/cocotile-spec)）
* 地理院タイル目録（[mokuroku-spec](https://github.com/gsi-cyberjapan/mokuroku-spec)）

## ウェブ地図レイヤ定義 layers.txt

https://github.com/gsi-cyberjapan/layers-dot-txt-spec

### 概要
ウェブ地図内におけるレイヤ管理の目的で利用されるメタデータとなります。実際に、[地理院地図](https://github.com/gsi-cyberjapan/gsimaps)では、この layers.txt 群を読み込んで、レイヤの管理を行っています。中身は JSON 形式で、レイヤの名称や ID 、レイヤの説明や凡例、タイルの URL やズームレベルの範囲を規定しています。

地理院地図のレイヤ選択では、layers.txt を順に開いて選んでいくような形式になっていますが、たとえば、URL からレイヤの表示状態を復元する際等は、**タイル ID からタイル URL 等の情報を探す**のに利用されていいます。

地理院地図の他、地理院地図Globe や地理院地図3D、地理院地図Vector 等、周辺のサービスでもこの layers.txt 群を利用しているようです。

一方、タイルを中心に考えると、**当該タイルセットを説明するためのメタデータ** としても活用可能です。地理院タイルについては「地理院タイル一覧」というページが公開されていますが、地理院地図のシステム的には、この layers.txt 群が、地理院タイル（一覧には記載されていないデータも含む）の一覧としての機能を持っていると考えられます。

```JavaScript:layers.txt の例
{
  "layers": [
    {
      "type": "Layer",
      "title": "地理院タイル（標準地図）",
      "attribution": "地理院タイル（標準地図）",
      "legendUrl": "https://maps.gsi.go.jp/development/ichiran.html#std",
      "html": "<h1>地理院タイル（標準地図）</h1>",
      "url": "https://cyberjapandata-t{s}.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
      "subdomains": "123"
    },
    {
      "type": "LayerGroup",
      "title": "写真",
      "src": "https://cyberjapandata.gsi.go.jp/layers_txt/layers_divided.txt"
    }
  ]
}
```


### 応用例

現在は、タイル ID を layers.txt 群から探してきて、該当する情報を利用する（解説の表示、タイルの取得等）を行うという実装が多いですが、layers.txt 群を用いることで、例えば、**キーワード検索等でレイヤを探す**、というような使い方も可能となるでしょう。

## ココタイル

https://github.com/gsi-cyberjapan/cocotile-spec

### 概要
ココタイルは、タイルの所在を示すメタデータです。**そのタイル位置にどのようなタイルが存在するか**の情報が格納されています。ココタイルは、実際に、地理院地図の「表示範囲で絞り込み」を実現するために使用されています。

中身としては、そのタイル位置に存在するタイルの種類（タイル ID）がカンマ区切りで列挙されています。

例えば、以下は、`http://cyberjapandata.gsi.go.jp/xyz/cocotile/18/239192/93905.csv` の内容であり、これは、このタイル位置（`18/239192/93905`）に標準地図（std）と淡色地図（pale）が存在していることを示しています。

```JavaScript:ココタイルの例
std,pale
```

### 応用例

国土地理院のココタイル仕様だと、タイル１枚１枚に応じて、ココタイル用となるタイルを作成しなければなりません。一方、タイル ID の数次第ですが、１枚１枚のタイルの情報は非常に小さい可能性が高いです。そのため、複数のココタイルの情報を１つにまとめれば、より効率的なココタイル管理ができる可能性が高いです。

まとめ方としては、タイルの性質を利用して、記載すべき所在タイルの ZL を小さくしたときのタイル番号を持つココタイルに記載していく方法が考えられます。たとえば、ZL18の所在情報は、ZL16のココタイルを取得するという感じですね。[地図タイルを ZL １つ分深く作るための覚悟](https://qiita.com/mg_kudo/items/b3ae4071a69d4026550c)でも記載したとおり、タイルの ZL を１つ減らせれば、管理運用コストは大きく削減できます。

良い名前は思いつきませんが、「cocotile 集」からとって、仮に  cocoshu tiles としておきましょうか？

```JavaScript:cocoshu tiles の例（ZL16の 16/19798/23476 のファイルに記載）
std/18/239192/93905
pale/18/239192/93906
・・・
std/18/239192/93906
・・・
```

## 地理院タイル目録 mokuroku

https://github.com/gsi-cyberjapan/mokuroku-spec

### 概要
地理院タイル目録（以後、mokuroku）は地理院タイル１枚１枚の所在情報を記述したファイルです。この mokuroku の実体は CSV 形式であり、１行がタイル１つ１つの情報となっています。このファイルは、タイルの種類ごとに存在し、`https://cyberjapandata.gsi.go.jp/xyz/{タイル ID}/mokuroku.csv.gz` という URL で、タイル ID があれば特定できます。

```JavaScript:mokuroku の仕様
（パス）,（最終更新時刻）,（サイズ）,（MD5SUM）
```
```JavaScript:mokuroku の例
18/239192/93905.png,1409468135,285,1635de9ccf8ec5d7e71ce535b72e1a23
```

標準地図（std）や淡色地図（pale）は、全国のデータが ZL18 まであるので、非常に重いデータとなります。しかも、ハッシュ値のような圧縮が効かないものが入っているので、ファイルサイズも巨大になります。標準地図の場合、タイル総数は約5,200万枚です。以前ダウンロードしたときの記憶だと、たしか、mokuroku は gzip 圧縮でも 1.1 GB、非圧縮の CSV だと、4.4 GB くらいだったと記憶しています（違っていたら申し訳ありません）。

もともと、そもそも mokuroku は、[効率的なタイルダウンロード・同期](https://www.gsi.go.jp/common/000106650.pdf)を目的としているようです。手元のタイル一式を地理院タイルサーバと同期させるにあたり、mokuroku に沿って、ハッシュ値を比較して、差分のあるタイルだけダウンロードすれば、サーバの帯域を効果的に活用できるというものです。

最近は、mokuroku 一式をダウンロードせずとも、特定期間内のタイル更新情報を記載した「[nippo](https://github.com/gsi-cyberjapan/nippo-spec)」というメタデータも提供されています。こちらは mokurokut と異なり、地理院タイル全体に対して1ファイルしか提供されていないため、nippo の無いようには、タイル ID も記載されています。

```JavaScript:nippo の例
pale/18/239192/93905.png,1409468135,285,1635de9ccf8ec5d7e71ce535b72e1a23
```

### 応用例

現在は、もっぱらタイル一式のリストとして使われていますが、もう少し簡易的にして、例えば、小さい ZL に限定してファイル容量も小さくすれば、あるタイル ID のデータがどこに存在するかを示すメタデータとして十分に活用できるかと思います。

たとえば、災害時に国土地理院が撮影したデータが地理院地図上で掲載されていますが、土地勘がないと、なかなか撮影地区を探すのは難しいです。そこで、タイル ID ごとに、例えば ZL 12 とかに限定した mokuroku（仮に mini mokuroku とでもしておきましょうか）を作成しておけば、その mini mokuroku を読み込むことで、おおよその位置にズームインさせる等の実装が可能となります。ファイルの内容もタイルパスさえあればよく、ファイルサイズやハッシュ値も不要でしょう。

::::::note warn
なお、現在地理院地図では、layers.txt の `area` という属性にタイルの代表地点を設定することで、タイルの存在する場所付近へ移動する機能があります。上記で提案した mini mokuroku の方式とどちらが良いかは運用次第かと思います（mini mokuroku は mokuroku と同時に作成できます）。
:::

## ３つのメタデータの関係性と活用法

3つのメタデータはどのように利用すればよいか、関係性とユースケースをまとめてみました。現行の地理院地図では、mokuroku は直接利用されていませんが、タイル ID からタイルの領域を探せるメタデータとしてユースケースを想定して記載しています。

![メタデータの関係性.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/ef048bd0-26bf-419b-86fb-cf944139d406.png)

![メタデータのユースケース.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/e3d35d05-d356-4e3f-a89c-24002c117391.png)


## サーバレスな仕組み

さて、３つのメタデータを見てきましたが、最後に重要な点として、これらが**静的コンテンツ**だけで実装できる仕組みである、ということを記載しておきます。

もちろん、データベースなどを使えば、もう少し管理が楽（※１）になりますし、通信量も抑えられる（※２）のかもしれませんが、サーバのセキュリティを（あまり）気にせず、サーバレスに GitHub Pages や S3 のみで配信できる安心感は強みかと思います。 

※１：動的な仕組みであれば、静的なファイルを大量にホストする必要がない
※２：たとえば、静的な仕組みのみで実装する場合、タイル ID を検索するのに、layers.txt を一式クライアントへダウンロードしなければならないのは通信コストが増える懸念がありデメリット（実際、地理院地図では、layers.txt 群の大量ダウンロードが発生することがある）

## おわりに

地理院地図や地理院タイルにまつわる３つのメタデータを見てました。これらは地理院地図エコシステム以外での実装を見たことｈありませんが、そのアイデアは有用かと思います。

今回は概要とアイデアをまとめた記事となっていますが、他に、ユースケースや応用例を思いついたら追記していければと思います。