Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pbfデータのmapbox leaflet独立な読み込み方法の開示について #14

Closed
satakagi opened this issue Mar 1, 2021 · 3 comments

Comments

@satakagi
Copy link

satakagi commented Mar 1, 2021

国土地理院ベクトルタイル提供実験の説明によれば、機械判読可能なオープンデータの提供をその趣旨の一つとされているとのことですので、オープンデータとして基本の要件といえるベンダ中立性を担保するという文脈でのISSUEとなります。

本リポジトリのREADMEによると、データはMapbox社が提唱するVector tile specificationに基づいた、pbf形式で配信されているとされています。
同仕様書によれば、pbf形式を判読するためには、google 社が提唱するgoogle protocol bufferに基づく読解が必要とされ、このために下記の.protoファイルが提供されています。
https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto
そこで、このファイルを用いてpbfファイルを読み取るためのツールとして、同Mapbox社が提供している
pbf.jsを用いることができるそうですので、これを用いて実際に解読を試みてみましたがうまく解読できていません。

mapbox社のleafletに依存しない、独立したデータの読み取り方法の具体的なオープンソース開示をいただければと思います。おそらくVector tile specificationの文書が同社の内部的にアウトデートしているなどの理由で、.protoファイルのバージョンが違うもしくは何らかの独自拡張が施されているのではないかと推測しますが、leafletの解析は当方のスコープ外のためこれ以上の調査はしていません。

なお、当方で具体的に実施し、読み込みができなかった手順を以下に記します。

mapbox_vector_tile仕様データの読み取りライブラリの構築。(vector_tile.protoは、上記vector-tile-specリポジトリの最新バージョンと思われるスペックにあるファイル)

npm install -g pbf
pbf vector_tile.proto --browser > mapbox_vector_tile.js

読み取りのテスト

<html>
<script src="https://unpkg.com/pbf@3.0.5/dist/pbf.js"></script>
<script src="./mapbox_vector_tile.js"></script>

<script>
onload=async function(){
	var data = await getPbf();
	console.log(data); // 空のデータとなる
}
async function getPbf(){
	var url ="33024-33279.pbf";
	let response = await fetch(url);
	if (response.ok) {
		var bufferRes = await response.arrayBuffer(); // arrauBufferは作られている
		pbf = new Pbf(new Uint8Array(bufferRes));
		var obj = Tile.read(pbf); 
		return obj;
	} else {
		console.error("error:", response.status);
	}
};
</script>
<body>
</body>
</html>
@frogcat
Copy link

frogcat commented Mar 1, 2021

このような記事を公開している者です。
Leaflet でバイナリベクトルタイル処理の流れを追ってみる

興味があったので手順を再現してみたところ、(以下のように修正が必要でしたが) console に正常出力を確認できました。

<html>
<script src="https://unpkg.com/pbf@3.0.5/dist/pbf.js"></script>
<script src="./mapbox_vector_tile.js"></script>

<script>
onload=async function(){
	var data = await getPbf();
	console.log(data); // 空のデータとなる
}
async function getPbf(){

	// var url ="33024-33279.pbf";
  var url ="https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/7/112/50.pbf";
	let response = await fetch(url);
	if (response.ok) {
		var bufferRes = await response.arrayBuffer(); // arrauBufferは作られている
		pbf = new Pbf(new Uint8Array(bufferRes));
		var obj = Tile.read(pbf);
		return obj;
	} else {
		console.error("error:", response.status);
	}
};
</script>
<body>

</body>
</html>

例示されていた pbf は、ファイル名から類推すると以下のようなフォントのための pbf ではなかったでしょうか?
https://maps.gsi.go.jp/xyz/noto-jp/NotoSansCJKjp-Regular/33024-33279.pbf
これは mapbox vector tile の spec とはことなるスキームでエンコードされていますので、 vector_tile.proto でのデコードは失敗すると思われます。

上の例は pbf の取得先を https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf に従った適当なバイナリベクトルタイルの URL に変更してみたものです。この場合は Tile.read によるデコードが正常に動作しました。

@satakagi
Copy link
Author

satakagi commented Mar 1, 2021

コメントありがとうございます。
読み込んでいたpbfが別物(フォントデータ)だったのですね!
ブラウザのデベロッパーツール優先でスペックのタイルURLの仕様を見ていませんでした^^;

試してみましたところうまく読み込むことができました。

フォントデータのエンコードスキームは、このリポジトリのスコープ外だと思いますので、これでこのISSUEはcloseさせていただきます。

@satakagi satakagi closed this as completed Mar 1, 2021
@satakagi
Copy link
Author

satakagi commented Mar 1, 2021

ご参考までに、追伸です。

leafletと独立した状態でgeojsonをwebAppsで取得するには、@frogcatさんの情報を参考にして以下のようなコードで取得することができました。

雑ですが、

var VectorTile = require('./vectortile');
window.VectorTile = VectorTile;
console.log("window.VectorTile:",window.VectorTile);

このようなmapbox_vector_tile_w.js を用意したうえで、

https://github.com/mapbox/vector-tile-js

https://github.com/mapbox/point-geometry
を参照してbrowserify でライブラリを作り、

browserify mapbox_vector_tile_w.js -o mbvt.js

これを用いて

<html>
<script src="https://unpkg.com/pbf@3.0.5/dist/pbf.js"></script>
<script src="./mbvt.js"></script>
<script>
onload=async function(){
	var data = await getPbf();
	var geoData = data;
	var gj = geoData.layers.railway.feature(0).toGeoJSON(112,50,7); // geoGeojson(x,y,z)の数値はタイルのxyzのことです
	console.log("geojson:",gj);
}

async function getPbf(){
	console.log("caled getPbf");
	var url ="https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/7/112/50.pbf"; // z,x,y
	//var url ="33024-33279.pbf"; // そもそもこのファイルが地図データではなくフォントデータでした
	let response = await fetch(url);
	if (response.ok) {
		var bufferRes = await response.arrayBuffer();
		var pbf = new Pbf(new Uint8Array(bufferRes));
		var obj = new VectorTile(pbf);
		return obj;
	} else {
		console.error("error:", response.status);
	}
};
</script>
</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants