LoginSignup
1
0

MapLibre GL JSのスタイルファイルの説明とMaputnikでの設定

Last updated at Posted at 2024-06-18

はじめに

以前の記事では、ベクトルタイルのスタイル作成の練習をするために、Maputnikを利用して地理院地図Vectorのスタイルを作成しました。本記事では、作成したスタイルを編集してみようと思います。また、スタイルの基本についても記載します。

MapLibre GL JSのstyleの基本

スタイルファイルは、ルート要素と、その下にぶら下がる入れ子になった要素から成り立ちます。ルート要素について主要なものを以下の表にまとめました。

ルート要素

要素 必須 or オプション 説明
version 必須 8  Style specificationのバージョン
name オプション  "Bright" スタイルの名前、人が見分ける用
metadata オプション  { "maputnik:renderer": "mlgljs" } スタイルファイルがどのように作成されたのか等が記載される。例えば、スタイルエディタのバージョンなど。
center オプション  [138.34, 35.66]  デフォルト中心位置、[経度, 緯度]の順番
zoom  オプション 12.5   デフォルトズームレベル
bearing オプション 29  方位。例えば90であれば、東の方角が上となる。
pitch オプション 59  傾き。0であれば、真上からの視点となる。最大値は60の模様
sources  必須 下段参照  どのデータを表示するのかを指定。sourcesはスタイリングのための色や太さ情報を持っていないため、sourcesを指定するだけでは地図は表示されない。layersが必要。この特性により、一つのソースから複数のスタイルを作成することが出来る。
sprite  オプション "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite"   地図記号、線、ポリゴンの塗りなどに使う画像の場所を指定
glyphs  オプション "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf"   フォントの場所をpbfフォーマットで指定。{fontstack}がフォント名を、{range}がフォントの実体を参照?
layers  必須 下段参照   最重要。スタイルで使用するレイヤを指定。backgroundレイヤを除き、参照するソースを指定する必要あり。

ここで、center、zoom、bearing、pitchについては、htmlファイルでも定義することが出来ます。どちらで定義しても良いのですが、両方で定義するとhtmlファイルの設定が優先されます。

sources

sourcesについては、少し細かく見ていきます。詳しくはMapLibre Style SpecのSourcesにありますが、必要そうな情報を記載します。

記載例は以下の通りです。

"sources": {
    "v": {
      "type": "vector",
      "tiles": [
        "https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf"
      ],
      "minzoom": 4,
      "maxzoom": 16,
      "attribution": "<a href=\"https://maps.gsi.go.jp/vector/\" target=\"_blank\">国土地理院ベクトルタイル提供実験</a>"
    }
  }

sourcesでよく使用されるベクトルタイルのプロパティを表にまとめました。

プロパティ名 必須 or オプション 説明
type 必須 "vector"  ベクトルタイルを指定
url オプション  "https://demotiles.maplibre.org/tiles/tiles.json" ベクトルタイルのソースをjsonファイルのURLで指定する時に使用する
tiles オプション  ["https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf"] ベクトルタイルのソースをpbfのURLで指定する時に使用する
bounds オプション  [123, 24, 147, 44]  地図の南西と北東の角を指定。[sw.lng, sw.lat, ne.lng, ne.lat]の形式で記載。このオプションが記載されていれば、範囲外のタイルはリクエストされない。タイルが読み込まれないだけで、範囲外への移動は可能であることに注意。
minzoom  オプション 0   タイルが存在する最小ズームレベル
maxzoom  オプション 15   タイルが存在する最大ズームレベル。例えば15で指定して、実際のズームレベルが16の場合は、ズームレベル15のタイルがオーバーズーミングされる。
attribution  オプション "<a href="https://maps.gsi.go.jp/vector/" target="_blank">国土地理院ベクトルタイル提供実験"   出典の記載

layers

次に一番重要なレイヤーを見ていきます。レイヤーについても詳しくはMapLibre Style SpecのLayersにありますが、必要そうな情報を記載します。

記載例は以下の通りです。

