Help us understand the problem. What is going on with this article?

国土地理院のベクトルタイルから道路中心線をぶっこ抜いた話

はじめに

スクリーンショット 2020-02-11 15.32.45.png

国土地理院は、2019年7月から「ベクトルタイル提供実験」を実施しています。
gsi-cyberjapan/gsimaps-vector-experiment

地理院地図Vectorでのデータ配信が本旨でしょうが、自分のサイトのMapbox GL JSに表示してみたいなんて気持ちになったりもします。また、地理院のベクトルタイルには「道路中心線」データが含まれており、これは今までオープンデータになった事はないはずです(確か有償提供)。じゃあその道路中心線、ゲットしたいな、という事で本記事ではその過程を示します。

なお本記事ではベクトルタイルとはなんぞや、という説明は省きます。

目標

以下の画像のようにQGISで地理院ベクトルタイルを表示する事を目標とします。
こうなれば外部ファイルへの出力など、煮るなり焼くなり好きに出来ますね。
スクリーンショット 2020-02-11 16.08.12.png

ベクトルタイル提供実験

データの使用条件などは以下のとおりです。

提供の位置づけ
国土地理院ベクトルタイル提供実験におけるデータの提供の位置づけは次のとおりです。
本提供実験は、ベクトルタイル提供における技術的・施策的課題を国土地理院が把握するとともに、外部からの技術的な提案を受け取り、外部との技術的な議論を通じてベクトルタイルの適切な提供方法を研究開発することを目的とするものです。
本提供実験の期間は、2019年7月29日から本提供実験終了までとなります。
本提供実験のデータは、国土地理院コンテンツ利用規約に従って利用できます。データを利用する際は、「国土地理院ベクトルタイル提供実験」と、出典の明示を行ってください。
本提供実験のベクトルタイルは基本測量成果と位置付けているものではありませんが、基本測量成果としての提供を検討するにあたって、提供を行うものです。
本提供実験の利用により生じた損失及び損害等について、国土地理院はいかなる責任も負わないものとします。

地理院ベクトルタイルについて

リポジトリより、地理院ベクトルタイルのデータソースは以下のURLである事がわかります。

https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf

しかしラスタータイルと異なり、多くのソフト・フレームワークでは、このURLをただ指定するだけでは表示してくれません。
ではまず、Mapbox GL JSで表示する手順を追ってみます。

Mapboxで表示する

https://kanahiro.github.io/experiment-gsi-bvmap/dist/
上記は表示したサンプルサイトです(うっすらとOSMを表示しています)。
Mapbox GL JSで地理院ベクトルタイルのうち道路中心線を表示するコードは以下のとおりです。

let map = new mapboxgl.Map({
    'container':'mapPane',
    'style':{
        'version':8,
        'sources':{
            'gsi-bvmap':{
                'type':'vector',
                'tiles':[
                    'https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf'
                ],
            }
        },
        'layers':[
            {
                'id':'road',
                'type':'line',
                'source':'gsi-bvmap',
                'source-layer':'road',
                'paint':{
                    'line-color':'#990000',
                    'line-width':3
                }
            }
        ]
    },
    center: [139.7, 35.6],
    zoom: 9
})

①source:「ベクトルタイルのURL(.pbf)」をtilesという配列にセットする。
②layer:sourceとそれに含まれるデータ(source-layer)を指定して、「好きなスタイルで」追加してやる。

source-layerの名前は、バイナリデータ内で定義されているため、事前にデータ名を把握しておいた方が良いです。
今回はリポジトリに定義一覧があるので、そこで道路中心線のデータ名は「road」である事がわかります。
※多分デコードしてsource-layerの名前を取得する事も不可能じゃないと思いますが調べていません

「好きなスタイルで」というのが、ベクトルタイルの大きな利点です。
同一のデータから、利用者の望むスタイル(色・太さ・透明度など)で表示する事が出来る訳ですね。

当然、道路データ以外もlayersで定義してやれば同時に表示する事が可能です。

QGISで読み込む

QGISでベクトルタイルを表示する手順は昨日の投稿した記事のとおりです。
しかしここまでの説明で行けば、明らかに足りないものがあります。tiles.jsonです。

無からtiles.jsonを錬成する

他のベクトルタイルのtiles.jsonを眺めてみると、.pbfタイルのURLがわかれば、tiles.jsonは自前で作成出来る事がわかりました。
というわけで今回作成したtiles.jsonの構造は以下のとおりです。
※どのkeyがoptionalでどれが必須なのかわからない中作成していますので、無駄なkeyがあるかもしれません
※追記:tiles.jsonの仕様について以下のリポジトリで定義されています
https://github.com/mapbox/tilejson-spec

tiles.json
{
    "tilejson": "2.0.0",
    "id": "gsi-bvmap",
    "name": "GSI-BinaryVectorMap",
    "format": "pbf",
    "maxzoom": 17,
    "minzoom": 5,
    "attribution": "国土地理院",
    "description": "GSI Experiment",
    "vector_layers": [
        {
            "id": "road",
            "fields": {
                "motorway": "String"
            },
            "maxzoom": 14,
            "minzoom": 0,
            "description": ""
        }
    ],
    "crs": "EPSG:3857",
    "crs_wkt": "PROJCS[\"WGS 84 / Pseudo-Mercator\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs\"],AUTHORITY[\"EPSG\",\"3857\"]]",
    "tile_grid": "mercator",
    "tiles": [
        "https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf"
    ]
}

今回はroadレイヤーのみ欲しいので、それ以外のデータは定義していません(が、プラグインは何も問題なく動きます(後述))。
本当なら、すべてのsource-layerをvector_layersで網羅してあげるべきです。

Vector Tiles Readerで表示する

上記のtiles.jsonを適当にホスティングして、そのURLをプラグインに与えてConnect→Addすれば、無事にQGISで地理院ベクトルタイルが表示されます(ある程度、日本列島の領域に拡大してからAddしてください)。なお、vector_layersに定義していないはずのroad以外のデータも(おそらくはpbfをデコードして自動的に)追加されます。
ちなみに私のGitHub pagesにも上記のtiles.jsonをアップしてあります。

なお、QGIS上の表示領域内の地物のみがレイヤーのデータとなるため、たとえばデータを外部ファイルに出力したいとき、狙いの地物が完全に表示領域内となっている必要があります。

そんなわけで道路中心線(北海道の主要道路のみ)をぶっこ抜けました。
そのデータを用いたネットワーク解析によるポケモンマンホール最適経路分析はまた別の記事で。

Kanahiro
GISを中心に勉強中、いろいろ作っています。
https://kiguchi999.hatenablog.com/
MIERUNE
位置情報に関する様々な技術情報やTipsをMIERUNEのメンバーがお届けします。位置や可視化に関するご相談がございましたらぜひご連絡ください!
https://mierune.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした