GLJSの条件式をユースケースごとにまとめてみた
GLJSの条件式をユースケースごとにまとめてみた
はじめに
アイディオットCTOの小倉です。
今回は、mapbox GLJSの実装で利用する条件式についてお話します。
mapboxの条件式について
普段我々がコードの中で利用する条件式について、mapbox GLJSにおいては特殊な記述方法があります。
例えばFeatureにvalue
というプロパティがあり、
以下のような条件式があるとします。
if (value === 'foo') {
return '#ff0000';
} else if (value === 'bar') {
return '#00ff00';
} else {
return '#000000';
}
mapbox GLJSでは、以下のようなLispライクな条件式で記述します。
[
'match',
['get', 'value'],
'foo',
'#ff0000',
'bar',
'#00ff00',
'#000000'
]
今回行うこと
上記の通り、mapbox GLJSでは条件式の記述方法はなかなか馴染みがないこともあり、実装の中でどう書けばいいのか悩むこともあると思います。
今回は条件式として書くことがありそうなものをユースケースとして想定して、JavaScriptでの条件式とmapbox GLJSでの条件式を比較したものを紹介しようと思います。
扱うサンプルコードについては、試して頂きやすいように、公式のEXAMPLESにあるCreate and style clustersを利用します。
こちらの実装例の中で、円のクラスターを描画するレイヤーにおいて、下記のコードのようにpoint_count
というクラスタリングされた円の数を表す属性値を利用して、クラスターの数に応じて円の色を変えるという処理を行っており、その部分を変更する形で進めていきます。
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'earthquakes',
filter: ['has', 'point_count'],
paint: {
// こちらのpaintプロパティの circle-color を変更します。
'circle-color': [
'step',
['get', 'point_count'],
'#51bbd6',
100,
'#f1f075',
750,
'#f28cb1'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
});
ユースケース
(1) まずは条件式を全く使わないケースで、単純に白くする。
JavaScript
paint['circleColor'] = '#ffffff'
GLJS
paint: {
'circle-color': '#ffffff'
}
結果
point_count
が300以上で赤くし、それ以外は白くする。
(2) JavaScript
if (point_count >= 300) {
paint['circleColor'] = '#ff0000'
} else {
paint['circleColor'] = '#ffffff'
}
GLJS
step関数を利用するパターン。
paint: {
'circle-color': [
'step',
['get', 'point_count'],
'#ffffff',
300,
'#ff0000',
],
}
case関数を利用して、演算子を利用するパターン。
paint: {
'circle-color': [
'case',
['>=', ['get', 'point_count'], 300],
'#ff0000',
'#ffffff',
],
}
結果
point_count
が5, 255, 106の場合赤くし、それ以外は白くする。
(3) JavaScript
if (point_count === 5 || point_count === 255 || point_count === 106) {
paint['circleColor'] = '#ff0000'
} else {
paint['circleColor'] = '#ffffff'
}
GLJS
match関数を利用します。
paint: {
'circle-color': [
'match',
['get', 'point_count'],
5,
'#ff0000',
255,
'#ff0000',
106,
'#ff0000',
'#ffffff',
],
}
リスト化することもできます。
paint: {
'circle-color': [
'match',
['get', 'point_count'],
[5, 255, 106],
'#ff0000',
'#ffffff',
],
}
結果
point_count
が300以上かつ5の倍数の場合緑にする。それ以外は白くする。
(4) if (point_count >= 300 && point_count % 5 === 0) {
paint['circleColor'] = '#00ff00'
} else {
paint['circleColor'] = '#ffffff'
}
GLJS
all関数を利用して &&
を表現します。
ちなみに ||
を表現する場合はany関数を利用します。
paint: {
'circle-color': [
'case',
[
'all',
['>=', ['get', 'point_count'], 300],
['==', ['%', ['get', 'point_count'], 5], 0]
],
'#00ff00',
'#ffffff',
],
}
結果
point_count
が300より小さい場合は青くし、300以上かつ5の倍数の場合緑に、2の倍数の場合は赤くする。それ以外は白くする。
(5) JavaScript
if (point_count >= 300) {
if (point_count % 5 === 0) {
paint['circleColor'] = '#00ff00'
} else if (point_count % 2 === 0) {
paint['circleColor'] = '#ff0000'
} else {
paint['circleColor'] = '#ffffff'
}
} else {
paint['circleColor'] = '#0000ff'
}
GLJS
入れ子の条件式は以下のように記述します。
paint: {
'circle-color': [
'step',
['get', 'point_count'],
'#0000ff',
300,
[
'case',
['==', ['%', ['get', 'point_count'], 5], 0],
'#00ff00',
['==', ['%', ['get', 'point_count'], 2], 0],
'#ff0000',
'#ffffff',
],
],
}
結果
まとめ
いかがでしたでしょうか。
mapbox GLJSの条件式は、JavaScriptの条件式とは異なる記述方法になっていますが、
ユースケースに応じて、条件式を組み合わせることで、JavaScriptの条件式と同じようなことができることがわかりました。
まだ様々な条件式があると思いますが、今回の記事が少しでもお役にたてればと思います。
Discussion