"layers": [
    {
      "id": "bg",
      "type": "background",
      "paint": { "background-color": "rgba(232, 225, 225, 1)" }
    },
    {
      "id": "coastline",
      "type": "line",
      "source": "v",
      "source-layer": "coastline"
    },
    {
      "id": "waterarea",
      "type": "fill",
      "source": "v",
      "source-layer": "waterarea",
      "paint": { "fill-color": "rgba(20, 101, 223, 1)" }
    }
  ],

こちらもよく使用されるプロパティを表にまとめました。

プロパティ名 必須 or オプション 説明
id 必須 "coastline"  レイヤーidを指定(ユニークな値とする)
type 必須 "fill"  fill: ポリゴン、line: 線、symbol: アイコン or テキストラベル、circle: 円、fill-extrusion: 3Dポリゴン、background: 背景色
source 必須 "v" sourcesで使用したデータソース名称を指定
source-layer 必須 "coastline" ベクトルタイルのソースのどのレイヤを使用するのかを指定
minzoom  オプション 0   レイヤに対する最小ズームレベル。この数値以下のズームレベルでは、該当レイヤは描画されない
maxzoom  オプション 15   レイヤに対する最大ズームレベル。この数値以上のズームレベルでは、該当レイヤは描画されない
filter  オプション 下段参照  ベクトルタイルのプロパティの値を使用して、条件に合致する地物のみを表示する。ベクトルタイルレイヤの地物を全て表示するときにはfilterは不要。
layout  オプション 下段参照  レイヤーをどのように表示するか指定するプロパティ(Line及びSymbolのみ)
paint  オプション 下段参照  レイヤーをどのように描画するか指定するプロパティ

Maputnikでのスタイルの編集

次にMaputnikで実際にスタイルの編集をしてみます。
以前の記事でも紹介した地理院地図Vector提供実験のウェブサイトの属性等の仕様詳細を見ながら作業します。今回は、建物データをMaputnikで編集します。
建物の属性を見てみると、以下の図のように記載されています。
GSeditI.JPG

さらに簡潔に表にしてみると以下になります。

地物名 source-layer ftCode ズームレベル
普通建物 building 3101  15, 16
堅ろう建物 building 3102  14, 15, 16
高層建物 building 3103  14, 15, 16
普通無壁舎 building 3111  15, 16
堅ろう無壁舎 building 3112  15, 16

layersでのminzoom, maxzoomと、オリジナルデータとの関係

例えば、普通建物のデータはズームレベル15,16に存在していますが、layersにおいてminzoomを16とすると、ズームレベル16まではデータが存在するにも関わらず、表示されないこととなります。

filter

これらをMaputnikのfilterを使用して編集してみます。

IDをbuilding3101として新しくレイヤを追加しました。

Maputnik1.JPG

そして、適当に建物に色をつけて表示させると以下の図のようになります。
Maputnik2.JPG

ここで、Filterを使用して、ftCodeが3101の普通建物のみ表示させてみます。
「Filter」は「every filter matches」を選択し、「ftCode == 3101」とします。そうすると、ftCodeが3101の普通建物のみ表示されました。先ほどの画像と比べて、表示されている建物の数が減っていますね。

Maputnik3edit.JPG

ちなみに、画面下部におけるJSON Editorでは以下のように示されています。
MaputnikJson1.JPG

次にIDをbuilding3102_3103として新しくレイヤを追加しました。

Maputnik4.JPG

Filterを使用して、堅ろう建物(3102)と高層建物(3103)を表示させてみます。
「Filter」は「any filter matches」を選択し、「ftCode == 3102」、「ftCode == 3103」とします。建物に青っぽい色をつけて、堅ろう建物(3102)と高層建物(3103)を表示しました。

Maputnik5edit.JPG

ここで、「no filter matches」としてみると、堅ろう建物(3102)と高層建物(3103)以外の建物、つまり普通建物(3101)、普通無壁舎(3111)、堅ろう無壁舎(3112)が表示されます。さらに、Layersの順番をbuilding3101を一番下に持ってくる(画面上では一番上に表示される)と普通無壁舎(3111)、堅ろう無壁舎(3112)が青色で表示されます。これはつまり、普通建物(3101)、普通無壁舎(3111)、堅ろう無壁舎(3112)が青色で表示されており、その上からbuilding3101により普通建物(3101)が灰色で塗られているため、普通無壁舎(3111)、堅ろう無壁舎(3112)のみが青色で表示されているということです。

