はじめに
Web 地図で利用するための 「地図タイル」を作成・管理するというのはかなりマニアックな分野だと思います。そんなマニアックな分野に新しく来られた方へどのような知識をお伝えすればよいでしょうか?
これまで、Web 地図用のタイル(slippy map tilenames 形式)の記事をいくつか書いてきましたので、その整理も兼ねて、関連知識をまとめてみたいと思います。
- 基本的に、本記事はリンク集です。
- 自分の記事多めですが、足りない部分は、参考になる記事・資料へのリンクを掲載させていただいております。
- とはいえ、まだ偏り・不足が否めないです。
- 随時更新していければと思います。(大規模に変更する可能性もあります。)
「タイルという仕組み」の名称
経験論として、「地図」の話をしている中で「タイル」という言葉が出てきたら、基本的に slippy map tilenames 形式を示しているものと理解して良いかと思います。タイトルの「地図タイル」はあまり使われない表現かもしれませんが、この経験に基づいて採用しています。
「地図タイル」にまつわる表現を少し例示してみます。
- OpenStreetMap Wiki ではタイルの仕組みを説明するのに、slippy map tilenames というページが設定されています
- 内閣府の「スマートシティ・リファレンスアーキテクチャ」の別冊「地理空間データ連携基盤」では、そのまま「地図タイル」という表現が出てきます
- また、国土地理院は、自ら提供するタイルを「地理院タイル」と呼んでいますが、一般的な表現として、「いわゆるXYZ方式」という呼び名を使っています
- 国連から提供されている「Mapping for a sustainable world」という冊子では、tile-based (web) map や tileset という表現が出てきます
- タイルの仕組みに関係する標準技術としては、Tile Map Service や Web Map Tile Service (WMTS) があります
この記事では、「地図タイル」は基本的に slippy map tilenames 形式を指していますが、広義では「あらかじめ分割された地図データ」と考えても良いでしょう。
前提知識
タイルの仕組みを話す前に、地図の基本的な知識は必要になるかと思います。また、実際にタイルを作成・ホスト・配信・消費するには、情報科学分野(Web まわり)の知識が必要になるでしょう。
参考に、自分が勉強している間に出会ったキーワードをあまり系統や粒度を気にせず雑多に並べてみます。
地図関係のキーワード
地図投影法、測地系、メルカトル図法、経緯度、測量、地図編集(総描、省略、転位)、縮尺、地図情報レベル、GIS、ラスタデータ、ベクタデータ、メッシュデータ、ポリゴン、ライン、ポイント、POI、GeoJSON、Shapefile、KML、クラスタリング、ヒートマップ、地域メッシュWeb 関係のキーワード
OS(Windows、Linux)、ファイルシステム、ブラウザ、デベロッパーツール、JavaScript、HTML、CSS、HTTPS、REST、Ajax、WebGL、canvas、非同期処理、(様々な)キャッシュ、PNG、JPEG、JSON、Protocol Buffers、クラウドサービス、クラウドネイティブ、サーバレス、Web サーバ、DNS、CDN、オブジェクトストレージ、データベース、オープンデータ、OSS、各種ライセンス(クリエイティブ・コモンズ・ライセンス等)、シングルページアプリケーションタイルの仕組み
タイルの概要・分割方法
地図タイル(slippy map tilenames 形式)の概要や分割方法については、以下のサイトが参考となります。特に「ズームレベル」(ZL)という概念が重要です。
タイルの基本的な考え方をまとめると、以下のようになるかと思います。
- まず、世界を正方形の地図とする
- ズームレベル(ZL)という指標に基づき、この正方形の世界をタイルへと分割する
- ZL が1つ大きく(深く)なると、1つのタイルは、縦横2分割ずつ、計4枚のタイルに分割される
- 各地図タイルは ZL (z)、経線方向座標(x)、緯線方向座標(y)で特定できる
※国土地理院の「地理院タイルについて」のページより転載
タイルの URL について
タイルデータを読み込む場合、ZL、X 座標、Y 座標をぞれぞれ {z}
、{x}
、{y}
という表記で埋め込んだ URL テンプレートで扱うことが一般的です。
たとえば、地理院地図(標準地図)を読み込む場合、以下のような URL テンプレートを利用するツール(Web 地図ライブラリや GIS ソフトウェア)へ登録します。
https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png
一般化すると以下のようになるでしょう。このような {z}
、{x}
、{y}
が入った URL(URI)を見た場合は、地図タイルを示す URL テンプレートだと考えて良いかと思います。
(通信プロトコル)://(ドメイン・フォルダパス)/{z}/{x}/{y}.(拡張子)?(クエリ等)
実際にデータを読み込むときは、テンプレート中の {z}
、{x}
、{y}
を具体的な数字(たとえば、{z}/{x}/{y}
→2/3/1
)に置き換えてタイルデータへアクセスします。多くの場合、ツール側で状況に応じて必要なタイルを読み込んでくれます。
多くのタイルデータは、{z}/{x}/{y}
という階層になっていることが多いですが、必ずしもこのような構造にこだわる必要はありません。
たとえば、{x}
と {y}
が逆になっている場合もあります。もっとテクニカルな例としては、GitHub Pages でタイルデータをホストするような場合、1レポジトリ当たりの制限にぶつかるかもしれませんが、その際に、レポジトリを ZL 毎に分けてしまうという方法も考えられます。
https://example.com/example-tile-{z}/tile/{x}/{y}.png (架空のタイル URL)
このアイデアは以下の記事からいただいています。
ただ、このような変則的な URL テンプレートは、後々問題を起こす懸念があります。たとえば、以下の記事では、タイル URL から、ZL、X 座標、Y 座標を復元する際に混乱を生じる可能性を(やや極端ではありますが)例示しています。タイルを提供する際は、理由がなければ、{z}/{x}/{y}
のテンプレートを採用することをおすすめします。
投影法(Web メルカトル)
この slippy map tilenames 形式では、Web メルカトル(Pseudo メルカトルとも)と呼ばれる投影法が用いられています。WGS84で得られた経緯度を、真球を仮定してメルカトル投影を行う図法です。
メルカトル図法は、地球上の角度と紙面上の角度が等しくなるように表現した図法です。経線は紙面上で平行に表されるため、緯度が大きくなるほど、経線間の差が拡大して表示されることになりますから、角度を正しく表示するため、緯線の間隔を、経線の間隔に合わせて拡大して表示しています。ただし、極へ近づくほど、図上距離が無限大に大きくなってしまいます。
そこで、Web メルカトルでは、ちょうど正方形で示すことができる南緯約85度~北緯約85度の範囲を対象としています。
Web メルカトルについては、以下の通り、整理を試みています。
タイル座標の計算
OpenStreetMap の Wiki には、経緯度とタイル座標を互いに変換する計算式が、各プログラミング言語の実装例とともに掲載されています。
ラスタタイルとベクトルタイル
GIS データがラスタデータとベクタデータに分別されるように、それぞれの形式をタイル化したラスタタイルとベクトルタイルが存在します。1枚1枚のラスタタイルは、一定の大きさの画像データ(PNG や JPEG 等)となっています。ベクトルタイルも、広義には、特定のベクタデータ(例えば GeoJSON)を各タイル領域に分割したデータとなりますが、最近は、効率的に符号化された Mapbox Vector Tile という形式が普及しています。
この記事でも、ベクトルタイルは主に Mapbox Vector Tile を想定して記載しています。
ラスタタイルとベクトルタイルの違い・特徴は、以下のサイトが参考となります。
タイルの縮尺・解像度
1枚のタイルが示す縮尺(範囲)や解像度(つまりピクセルの大きさ)が気になることはあると思います。
そのような需要は多いのか、主な地図サービスには、タイルの縮尺や精度のイメージを説明するページが準備されています。
これらの解説ページでは、ズームレベル毎にタイル1枚又は1ピクセルがどのくらいの大きさになるのか、スクリーン解像度毎に画面上での縮尺はどれくらいになるか、という説明が主です。なお、タイル1枚のピクセル数や画面上に表示するサイズによって、数字は変わってきますので、あくまで大まかな数字として捉えておくことが重要だと思います。
- Slippy map tilenames#Resolution_and_Scale (OpenStreetMap Wiki)
- Zoom levels (OpenStreetMap Wiki)
- Glossary | zoom level (mapbox)
- Zoom levels and scale (esri Developer)
- Bing Maps Tile System#ground-resolution-and-map-scale (Bing Maps)
- Understanding Scale and Resolution (Bing Maps)
私も日本周辺のタイルにまつわる数字を整理してみましたので、この記事の最後の方に掲載しています。
タイルの生産
利用可能なツール等
タイルの生産方法については、以下の @Kanahiro 様の記事にて、最近のトレンドがまとまっており大変参考になります。
タイルの設計
ツールによっては、データを流し込めばよしなにタイルを作成してくれるかもしれませんが、場合によっては、パラメータや作業フローを調整する必要があるでしょう。
特に、地図タイルの重要なコンセプトである ズームレベル(ZL)がタイルデータ生産以後に及ぼす影響は非常に大きいので、必要精度やコスト等をよく考えて ZL を設定する必要があるというのが私の持論です。
また、特にベクトルタイルの場合、ラスタタイルと異なり、どのようなデータ構造とするか、より深い検討が必要になります。たとえば、以下はベクトルタイル(Mapbox Vector Tile)の表示速度を考慮した検証をしてみた記事です。
巨大なデータを取り扱う場合は、データの分割処理を含めて、作業フローの検討が必要です。参考に、以下は、全世界のデータをベクトルタイルへ変換するための取り組みが紹介された論文となります。「4.2.3 Module-wise Hosting」「5.1.2 Division of the globe into 12 areas」あたりが、大規模なデータを取り扱う考え方のヒントになると思います。
タイルのホスト・配信
タイルを配信する場合は、Web サーバなどにホストする必要があります。利用する環境次第ということもあり、本記事での詳細は割愛しますが、タイルデータは静的コンテンツであるという点を活かして、AWS の S3に置くだけで配信できたり、GitHub Pages でのホストも可能です。
ただし、タイル管理の関係上、タイル用のサーバを設定することもあり得ます。以下は、タイルサーバについて解説されたサイトです。
タイル周辺知識が分かりやすく解説されていますが、ポイントは以下の点です。
インフラ系の人なら、「これを静的にファイル持ってたら死ぬんじゃない?」って気づくかもしれません。実際のところ静的なファイルとしてホスティングしてしまうとファイルシステムの限界に当たってしまいます。今回作成しているタイルサーバではtileserver-glおよびmbtilesというファイルを使うことでこれを解決しています。なお、地理院地図ではCDNにホスティングをしてこの問題を解決しています。
どの程度のファイル数になるかは、この記事の最後の方(タイルの管理)にてご紹介します。
タイルの消費・活用
ウェブ地図として閲覧する
タイルを作成した主目的は、Web 地図で利用するためである場合が多いと思います。
タイルデータを表示できる主要なライブラリを列挙してみますが、利用したいユースケースに合わせて選択できればよいと思います。このほか、QGIS 等の GIS ソフトでも対応している場合が多いです。
個人的な感覚ですが、ラスタタイルだけの場合は Leaflet が利用されている場合が多く、ベクトルタイル(Mapbox Vector Tile)が利用される場合は、Mapbox GL JS か MapLibre GL JS が使われています。
ベクトルタイルのスタイルについて
ベクトルタイルを利用する場合、別途、地図をどのように描画するかの設定を行う必要があります。Mapbox GL JS や MapLibre GL JS では、Style Specification という、地図のデザイン(私は「スタイル」と呼んでいます)を指定する設定があります。
スタイルの事例
好きなデザインを実現するためには、地道に公式サイト(Mapbox/MapLibre)を読んでいくことになると思いますが、たとえば、以下のアドベントカレンダーには、Style Specification の解説・実装例が充実しており、参考になるかと思います。
また、既にあるスタイルを改造する、という方法も有効かと思います。以下は、国土地理院提供のスタイルを改造する方法です。
工夫すれば、遊び的なデザインも可能で、以下はクレヨン風のスタイルを試作してみた記事です。
スタイルとパフォーマンス
また、スタイル設定も複雑になるにつれ、表示速度へ影響が生じます。タイルの設計にも関係しますが、大規模・複雑なデータの場合、スタイルの部分でもパフォーマンスに検討が必要です。
(参考)OpenLayers について
OpenLayers について
OpenLayers 関係の情報はかなり少ない印象ですが、以下のように水戸地図(β)様から、国土地理院のベクトルタイルの表示に関するツール・情報が提供されています。
私も OpenLayers でのベクトルタイル表示方法を検討してみたことがあります(私の実装での性能はそんなによくありません)。
データベース代わりに使う
タイルは、Web 地図上で可視化するだけでなく、タイル1枚1枚をデータベースの断片として、データ取得 API のように利用することができます。この場合、1枚のタイルは事前に空間検索・地物のフィルタ等を完了させた結果のキャッシュと考えてよいでしょう。
グリッド PNG タイル
たとえば、国土地理院では、標高タイルが提供されていますので、以下のように、タイルデータを用いて特定地点の標高を得ることができます。
- 標高を知りたい地点の経緯度をタイル座標とタイル内のピクセル座標へ変換する
- 目的のタイル座標の標高タイルをダウンロードする
- タイルの中の目的のピクセル座標の情報を標高値へデコードする
(参考:標高を求めるプログラム)
産総研では、このような使い方のできるタイルを「グリッド PNG タイル」という考え方で整理しているようです。
私も、過去、標高タイルや重ねるハザードマップのオープンデータを用いて、標高値や洪水・津波などの浸水深を取得・利用させていただいたことがあります。
slippy map tilenames 以外の分割方法
データとして使う場合は、これまで説明したラスタタイルやベクトルタイルの形式にこだわる必要はありません。たとえば、分割方法に slippy map tilenames 以外の方法(地域メッシュ等)を採用しても良いかもしれませんし、GeoJSON ファイルや CSV ファイルをタイル状に分割して管理するという方法も考えられます。
本記事で、地図タイルの広義な定義を「あらかじめ分割された地図データ」と考えたのは、上記のような slippy map tilenames 以外の分割方法を想定したためです。
ただし、独自の分割方法やデータ形式を利用する場合は、将来的な相互運用性をよく考慮すべきだと思います。
タイルの管理
タイルは細かいデータの集まりです。そのため、あまりにも多いタイルをファイルシステム上で保持すると、データのコピー等で時間がかかることが多くなるなど、弊害も生じてきます。(本記事でも何度か言及している通りです。)
以下の記事では、どの程度のタイルデータ(ファイル数や容量)があるのか、タイルごとのサイズがどのように分布するのか、日本全国をカバーするようなデータの規模感(国土地理院のラスタタイル・ベクトルタイルの例)を調べてみました。
最近は、サーバ側の実装を必要としない形式でタイル一式を1つのファイルにまとめた PMTiles というファイル形式も普及しつつあります。
- PMTiles の仕様と取扱いを勉強してみる@mg_kudo
- ウェブ地図で複数の PMTiles をひとつの Source として扱う方法(←こちらは結構マニアックかもしれません)
タイル周りの数字
日本周辺のタイルに関する数字をまとめた1枚紙を作成してみました。何かの参考になれば幸いです。(中の数字は「地図タイルを ZL 1つ分深く作るための覚悟」で扱ったものです。)
おわりに
これまでの記事の整理と合わせて、地図タイルにまつわる関連知識をまとめてみました。おそらく足りない部分や、初めての方にはマニアックすぎるものもあるかと思います。目的によって、ロードマップも変わってくるかと思います。また機会があれば、この記事にも手を入れていきたいです。