はじめに
クレヨンで書いたような地図を作ってみたくなり、国土地理院の最適化ベクトルタイルと Mapbox GL JS(Maplibre GL JS も可)で実装してみました。
デモサイト
以下は手書き地図記号付き
実装方法
スタイルで line-pattern
を用いて実現します。これで画像をラインに沿わせて表示させることができるようになります。シームレスなパターンを表示するには、画像の幅は2の累乗とした方が良いです。
{
"type": "line",
"source": "v",
"id": "hoge",
"source-layer": "WL",
"layout": {},
"paint": {
"line-width": 6,
"line-opacity": 1,
"line-pattern": "sky"
}
},
なお、line-pattern
で参照する文字列は、画像は Map インスタンスで取り込んでおく必要があります。本当は sprite 形式で取り込んだ方が通信時のオーバーヘッドを抑えられますが、今回は簡易的に画像を1枚ずつ読むことにします。
また、取り込むのは最初に利用される時とします。参照した画像データがないときに発火する styleimagemissing
という便利なイベントがあります。これを利用して、このイベントが起きた時(つまり、スタイルで最初に利用される時)に、loadImage()
で画像を読み込み、addImage()
でスタイルで使えるように登録します。
map.on('styleimagemissing', (e) => {
const crayon = e.id;
map.loadImage(`./crayon/${crayon}.png`, (error, image) => {
if(error) throw error;
if(!map.hasImage(crayon)) map.addImage(crayon, image);
});
});
パターン用画像の準備
パターン用の画像は簡易的に準備しました。
Windows の「ペイント」ツールでクレヨン風の線を引けるので、これを PowerPoint に取り込んで、トリミングと背景の透過を行います。トリミングの大きさは結構適当です。上で、「画像の幅は2の累乗とした方が良い」と書きましたが、今回の場合は、適当でも見栄えは悪化しませんでした。
なお、line-pattern
では、色を変えることはできないので、必要な色の分だけ、画像を作っておきます。とりあえず、ペイントのパレットにあった内から12色分くらい作りました。
水面だけ、ポリゴンの塗りつぶし用パターンを作成しました。これは、地理院の最適化ベクトルタイルでは、一部のズームレベル帯でポリゴンのみで海岸線を表現しているからです。
ポリゴンの外周をラインとして表示させるテクニックもありますが、この場合、下記の画像のように、ポリゴンに切れ目があると目立ちます。地理院の最適化ベクトルタイルの水面データは、適宜分割されているようですので、関係ないところに線が入ってしまい、かっこ悪いです。そのため、水面だけクレヨン風の塗りつぶし表現とすることにしました。
塗りつぶしの場合、ラインのパターンと違い、きっちり作らないと敷き詰めた際に境界が目立ってしまいます。これをなくそうとすると、ペイントと PowerPoint だけでは厳しいです。今回はある程度で妥協しました。
スタイリングの工夫点
- クレヨンなので、線が細くなりすぎないようにし、また地物の種別毎にあまり太さを変えないようにしました。一方、等高線はうるさくなりすぎるので、色を薄く、太さも補足しています。
- 鉄道は縞々模様(旗竿)を採用しました。クレヨンで書いた線の上に、通常の白色の点線を重ねています。実際クレヨンでこんな細かい芸当は難しいだろうと思いましたが、思いのほかしっくりくるほか、引き締まって見えます。
- 建物は、通常のスタイルで薄く塗りつぶしてみました。建物一つ一つはそんなに大きくないため、普通のべた塗でもあまり違和感は感じないです。
レポジトリ
最後に
手軽に作りましたが、思ったよりクレヨン感が出ていて満足しています。塗りつぶしは今回は色々と妥協しましたが、例えば、クレヨン線画の上から水彩絵の具を塗った時のようなイメージで、良い感じの表現が工夫できそうな気がします。
参考