Maputnik6edit.JPG


filterの3つの機能をまとめてみると以下になります。
①every filter matches:記載されているすべての条件を満たす地物を表示
今は一つの条件しかありませんが、複数の条件がある場合において、一つでもfalseがあると条件が満たされません。
JSONファイルでは"all"を使用し、以下のように記載されています。

  "filter": [
    "all",
    ["==", "ftCode", 3101]
  ]

allについては、MapLibre Expressionsのallに詳しく記載されています。


②any filter matches:記載されているいずれかの条件を満たす地物を表示
今回の例では、堅ろう建物(3102)と高層建物(3103)の両方が条件を満たします。
JSONファイルでは"any"を使用し、以下のように記載されています。

  "filter": [
    "any",
    ["==", "ftCode", 3102],
    ["==", "ftCode", 3103]
  ]

anyについては、MapLibre Expressionsのanyに詳しく記載されています。


③no filter matches:記載されている条件をすべて満たさない地物を表示
JSONファイルでは"none"を使用し、以下のように記載されています。

  "filter": [
    "none",
    ["==", "ftCode", 3102],
    ["==", "ftCode", 3103]
  ]

noneについては、なぜかMapLibre Expressionsに記載がありませんでした。

Maputnikから作成したJSONファイルをエクスポートして、"center"と"zoom"の値を編集したものは以下になります。

style2.json
{
  "version": 8,
  "name": "Empty Style",
  "metadata": { "maputnik:renderer": "mlgljs" },
  "center": [139.80336, 35.74141],
  "zoom": 15,
  "sources": {
    "v": {
      "type": "vector",
      "tiles": [
        "https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf"
      ],
      "minzoom": 4,
      "maxzoom": 16,
      "attribution": "<a href=\"https://maps.gsi.go.jp/vector/\" target=\"_blank\">国土地理院ベクトルタイル提供実験</a>",
      "bounds": [123, 24, 147, 44]
    }
  },
  "sprite": "",
  "glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf",
  "layers": [
    {
      "id": "bg",
      "type": "background",
      "paint": { "background-color": "rgba(232, 225, 225, 1)" }
    },
    {
      "id": "coastline",
      "type": "line",
      "source": "v",
      "source-layer": "coastline"
    },
    {
      "id": "waterarea",
      "type": "fill",
      "source": "v",
      "source-layer": "waterarea",
      "paint": { "fill-color": "rgba(20, 101, 223, 1)" }
    },
    {
      "id": "building3102_3103",
      "type": "fill",
      "source": "v",
      "source-layer": "building",
      "filter": ["none", ["==", "ftCode", 3102], ["==", "ftCode", 3103]],
      "paint": { "fill-color": "rgba(71, 102, 191, 1)" }
    },
    {
      "id": "building3101",
      "type": "fill",
      "source": "v",
      "source-layer": "building",
      "filter": ["all", ["==", "ftCode", 3101]],
      "layout": { "visibility": "visible" },
      "paint": { "fill-color": "rgba(146, 134, 134, 1)" }
    }
  ],
  "id": "hfkgus5"
}

MapLibre GL JSで表示させてみました。

また、設定したスタイルファイルでのMaputnikのリンクはこちらです。

今回はレイヤを分けましたが、MapLibre GL JSではmatchなどを使用するとレイヤを分けずに書けるのかもしれません。今後試してみたいと思います。

Paint properties

次にMaputnikのPaint propertiesの機能について見ていきたいと思います。

共通設定

Opacity : 透過度。1が100%(不透明)で0が0%(透明)です。

