ベクトルタイルに埋め込まれた building の height または building:levels の情報を style.json で処理して、建物が立ち上がるようにしてみました。
https://unvt.github.io/mame/#15.68/41.322155/19.824567/-85.6/57
これの作り方を共有します。
0. 目的の整理
西バルカン地域をカバーする OSM ベクトルタイル実験サイトを作成すること
1. 作成範囲を作る
https://geojson.io を使って、作成範囲を作ります。
作ったものを https://github.com/optgeo/kokoromi-western-balkans/blob/master/extent/area.geojson に置きました。
作成範囲ファイルのある作業場所を clone します。
~ $ git clone git@github.com:optgeo/kokoromi-western-balkans
2. 切り出し用作業場所を clone する
切り出し用の作業場所を clone しました。ここの Rakefile に、planet.osm.pbf をダウンロードする方法と、切り出す方法が書いてあります。
~ $ git clone git@github.com:optgeo/waku
~ $ cd waku
~/waku $ cat Rakefile
task :planet do
sh "curl -L -o src/planet-latest.osm.pbf -C - https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf"
end
task :extract do
sh "osmium extract --polygon area/area.geojson --output a.pbf src/planet-latest.osm.pbf"
end
3. 最新の planet.osm.pbf ファイルをダウンロードする
上記の Rakefile にあるとおり、
~/waku $ curl -L -o src/planet-latest.osm.pbf -C - https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
とすることで最新の planet.osm.pbf ファイルをダウンロードできますが、ダウンロード途中で planet-latest.osm.pbf ファイルが変更されてしまうと、ダウンロードに失敗します。-latest ではなく、具体的な日付のファイルをダウンロードしましょう。
https://planet.osm.org/pbf/ を確認して、最新版の URL を確認します。作業時点では、
https://planet.osm.org/pbf/planet-200622.osm.pbf
が最新版でした。これを踏まえて、
~/waku $ curl -L -o src/planet-200622.osm.pbf -C - https://planet.openstreetmap.org/pbf/planet-200622.osm.pbf
を実行します。ファイルサイズは 50GB 以上あり、ダウンロードには10時間以上かかります。
なお、何らかの事故でダウンロードが止まっても、上記のコマンドを再度投入すれば、ダウンロードが継続されます。継続でダウンロードするようにするためのオプションが -C -
です。
4. md5sum をチェックする
planet.osm.pbf ファイルが壊れていると、変換の途中でエラーが起こります。他方で、planet.osm.pbf は巨大なファイルですので、事故は起こるものです。
ダウンロードの段階でファイルが壊れていないかを確認するために、md5sum をチェックしましょう。
md5sum の MD というのはメッセージダイジェストということを意味しています。md5sum は、与えられたデータに対して計算される一定の長さの文字列で、その計算をするはたらきのことをハッシュ関数といい、計算で得られた文字列をハッシュ値といいます。ハッシュ関数は、データが同じである場合に同じハッシュ値を返します。このことを利用して、ファイル(メッセージ)が同じかどうかを確認するのに、ファイル全体をながめわたす代わりに、ハッシュ値を比較するということがよく行われます。
~/waku $ curl https://planet.openstreetmap.org/pbf/planet-200622.osm.pbf.md5
6ea93910ce1757c098132097690e5544 planet-200622.osm.pbf
上記が、サーバ上にあるファイルの md5sum でした。手元のディスク上にあるファイルの md5sum を、次のようにして計算します。
~/waku $ md5sum src/planet-200622.osm.pbf
6ea93910ce1757c098132097690e5544 src/planet-200622.osm.pbf
ハッシュ値が 6ea9 で始まる同一の文字列になりました。これで、planet-200622.osm.pbf が問題なくダウンロードできたことが確認できたことになります。
5. 作成範囲をカバーする osm.pbf ファイルを planet.osm.pbf ファイルから切り出す
切り出しの標準形は、waku の Rakefile にあるとおり、
sh "osmium extract --polygon area/area.geojson --output a.pbf src/planet-latest.osm.pbf"
です。ここでは、これをアレンジして、次のコマンドを実行することにより、wastern-balkans.pbf を作成します。
~/waku $ osmium extract --polygon ../kokoromi-western-balkans/extent/area.geojson --output western-balkans.pbf src/planet-200622.osm.pbf
なお、src/planet-200622.osm.pbf のサイズは 52GB であったのに対し、western-balkans.pbf のサイズは 662MB でした。
GitHub レポジトリに収容できるデータの総量は 1GB です。pbf ファイルからファイルシステム上のタイルにすると、データ量が2倍から数倍になります。この倍率には、どうも面積が関係するようで、ニュージーランドのときには思ったより大きくなったという感覚があります。ファイルシステム上のタイルの総量が大きすぎる場合には、大きなズームレベルから切り捨てていきます。作業を続けていきましょう。
6. タイルを格納するレポジトリを作る
https://github.com/kokoromi-western-balkans-tiles を作ります。
docs/.gitkeep を作ります。空ファイルで良いです。
レポジトリの Settings を開きます。
GitHub Pages (gh-pages) の設定に行って、Source を「master branch /docs folder」に変更します。なお、執筆時点では master という表現が使われてますが、近いうちに master という表現が main といった表現に変更されているかもしれません。ここでは、執筆時点での GitHub のデフォルトをそのまま使っています。
これで、kokoromi-western-balkans-tiles レポジトリの docs に置かれたファイルが https://optgeo.github.io/kokoromi-wastern-balkans-tiles で公開されるように設定されました。
例えば、docs/zxy/2/3/1.pbf というファイルを kokoromi-western-balkans-tiles レポジトリにコミットすれば、GitHub でファイルをアップロードするアクションが動作して、動作後には https://optgeo.github.io/kokoromi-wastern-balkans-tiles/zxy/2/3/1.pbf という URL でアクセスできるようになります。
GitHub Pages は、HTTPS という、実勢上のウェブでの標準的なプロトコルでファイルをホストしてくれるだけではなく、HTTPS 上のさらに高速なプロトコルである HTTP/2 でホストをしてくれ、さらにタイルを外部サイトからアクセスするのを許可する特別な設定(Cross Origin Resource Sharing: CORS)も最初から済ませてくれています。開発者向けにチューンアップした親切な設定を、デフォルトでセットしてくれていることは非常にありがたいことです。このありがたさは、将来あなたが自分のサーバでタイルをホストする際に実感することになるかもしれません。
7. タイルを格納するレポジトリのクローンを作る
上記の通り設置したレポジトリのクローンをファイルシステム上に作ります。
$ cd
~ $ git clone git@github.com:optgeo/kokoromi-western-balkans-tiles
8. naru のクローンを作る
今回の作業では、建物の表示を三次元風から三次元に改修しようと思っていますが、事前の調査 から考えるに、この改修はタイルレベルではなくてスタイルレベルで行けるのではないかと思っています。このため、まずは素直に naru で pbf ファイルをベクトルタイルに変換して kokoromi-ke 相当の表示を実現してしまいましょう。
まずは naru のクローンを作ります。
$ cd
~ $ git clone git@github.com:unvt/naru
naru は「geofabrik extract を使って、スタンドアローンのベクトルタイルウェブ地図を作る」という設計目標のために作られたキットなので、そのままでは使わず、これから説明するように、少しアレンジして使っていくことになります。
9. タイルを生産する
naru のタスクの一覧を見てみます。
$ cd naru
~/naru $ rake -T
rake host # host the site
rake inet:download # download source geospatial data to the place
rake inet:fonts # TODO: clone and build fonts, and copy to docs
rake inet:install # install extra software for naru
rake inet:mbgljs # TODO: clone and build mapbox-gl-js, and copy to docs
rake inet:sprite # TODO: clone and build maki, and copy to docs
rake js # TODO: build JavaScript code using rollup
rake optimizer # TODO: run vt-optimizer
rake style # build style.json from HOCON descriptions
rake tiles # build tiles from source data
タイルの生産をするのは、tiles
ですね。Rakefile の該当記述内容は、次の通りです。
desc 'build tiles from source data'
task :tiles do
sh "osmium export --config osmium-export-config.json --index-type=sparse_file_array --output-format=geojsonseq --output=- src/#{AREA}-latest.osm.pbf | node filter.js | tippecanoe --no-feature-limit --no-tile-size-limit --force --simplification=2 --maximum-zoom=15 --base-zoom=15 --hilbert --output=tiles.mbtiles"
sh "tile-join --force --no-tile-compression --output-to-directory=docs/zxy --no-tile-size-limit tiles.mbtiles"
end
この第一行をアレンジした、次のコマンドを実行します。具体的には osmium のインプットを、作成しておいた western-balkans.pbf に変更するだけですね。
~/naru $ osmium export --config osmium-export-config.json --index-type=sparse_file_array --output-format=geojsonseq --output=- ~/waku/western-balkans.pbf | node filter.js | tippecanoe --no-feature-limit --no-tile-size-limit --force --simplification=2 --maximum-zoom=15 --base-zoom=15 --hilbert --output=tiles.mbtiles
For layer 0, using name "tiles"
7490213 features, 543030712 bytes of geometry, 1989854 bytes of separate metadata, 11164270 bytes of string pool
99.9% 15/17961/12321
tiles.mbtiles のサイズは 1.0 GB でした。
vt-optimizer を使って、構成を確認してみます。
~/naru $ node ../vt-optimizer/index.js -m tiles.mbtiles
✔ Parsing VT file contents
Vector Tile Info
Zoom levels: 0,
Format: pbf
Center: 19.517212,42.069684,15
Layers:
• boundary
• building
• nature
• place
• railway
• road
• route
• structure
• water
Vector Tile Summary
Zoom level Tiles Total level size (KB) Average tile size (KB) Max tile size (KB)
---------- ------ --------------------- ---------------------- ------------------ -
2 1 5.6240234375 5.6240234375 5.6240234375 ✓
3 2 9.6689453125 4.83447265625 5.6416015625 ✓
4 3 11.375 3.7916666666666665 6.0556640625 ✓
5 3 14.958984375 4.986328125 9.0234375 ✓
6 8 50.69140625 6.33642578125 18.0986328125 ✓
7 16 94.51953125 5.907470703125 14.1923828125 ✓
8 54 420.9755859375 7.795844184027778 21.9052734375 ✓
9 180 963.41015625 5.352278645833334 27.646484375 ✓
10 624 3458.59375 5.542618189102564 31.6875 ✓
11 2677 37363.8994140625 13.957377442683041 167.0625 ✓
12 9545 62084.77734375 6.504429265976952 118.521484375 ✓
13 35338 101244.0712890625 2.865019845182594 66.6337890625 ✓
14 136187 240321.087890625 1.7646404421172726 70.8759765625 ✓
15 510080 470067.720703125 0.9215568552053109 100.5126953125 ✓
? Do you want to get more information about a given level? (y/N)
ズームレベル 15 を捨てれば、470MB ほど削ることができるような構成になっているようです。
いざとなったらズームレベル 15 を捨てるつもりで、継続の作業をしてみましょう。ファイルシステムにタイルを展開します。
~/naru $ tile-join --force --no-tile-compression --output-to-directory=docs/zxy --no-tile-size-limit tiles.mbtiles
10. スタイルをビルドする
動作確認の目的で、スタイルもビルドしておきます。
~/naru $ vi hocon/_root.conf
として、gh-pages にホストしたタイルが反映されるように site_root を変更します。変更後の hocon/_root.conf の内容は次の通りです。
# _root.conf
# project specific parameters
site_root: "https://optgeo.github.io/kokoromi-western-balkans-tiles"
# site_root: "http://localhost:9966"
# center: [lng, lat]
center: [
174.786987
-41.314950
]
zoom: 11
sprite: ${site_root}"/sprite/sprite"
glyphs: ${site_root}"/font/{fontstack}/{range}.pbf"
この変更をした上で、スタイルをビルドします。
~/naru $ rake style
parse-hocon hocon/style.conf > docs/style.json
gl-style-validate docs/style.json
これで、naru の docs フォルダに、とりあえず動く西バルカン地域のベクトルタイルができました。これを kokoromi-western-balkans-tiles の docs にコピーしてアップロードします。
11. kokoromi-western-balkans-tiles にアップロード
~/naru $ cp -r docs ~/kokoromi-western-balkans-tiles
これで、naru/docs に作ったファイルをコピーしました。
~/naru $ cd ~/kokoromi-western-balkans-tiles
~/kokoromi-western-balkans-tiles $ git add .
~/kokoromi-western-balkans-tiles $ git commit -m update
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
...
create mode 100644 docs/zxy/9/289/194.pbf
create mode 100644 docs/zxy/9/289/195.pbf
create mode 100644 docs/zxy/metadata.json
[master dedc554] update
~/kokoromi-western-balkans-tiles $ git push origin master
Enumerating objects: 687472, done.
Counting objects: 100% (687472/687472), done.
Delta compression using up to 4 threads
Connection to github.com closed by remote host.
fatal: the remote end hung up unexpectedly
Compressing objects: 100% (686100/686100), done.
fatal: the remote end hung up unexpectedly
データが大きすぎるようですね。やり直しましょう。コミットをリセットします。
~/kokoromi-western-balkans-tiles $ git reset --hard HEAD^
Checking out files: 100% (694987/694987), done.
HEAD is now at 4aa1e62dbb Create .gitkeep
12. 方針変更
zxy ディレクトリの大きさを macOS の Finder 調べたところ、1.18 GB と表示されます。
つまり、ファイル総量を三割程度小さくすれば入ります。1.18 * 0.7 = 0.826 ですから、たぶんいけます。
他方、西バルカン地域では、小さな建物が多いようです。z=15 を捨てることをしてしまうと、小さな建物が取り込まれなくてもったいないと思います。
このため、エリアを精査して 3割ほど削ります。
西バルカン地域といったときに、クロアチアは含んでおいた方が良いのでしょうか。https://www.mofa.go.jp/mofaj/erp/c_see/page25_001753.html によれば、クロアチアを含まない6が取り扱われています。また、https://www.mofa.go.jp/mofaj/gaiko/oda/files/000458062.pdf でも「アルバニア、コソボ、セルビア、ボスニア・ヘルツェゴビナ、マケドニア旧ユーゴスラビア共和国、モンテネグロ」の6です。クロアチアを含まない6でいきましょう。
https://geojson.io をもう一度使って、ポリゴンでエリアを切り直しました。実用上、外側に少しマージンを取ります。
https://github.com/optgeo/kokoromi-western-balkans/blob/master/extent/area2.geojson
これで、改めて切り直しを行います。
13. 切り直し
$ cd ~/kokoromi-western-balkans
~/kokoromi-western-balkans $ git pull
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
From github.com:optgeo/kokoromi-western-balkans
1c5615b..c4a24a0 master -> origin/master
Updating 1c5615b..c4a24a0
Fast-forward
extent/area2.geojson | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 236 insertions(+)
create mode 100644 extent/area2.geojson
$ cd ~/waku
~/waku $ mv western-balkans.pbf western-balkans.old.pbf
~/waku $ osmium extract --polygon ../kokoromi-western-balkans/extent/area2.geojson --output western-balkans.pbf src/planet-200622.osm.pbf
[======================================================================] 100%
~/waku $ ls -lh western*pbf
-rwxrwxrwx 1 hfu staff 662M 6 28 07:54 western-balkans.old.pbf
-rwxrwxrwx 1 hfu staff 317M 6 28 16:07 western-balkans.pbf
pbf ファイルのサイズを半分以下に抑えることができたようです。
14. タイル生産(2回目)
$ cd ~/naru
~/naru $ osmium export --config osmium-export-config.json --index-type=sparse_file_array --output-format=geojsonseq --output=- ~/waku/western-balkans.pbf | node filter.js | tippecanoe --no-feature-limit --no-tile-size-limit --force --simplification=2 --maximum-zoom=15 --base-zoom=15 --hilbert --output=tiles.mbtiles
For layer 0, using name "tiles"
3132118 features, 252451262 bytes of geometry, 911496 bytes of separate metadata, 4866588 bytes of string pool
99.9% 15/17993/11801
~/naru $ ls -lh tiles.mbtiles
-rw-r--r-- 1 hfu staff 561M 6 28 16:28 tiles.mbtiles
~/naru $ node ../vt-optimizer/index.js -m tiles.mbtiles
✔ Parsing VT file contents
Vector Tile Info
Zoom levels: 0,
Format: pbf
Center: 19.517212,42.069684,15
Layers:
• boundary
• building
• nature
• place
• railway
• road
• route
• structure
• water
Vector Tile Summary
Zoom level Tiles Total level size (KB) Average tile size (KB) Max tile size (KB)
---------- ------ --------------------- ---------------------- ------------------ -
2 1 1.029296875 1.029296875 1.029296875 ✓
3 2 2.2451171875 1.12255859375 1.4931640625 ✓
4 2 2.2412109375 1.12060546875 1.48046875 ✓
5 2 2.8427734375 1.42138671875 1.9716796875 ✓
6 6 26.58203125 4.430338541666667 15.408203125 ✓
7 12 51.5546875 4.296223958333333 10.107421875 ✓
8 32 220.74609375 6.8983154296875 21.9052734375 ✓
9 98 469.5263671875 4.791085379464286 19.4755859375 ✓
10 354 1800.37890625 5.085816119350283 26.39453125 ✓
11 1630 21976.1181640625 13.482281082246933 112.7919921875 ✓
12 5758 35167.71484375 6.107626752995832 86.12109375 ✓
13 21088 55704.8955078125 2.6415447414554487 47.9228515625 ✓
14 80294 126118.615234375 1.5707103299670586 55.57421875 ✓
15 298315 237684.1416015625 0.7967555825270687 100.5126953125 ✓
? Do you want to get more information about a given level? (y/N) No
~/naru $ tile-join --force --no-tile-compression --output-to-directory=docs/zxy --no-tile-size-limit tiles.mbtiles
15. フォント入れ替え
naru が持っている sans フォントは、CJK に対応したフォントで、西バルカン地域で使われているディアクリティカルマークに対応したフォントが入っていないので、入れ替えます。
OpenMapTiles プロジェクトで作られたフォントは、基本的に世界のなるべく多くの文字を取り扱ったものですが、漢字については日本人にとり次のような課題がありました:Unicode では Han unification(漢統一)が行われており、例えば日本語と中国語での漢字について同一のコードが割り振られています。他方で、OpenMapTiles の標準フォントでは、漢字について中国語のグリフを優先するという判断が行われています。この結果、日本の地名が中国語のフォントで表示されるという問題がありました。このこともあり、naru などで伝統的に使っていたフォントは、日本語用にセットされたデータを使ったものでした。
他方で、最近の Mapbox GL JS では、ideograph はローカルのもので代用するのがデフォルトです。
このため、この機会に、OpenMapTiles が標準で使っているグローバル向けフォントセットを Mapbox GL JS 用に変換したものを使うように変更します。naru のレベルでこの入れ替えを行いました。
$ cd ~
~ $ git clone git@github.com:hfu/openmaptiles-fonts
~ $ cd naru
~/naru $ git rm docs/font/sans/*
~/naru $ cp ~/openmaptiles-fonts/
~/naru $ mkdir -p docs/font/sans
~/naru $ cp ~/openmaptiles-fonts/Noto\ Sans\ Regular/*.pbf docs/font/sans
~/naru $ cp ~/fonts/LICENSE docs/font/sans
~/naru $ git add docs/font
~/naru $ git commit -m "replaced font"
~/naru $ git push origin master
この修正により、セルビアの都市名について、次の通り表示が改善されました。
修正前
修正後
16. アップロード
~/naru $ cp -r docs ~/kokoromi-western-balkans-tiles
~/naru $ cd ~/kokoromi-western-balkans-tiles
~/kokoromi-western-balkans-tiles $ git add .
~/kokoromi-western-balkans-tiles $ git commit -m update
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
[master e89b897380] update
...
create mode 100644 docs/zxy/9/288/190.pbf
create mode 100644 docs/zxy/9/288/191.pbf
create mode 100644 docs/zxy/metadata.json
~/kokoromi-western-balkans-tiles $ git push origin master
Enumerating objects: 404882, done.
Counting objects: 100% (404882/404882), done.
Delta compression using up to 4 threads
Compressing objects: 100% (402187/402187), done.
Writing objects: 100% (404880/404880), 492.89 MiB | 2.98 MiB/s, done.
Total 404880 (delta 2063), reused 404747 (delta 1986)
remote: Resolving deltas: 100% (2063/2063), completed with 1 local object.
To github.com:optgeo/kokoromi-western-balkans-tiles
4aa1e62dbb..e89b897380 master -> master
ちなみに、push すると gh-pages を作るための Action が GitHub の側で動きます。
成功したタイミングで、表示がこのようになるように refresh できるようになります。
https://optgeo.github.io/kokoromi-western-balkans-tiles/ にアクセスすると、次のような表示がされることが確認できます。
このあと、元の目的にあったとおり、naru レベルで建物の表示を改善します。
変更前の naru
の pg-buidling*.conf の実装
layers.conf
{ include pg-building-shadow }
{ include pg-building }
{ include pg-building-train-station }
{ include pg-building-outline }
二次元グラフィックスで三次元っぽく見せるように黒く縁取りをするということを狙った設計でした。
鉄道駅については、建物の中に鉄道が入っているパターンがあったので、ある程度拡大すると半透過にするという工夫をしており、そのために別レイヤとしていました。
Mapbox Style を記述する原則は「下に書くものから順番に書いていく」というものです。それぞれのレイヤの記述内容について、順番にみていきます。
なお、この layers.conf で使っているレイヤ id の命名規則は、概ね次のような感じです。
{ジオメトリタイプ}-{OSMタグ}-{レイヤ固有名}
ジオメトリタイプは、ベクトルタイルに含まれているジオメトリの型です。次の3種類にしています。
- pt: Point
- ls: LineString
- pg: Polygon
MultiLineString は ls で、MultiPolygon は pg で扱っている場合が多いです。
OSM タグは、今回の場合は building です。naru で作るベクトルタイルは、OSM のタグ構造を比較的そのまま素直に取り入れるようになっているので、Mapbox Style の filter でうまくひっかけて判別しています。他のベクトルタイルでは、クラス構造(あるいはリレーショナルデータベースのテーブル)を作ってマッピングをしていることがあるかもしれませんが、naru の基本的な考え方は、回避不可能な必要が生じるまでは、凝ったマッピングはしない、というものです。
pg-building-shadow
id: pg-building-shadow
type: fill
source: v
source-layer: building
minzoom: 16
filter: [
match
[
geometry-type
]
[
Polygon
MultiPolygon
]
[
match
[
get
layer
]
[
"-1"
"-2"
"-3"
"-4"
"-5"
]
false
[
match
[
get
building
]
[
train_station
roof
]
false
true
]
]
false
]
paint: {
fill-color: [
rgb
131
124
124
]
fill-translate: [
2
2
]
}
このレイヤは、建物の影を描画するためのもので、paint
にある fill-translate
で、もとのジオメトリから (2, 2) ピクセル分ずらすことで、この後建物本体が描かれたあとに影としてみられる微量の濃色部をつくります。
pg-building
執筆現在最新のものは kokoromi-ke のために fill-extrusion を使うように改修されているので、この改修前のものをコピーすると次の通りです。
id: pg-building
type: fill
source: v
source-layer: building
filter: [
match
[
get
building
]
[
train_station
roof
]
false
[
match
[
geometry-type
]
[
Polygon
MultiPolygon
]
true
false
]
]
paint: {
fill-color: [
match
[
get
layer
]
[
"-1"
"-2"
"-3"
"-4"
"-5"
]
[
rgb
238
238
238
]
[
rgb
222
215
215
]
]
}
train_station と roof を外すという調整はしていますが、基本的には素直なポリゴン描画のスタイルになっています。
pg-building-train-station
id: pg-building-train-station
type: fill
source: v
source-layer: building
filter: [
match
[
geometry-type
]
[
Polygon
MultiPolygon
]
[
match
[
get
building
]
[
train_station
roof
]
true
[
match
[
get
public_transport
]
station
true
false
]
]
false
]
paint: {
fill-color: [
match
[
get
layer
]
[
"-1"
"-2"
"-3"
"-4"
"-5"
]
[
rgb
238
238
238
]
[
rgb
222
215
215
]
]
fill-opacity: [
interpolate
[
linear
]
[
zoom
]
16
1
17
0.4
]
}
fill-opacity のところに、ズームによって透過率を変えるという expression を入れているところが特徴です。つまり、
(interpolate (linear) (zoom) 16 1 17 0.4)
という表現を入れることで、ズームレベルが17になったら opacity を 0.4 に下げるということをしています。
雑談になりますが、expression は Lisp で書きたくなりますね。Mapbox Style の仕様にも、次のとおり書いてあります。
Mapbox GL JS expressions uses a Lisp-like syntax, represented using JSON arrays.
pg-building-outline
id: pg-building-outline
type: line
source: v
source-layer: building
minzoom: 14
include _polygon
paint: {
line-color: [
rgb
183
174
174
]
line-width: 1
}
フチを強調するためのアウトラインです。
このあと、smellman から次のヒントをもらいました。
高さってこれかな?
https://github.com/openmaptiles/openmaptiles/blob/master/layers/building/building.sql#L101
OpenMapTilesではlevels*3.66としています。
これが「データベース」に入ってるというのがポイントです。
これをベースに、https://github.com/unvt/mame を実装しました。
建物の高さ設定の具体的なところは、https://github.com/unvt/mame/blob/master/hocon/pg-building.conf に書いてあり、その主要な部分は次の通りです。
fill-extrusion-height: [
max
[
to-number
[
get
height
]
]
[
"*"
[
to-number
[
get
"building:levels"
]
]
3.66
]
5
]
Mapbox Expression の to-number
は、数が得られないときに null を返すわけではなく、 0 や 1を返すので coalesce ではなくて max で代用しています。
感想
私の流儀というのは、昔から、「地理空間情報、データベース、ウェブ」という三層の真ん中をなるべく薄くして地理空間情報とウェブを直結したい、というものだと思います。データベースがボトルネックになり、またパフォーマンスとセキュリティの問題源になることを本能的に恐れる傾向があり、データの設計でデータベースの介在を回避できるというアイディアに賭ける傾向がある。手段として、データベースの代わりにストリームを持ってこようとする傾向がある。計算機科学的には、私は随分と古典的な人間なのだなあと思います。古典的で、プラクティカルであろうとする傾向があると思います。