地理院ベクトルタイルをクリスマスにする

これはFOSS4G AdventCalendar 2024 (シリーズ2)の10日目の記事です。

私もすっかりおじさんですが、こちらの記事にヒントを得て、おじさんでも童心に返れる地図を作成してみました😆
qiita.com

完成イメージ


https://tmizu23.github.io/advent2024/santa.html#15.66/35.691993/138.486518/-11.4/79

作り方

① noto-emojiをダウンロードします。

noto-emojiのサイトから一式ダウンロードします。svgフォルダから使用する画像を選別して、わかりやすいファイル名に変更しておきましょう。

② spreetを利用してsvgからスプライトを作成します。

スプライトとは地図上で使用するアイコンを一つの画像にまとめたものです。svgからスプライトを作成するためにspreetを利用します。spreetをインストールして、以下のコマンドを打つと、svgフォルダに入っている画像からmy_symbol.pngとmy_symbol.jsonが作成されます。pngは画像をまとめたもの、jsonは各画像の位置と名前が記録されています。高解像度用のファイルも--retinaのオプションをつけて作成します。

spreet svg my_symbol
spreet --retina svg my_symbol@2x

作成したファイル一式はspriteフォルダに入れて自分のウェブサイトにアップロードしておきます。

https://tmizu23.github.io/advent2024/sprite/my_symbol.png

③ 地理院ベクトルタイルのスタイルを用意します。

地理院地図の標準のスタイル(std.json)が以下にあるので取ってきます。
github.com

④ std.jsonの"sprite"を変更します。

自分が作成したスプライトを読み込めるようにstd.jsonの"sprite"の行を以下のように変更します。idは、元のものを"default"にして、自分で作成したものを今回は"custom"にしておきます。urlはspriteフォルダをアップロードした場所にスプライトのファイル名(拡張子を除く)を加えたものになります。

"sprite": [{ id: "default", url: "https://gsi-cyberjapan.github.io/optimal_bvmap/sprite/std" },
{ id: "custom", url: "https://tmizu23.github.io/advent2024/sprite/my_symbol" }],

※この方法はmaplibreでの仕様です。

⑤ 地図記号を置き換えます。

既存の地図記号を自分で作成したスプライトのアイコンに置き換えます。アドベントカレンダーなのでクリスマス風にします。

三角点をベルに、電子基準点をケーキに、水準点はプレゼントに、そして老人ホームはサンタさんに、発電所等はトナカイにしました。また、学校は子どもたちに、寺院は雪だるまに、果樹園はクリスマスソングの音符に、城跡も洋風のキャッスルになってます。ついでに、風車も鳥やコウモリが衝突しないように、こいのぼりにしておきました。

まるでシンデレラの魔法使いの気分です。もしくはマッチ売りのおっさんが最期の灯火で見ている幻想です。

そのほかの地図記号も、なるべく元の意味を損なわないように置き換えます。(しっくりくるものがない場合は、虫や動物になってます)
こんな感じです。

  • 三角点 → ベル
  • 電子基準点 → ケーキ
  • 水準点 → プレゼント
  • 老人ホーム → サンタ
  • 発電所等 → トナカイ
  • 標高点(測点) → スター
  • ç”° → ゆき
  • 寺院 → 雪だるま
  • 神社 → 神社
  • 温泉 → 温泉
  • 墓地 → おばけ
  • 果樹園 → おんぷ
  • 城跡 → キャッスル
  • 風車 → こいのぼり
  • 小学校 → 小学生
  • 高等学校・中等教育学校 → 高校生
  • 警察署 → 警察官
  • 消防署 → 消防士
  • 主要な港 → フェリー
  • 港湾 → 釣船
  • 漁港 → さかな
  • 主要な空港 → 飛行機
  • 町村役場・政令指定都市の区役所 → 建物
  • 外国公館 → 風船
  • 灯台 → æ³¢
  • ç•‘ → チューリップ
  • 茶畑 → 葉っぱ
  • 広葉樹林 → 広葉樹
  • 針葉樹林 → 針葉樹
  • 竹林 → 七夕
  • 荒地 → サル
  • 油井・ガス井 → アリ
  • 電波塔 → カモ
  • 噴火口・噴気口 → ワシ
  • 博物館法の登録博物館・博物館相当施設 → ネコ

⑥ ベクトルタイルのスタイルstd.jsonのアイコン名を変更します。

上記のとおりにアイコンのファイル名を置換すれば良いのですが、その際に④で指定したid(今回はcustom)をコロン:でくっつけます。defaultのアイコンは、そのままでOKです。

⑥ maplibreでスタイルを読み込みます。

あとは、maplibreでスタイルを読み込んで地図を仕上げます。レイヤーやコントーロールを付け足して完成です。コード一式はこちらにあります。GitHub - tmizu23/advent2024

コツ・ポイント

お好みでアイコンを点滅させることもできます。

まず点滅させたいアイコンのレイヤーをスタイルに追加します。

{
    "id": "スターレイヤ",
    "type": "symbol",
    "source": "v",
    "source-layer": "Anno",
    "filter": ["==", ["get", "vt_code"], 7102], // 三角点に該当するフィルタ
    "layout": {
        "icon-allow-overlap": true,
        "icon-image": "custom:スター", // 初期アイコンを設定
        "icon-size": 0.3,
    }
}

次に以下のコードでアイコンを切り替えることで点滅させます。intervalを変えれば点滅スピードを変更できます。

map.on('load', () => {
            const frames = ["custom:スター", ""];
            const interval = 1000;
            let frameIndex = 0;

            setInterval(() => {
                const currentFrame = frames[frameIndex];
                frameIndex = (frameIndex + 1) % frames.length;
                map.setLayoutProperty("スターレイヤ", "icon-image", currentFrame);
            }, interval);
});

感想

冗談半分で地図記号を変えてみましたが、外国人にわかりやすい地図作成の取り組み | 国土地理院 という公式のものがあります。地図記号も用途によって変更すると見え方が違って面白いですね。ベクトルタイルならそれが簡単にできました。では、良いクリスマスを!