Color : 色指定。カラーネーム(ex. red)、カラーコード(ex. #000000は黒)、RGB関数(ex. rgba(240, 90, 70, .75))、HSLa(ex. hsla(240, 90%, 70%, .75))などが使用できます。

Pattern: 塗りつぶす画像を指定します。

Type: Background

背景を指定します。
https://maplibre.org/maplibre-style-spec/layers/#background

Backgroundでは以下のPaint Properitesが利用可能です。

Maputnikのプロパティ名 MapLibre GL JS デフォルト値 説明
Color background-color #000000(黒)  背景色。background-patternが設定されている時は無効となる
Pattern background-pattern なし  塗りつぶす画像を指定
Opacity background-opacity 1(透過なし)  背景の透過度

Type: Fill

ポリゴンの塗りつぶしを指定します。建物や水域などの表示に使用します。
https://maplibre.org/maplibre-style-spec/layers/#fill

Fillでは以下のPaint Properitesが利用可能です。

Maputnikのプロパティ名 MapLibre GL JS デフォルト値 説明
Opacity fill-opacity 1(透過なし)  塗りつぶしの透過度
Color fill-color #000000(黒)  塗りつぶす色。fill-patternが設定されている時は無効
Antialias fill-antialias true  trueにするとアンチエイリアス(ギザギザを目立たなくする処理)がオン
Outline color fill-outline-color なし  ポリゴンの外枠の色。有効にするには、fill-antialiasをtrueにする必要あり。fill-patternが設定されている時は無効
Pattern fill-pattern なし  塗りつぶす画像を指定
Translate fill-translate [0, 0]  オフセット(位置を基準点からの距離で表した値)の指定。例えば、[3, 5]だと東に3ピクセル、南に5ピクセル移動
Translate anchor fill-translate-anchor map  fill-translateの設定が必要。map に関連付けるか、viewport に関連付けるかを指定する。mapの場合は地図を回転させても同じようにずれるが、viewportでは地図を回転させるとそれに合わせてTranslateが変動する

Type: Line

ラインの表示を指定します。海岸線などに使用します。
https://maplibre.org/maplibre-style-spec/layers/#line

Lineでは以下のPaint Properitesが利用可能です。

Maputnikのプロパティ名 MapLibre GL JS デフォルト値 説明
Opacity line-opacity 1(透過なし)  ラインの透過度
Color line-color #000000(黒)  ラインの色。line-patternが設定されている時は無効
Width line-width 1  ラインの太さをピクセルで指定
Offset line-offset 0  オフセットの指定
Blur line-blur 0  ぼかしの指定
Dasharray line-dasharray [0, 0]  ダッシュパターンの配列などを指定。例えば、[1, 2]とすれば、1つ線があり、2つ空白があるというイメージ
Pattern line-pattern なし  Spriteの画像を指定。画像の幅は2の倍数である必要がある
Translate line-translate [0, 0]  線のオフセット座標([x, y])を左上を原点として指定
Translate anchor line-translate-anchor map  line-translateの設定が必要。map に関連付けるか、viewport に関連付けるかを指定する。mapの場合は地図を回転させても同じようにずれるが、viewportでは地図を回転させるとそれに合わせてTranslateが変動する
Gap width line-gap-width 0  ラインの外側にラインを描く。値はライン間の距離を示す

Layout properties

次にLayout propertiesを見ていきます。Layout propertyは基本的にはラインとシンボルにのみ存在します。(Fill等でもvisibilityの設定で存在しますが、あまり使わなさそうです。)ここではラインに関するLayout propertyのみ扱います。
https://maplibre.org/maplibre-style-spec/layers/#line

Maputnikのプロパティ名 MapLibre GL JS デフォルト値 説明
Cap line-cap butt  ライン終点の表示。butt: ライン手前終点のお尻に合わせた角型。 round: 丸型。 square: buttと同じ形だが、roundの終点(つまり先に少し伸びている箇所)に合わせた角型
Join line-join miter  ラインが接合される際の形状。bevel: 角型 round: 丸型 miter: とがった形状
Miter Limit line-miter-limit 2  2つのパス区分の継ぎ目が鋭角の場合に line-join を miter から bevel とするための比率。line-joinにおいて、miterであることが必要。
Round limit line-round-limit 1.05  つなぎ目が浅い角度の時に、roundからmiterとする際に使用。line-joinにおいて、roundであることが必要。

まとめ

本記事では、MapLibre GL JSのスタイルファイルの基本と、それがMaputnikでどのように設定されているのかを説明しました。Symbolやズームレベル毎の処理について今回は扱わなかったので、また記事を書こうと思います。

Reference

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0