本記事については問題があり、原因については下記にて説明しています。
https://qiita.com/R_28/items/49826f822121cb15e11c
前提
結論としてST_AsMVTでベクタータイルは作れます。(そういう関数なので)
下記に詳細は記載されていますので、ST_AsMVTを試してみたい方はこちらを参考にされるほうが良いです。
http://waigani.hatenablog.jp/entry/2017/12/22/060000
自分はベクタータイルの作り方は下記の「simple-vectorizer」を参考にしています。
https://qiita.com/honjo/items/8ea61f5a9c1bbaa669c0
https://github.com/mapion/simple-vectorizer
ここでの本題は
ST_AsMVTで「simple-vectorizer」と同じベクタータイルが生成できるか?
になります。
simple-vectorizerは次のような手順でベクタータイルを作成しています。
- タイル状にクリッピングしたジオメトリとパラメータを作成
- ジオメトリの結合、単純化を適用
- 生成したジオメトリをGeoJSONに変換して出力
- JSONをmapnik.VectorTileを使ってバイナリ化
1から3まではSQLで処理し、JSONからバイナリ化はNode.js側で処理している設計ですね。
この際、
- ジオメトリからJSONに変換している
- JSONをバイナリにNode.jsで変換している
といったところオーバヘッドになっているわけですが、
PostGIS2.4から「ST_AsMVT」が使えるようになったことから
「SQLでバイナリ化まで可能」になったようです。
で、ST_AsMVTで同様のベクタータイルが生成できるのかを検証。
環境
OS:
Windows10
PostgreSQL:
'PostgreSQL 10.1, compiled by Visual C++ build 1800, 64-bit'
PostGIS:
'2.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1'
タイル:
16/58306/25693
レイヤー:
rdcl
SQL
ST_AsMVTを使用したSQL部分については下記の通り
SELECT ST_AsMVT(q, 'rdcl', 4096, 'geom')
FROM (
SELECT
rdctg AS c1,
ST_AsMVTGeom(
ST_Simplify(ST_LineMerge(ST_Collect(geom)),map.pixel_at_zoom(16)), --- 1
map.tile_to_box(58306,25693,16,2),
4096,
0,
true) --- 2
AS geom
FROM (
SELECT
rdctg,
(ST_Dump(geom)).geom --- 3
FROM rdcl
WHERE geom && map.tile_to_box(58306,25693,16,2)
) a GROUP BY a.rdctg
) as q
- ST_Transformは実施していません。(ST_AsMVTGeomがやっている?)
- タイルのクリッピング処理をST_AsMVTGeomで実施
- そのため、map.safe_intersectionは省略
描画
SQLを一度テキストで吐き出してバイナリ化、vt2gejsonでJSON化し、表示。
やり方は下記参照
http://waigani.hatenablog.jp/entry/2017/12/22/060000
GEOJSONの表示は下記のサイトを使用
http://geojson.io/
比較
赤:simple-vectorizerで作成したジオメトリ
黒:ST_AsMVTで作成したジオメトリ
※simple-vectorizerで生成したベクタータイルのバイナリをvt2gejsonでJSONに変換して使用
なんかずれるんだよなぁ
考察
なぜずれるか
- ST_TransformとST_AsMVTGeomの座標変換での差?
- map.safe_intersectionの差?
ずれ方を見る限り、中心付近ではマッチしていることから、測地系のずれではなさそう。
投影法かなぁ