ブログ
これまでに経験してきたプロジェクトで気になる技術の情報を紹介していきます。
Vue3でMapboxを使用する - レイヤ、ソース編 -
Okuda
2 years
レイヤを追加する
オリジナルのレイヤをセットする
4つのポイントを線と面で表示するために geojson
を作成
任意の場所に設置、今回は \assets\my_geo.json
とする
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "My",
"properties": {
"name": "My neighborhood"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[135.41545700901753, 34.819065318110475],
[135.44067870224166, 34.83651233402895],
[135.45343746865467, 34.82472403614395],
[135.4309363900154, 34.81202795549663]
]
]
]
}
}
]
}
トップレベルにインポートする
import my_geo from "@/assets/my_geo.json";
トップレベルにメソッドを追加
// オリジナルのレイヤをセットする
const setMyLayer = () =>
{
// ソースがあるかチェック
const myLayerSource = map.getSource("my-layer-source");
// ソースがない場合は追加
if (!myLayerSource) {
map.addSource("my-layer-source", {
type: "geojson",
data: my_geo,
});
}
// レイヤを取得
const layers = map.getStyle().layers;
// 面のレイヤがすでにあるかチェック
const myLayer = layers.find((layer) => layer.id === "my-fill");
// ある場合
if (myLayer) {
// visibilityプロパティをトグルする
if (map.getLayoutProperty('my-fill', 'visibility') === 'none') {
// 面のレイヤ
map.setLayoutProperty('my-fill', 'visibility', 'visible');
// 線のレイヤ
map.setLayoutProperty('my-line', 'visibility', 'visible');
// 点のレイヤ
map.setLayoutProperty('my-point', 'visibility', 'visible');
} else {
// 面のレイヤ
map.setLayoutProperty('my-fill', 'visibility', 'none');
// 線のレイヤ
map.setLayoutProperty('my-line', 'visibility', 'none');
// 点のレイヤ
map.setLayoutProperty('my-point', 'visibility', 'none');
}
}
// ない場合は追加
else {
// 面のレイヤ追加
map.addLayer({
id: "my-fill",
type: "fill",
source: "my-layer-source",
'layout': {
// デフォルトでレイヤーを表示
'visibility': 'visible',
},
paint: {
"fill-color": "#943636",
"fill-opacity": 0.5,
},
});
// 線のレイヤ追加
map.addLayer({
id: "my-line",
type: "line",
source: "my-layer-source",
'layout': {
// デフォルトでレイヤーを表示
'visibility': 'visible',
// 接続部を丸く
'line-join': 'round',
// 先端を丸く
'line-cap': 'round',
},
paint: {
"line-color": "#000",
"line-width": 3,
},
});
// 点のレイヤ追加
map.addLayer({
id: "my-point",
type: "circle",
source: "my-layer-source",
'layout': {
// デフォルトでレイヤーを表示
'visibility': 'visible',
},
'paint': {
'circle-radius': 10,
'circle-color': '#F84C4C'
},
});
// 面のレイヤをクリックするとポップアップ
map.on("click", "my-fill", (e) =>
{
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML("my layer!")
.addTo(map);
});
}
};
テンプレート内にボタンを追加
<button @click="setMyLayer">set my layer</button>
3dの建物のレイヤをセットする
トップレベルにメソッドを追加
// 3dの建物のレイヤをセットする
const setBuilding = () =>
{
// レイヤーを取得
const layers = map.getStyle().layers;
// すでにあるかチェック
const buildingLayer = layers.find(
(layer) => layer.id === "add-3d-buildings"
);
// ある場合
if (buildingLayer) {
// visibilityプロパティをトグルする
if (map.getLayoutProperty('add-3d-buildings', 'visibility') === 'none') {
map.setLayoutProperty('add-3d-buildings', 'visibility', 'visible');
} else {
map.setLayoutProperty('add-3d-buildings', 'visibility', 'none');
}
}
// ない場合は追加
else {
// 任意のシンボルレイヤーの下にレイヤーを挿入
const labelLayerId = layers.find(
(layer) => layer.type === "symbol" && layer.layout["text-field"]
).id;
// MapboxStreetsの「building」レイヤー
// ベクタータイルセットには建物の高さデータが含まる
map.addLayer(
{
id: "add-3d-buildings",
source: "composite",
"source-layer": "building",
'layout': {
// デフォルトでレイヤーを表示
'visibility': 'visible',
},
filter: ["==", "extrude", "true"],
type: "fill-extrusion",
minzoom: 15,
paint: {
"fill-extrusion-color": "#aaa", //建物の色
"fill-extrusion-height": // 建物の高さ
[
"interpolate", // スムーズに追加、ニョキッと生えるようになる
["linear"], // 追加時のトランジッション
["zoom"], // ズームインで追加する
15,
0,
15.05,
["get", "height"],
],
"fill-extrusion-base": // 建物の基礎高さ
[
"interpolate",
["linear"],
["zoom"],
15,
0,
15.05,
["get", "min_height"],
],
"fill-extrusion-opacity": 0.6,
},
},
labelLayerId
);
}
};
テンプレート内にボタンを追加
<button @click="setBuilding">set building</button>
等高線のレイヤをセットする
トップレベルにメソッドを追加
// 等高線のレイヤをセットする
const setContour = () =>
{
// ソースがあるかチェック
const contourSource = map.getSource("contour");
// ソースがない場合は追加
if (!contourSource) {
map.addSource("contour", {
type: "vector",
url: 'mapbox://mapbox.mapbox-terrain-v2'
});
}
// レイヤを取得
const layers = map.getStyle().layers;
// 面のレイヤがすでにあるかチェック
const contourLayer = layers.find((layer) => layer.id === "contour-vector");
// ある場合
if (contourLayer) {
if (map.getLayoutProperty('contour-vector', 'visibility') === 'none') {
map.setLayoutProperty('contour-vector', 'visibility', 'visible');
} else {
// 面のレイヤ
map.setLayoutProperty('contour-vector', 'visibility', 'none');
}
}
// ない場合は追加
else {
map.addLayer({
'id': 'contour-vector',
'type': 'line',
'source': 'contour',
'source-layer': 'contour',
'layout': {
'visibility': 'visible',
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#877b59',
'line-width': 1
}
});
}
}
テンプレート内にボタンを追加
<button @click="setContour">set contour</button>
空のレイヤをセットする
次の「- 空に太陽を反映編 -」も参照
onMounted
のなかの map on load
イベントで空レイヤを追加
// 空のレイヤをセット
map.addLayer({
'id': 'sky',
'type': 'sky',
'paint': {
// 空をグラデーションにする
'sky-type': 'gradient',
// 空を表現する
'sky-gradient': [
'interpolate',
['linear'],
['sky-radial-progress'],
0.8,
'rgba(135, 206, 235, 1.0)',
1,
'rgba(0,0,0,0.1)'
],
'sky-gradient-center': [0, 0],
'sky-gradient-radius': 90,
'sky-opacity': [
'interpolate',
['exponential', 0.1],
['zoom'],
5,
0,
22,
1
]
}
});
ソースを追加する
3dの地形のソースをセットする
トップレベルにメソッドを追加
const set3d = () =>
{
// `mapbox-dem`ソースがすでにあるかチェック
const terrainSource = map.getSource("mapbox-dem");
// ない場合は追加
if (!terrainSource) {
map.addSource("mapbox-dem", {
type: "raster-dem",
url: "mapbox://mapbox.mapbox-terrain-dem-v1",
tileSize: 512,
maxzoom: 14,
});
}
// exaggeration 地形の仕様を取得
const terrain = map.getTerrain();
// 誇張度をつかってトグルする
if (terrain?.exaggeration === 1.5) {
// DEMソースを誇張された高さの解除
map.setTerrain({source: "mapbox-dem", exaggeration: 0});
} else {
// DEMソースを誇張された高さの地形レイヤーとして追加
map.setTerrain({source: "mapbox-dem", exaggeration: 1.5});
}
};
テンプレート内にボタンを追加
<button @click="set3d">set 3d</button>
フォグレイヤをセットする
トップレベルにメソッドを追加
// フォグを追加
const setFog = () =>
{
const fog = map.getFog();
if (!fog) {
map.setFog({
'range': [-1, 1.5],
'color': 'white',
'horizon-blend': 0.1
});
} else {
if (fog.color === 'white') {
map.setFog({'color': 'rgba(255, 255, 255, 0)'});
} else {
map.setFog({'color': 'white'});
}
};
}
テンプレート内にボタンを追加
<button @click="setFog">set fog</button>
Vue3でMapboxを使用する - レイヤ、ソース編 -
Vue3でMapboxを使用する - レイヤ、ソース編 -
2022-03-05 18:16:02
2022-03-05 18:25:47
コメントはありません。