LoginSignup
8
8

More than 1 year has passed since last update.

Mapboxの3Dデータと土砂災害警戒区域をMapbox GL JSで重ねて表示してみました

Posted at

はじめに

アウトプットイメージ

前提条件

  • Mapbox GL JSのバージョンはv2になります。
  • Mapboxのアクセストークンが必要になります。
  • Mapboxの3D地形及び3D建物の表示では下記のMapboxさんのドキュメンテーションを参考させていただきました。
  • Add 3D terrain to a map
  • 建物を3Dで表示
  • 土砂災害警戒区域には国土数値情報の土砂災害警戒区域データから全国(令和2年)のデータをダウンロードして用いています。
  • 具体には、ダウンロードしたデータの中から土砂災害警戒区域のポリゴンデータである、「A33-20_22Polygon.geojson」のgeojson形式のデータを用いています。

html

3Dterrain_3DBuildings_DisasterArea.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Mapbox3D地形+3D建物+土砂災害警戒区域(急傾斜地の崩壊・土石流・地滑り)</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet">
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <nav id="menu"></nav>
    <div id="map"></div>
    <script src="script.js"></script>
</body>

</html>

CSS

style.css
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }

#menu {
  background: #fff;
  position: absolute;
  z-index: 1;
  top: 10px;
  right: 10px;
  border-radius: 3px;
  width: 240px;
  border: 1px solid rgba(0,0,0,0.4);
}

#menu a {
  font-size: 13px;
  color: #404040;
  display: block;
  margin: 0;
  padding: 10px;
  text-decoration: none;
  border-bottom: 1px solid rgba(0,0,0,0.25);
  text-align: center;
}

#menu a:last-child {
  border: none;
}

#menu a:hover {
  background-color: #f8f8f8;
  color: #404040;
}

#menu a.active {
  background-color: #8DCF3F;
  color: #ffffff;
}

#menu a.active:hover {
  background: #79bb2b;
}

JavaScript

  • Mapboxのアクセストークンを入力してください。
  • 土砂災害警戒区域のレイヤの切り替え(フィルタ機能)では、geojsonファイルの属性の「現象の種類 (A33_001)」を用いています。
  • 現象種別コードはこちらで確認することができます。
script.js
mapboxgl.accessToken = 'Mapboxのアクセストークンを入力してください';
var map = new mapboxgl.Map({
    container: 'map',
    zoom: 16,
    center: [139.0835887, 35.1116931],
    pitch: 85,
    bearing: -45,
    style: 'mapbox://styles/mapbox-map-design/ckhqrf2tz0dt119ny6azh975y'
});

map.on('load', function () {
    map.addSource('mapbox-dem', {
        'type': 'raster-dem',
        'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
        'tileSize': 512,
        'maxzoom': 14
    });
    // add the DEM source as a terrain layer with exaggerated height
    map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });

    // add a sky layer that will show when the map is highly pitched
    map.addLayer({
        'id': 'sky',
        'type': 'sky',
        'paint': {
            'sky-type': 'atmosphere',
            'sky-atmosphere-sun': [0.0, 0.0],
            'sky-atmosphere-sun-intensity': 15
        }
    });

    // 既存の3D建物レイヤを追加
    map.addLayer({
        "id": "3d-buildings",
        "source": "composite",
        "source-layer": "building",
        "filter": ["==", "extrude", "true"],
        "type": "fill-extrusion",
        "minzoom": 10,
        "paint": {
            "fill-extrusion-color": "#ffffff",
            "fill-extrusion-height": [
                "interpolate", ["linear"], ["zoom"],
                10, 0,
                14.05, ["get", "height"]
            ],
            "fill-extrusion-base": [
                "interpolate", ["linear"], ["zoom"],
                10, 0,
                14.05, ["get", "min_height"]
            ],
            "fill-extrusion-opacity": 1.0
        }
    });
    //土砂災害計画区域ポリゴン追加
    map.addSource("MapPolygon", {
        type: "geojson",
        data: "data/A33-20_22Polygon.geojson"
    });
    //地滑り
    map.addLayer({
        id: "MapPolygon3",
        type: "fill",
        source: "MapPolygon",
        layout: {},
        paint: {
            "fill-color": "#ffa500",
            "fill-opacity": 0.5
        },
        filter: ["==", "A33_001", "3"]
    });
    //土石流
    map.addLayer({
        id: "MapPolygon2",
        type: "fill",
        source: "MapPolygon",
        layout: {},
        paint: {
            "fill-color": "#ffff00",
            "fill-opacity": 0.5
        },
        filter: ["==", "A33_001", "2"]
    });
    //急傾斜地の崩壊
    map.addLayer({
        id: "MapPolygon1",
        type: "fill",
        source: "MapPolygon",
        layout: {},
        paint: {
            "fill-color": "#ff00ff",
            "fill-opacity": 0.5
        },
        filter: ["==", "A33_001", "1"]
    });
    //崩壊地等分布図ポリゴン追加
    map.addSource("MapPolygon2", {
        type: "geojson",
        data: "data/Collapsed_Area_20210706.geojson"
    });
    map.addLayer({
        id: "MapPolygon4",
        type: "line",
        source: "MapPolygon2",
        layout: {},
        paint: {
            "line-color": "#ff0000",
            "line-width": 3
        },
    });

    // レイヤ設定
    var Map_AddLayer = {
        MapPolygon1: "土砂災害警戒区域-急傾斜地の崩壊",
        MapPolygon2: "土砂災害警戒区域-土石流",
        MapPolygon3: "土砂災害警戒区域-地滑り"
    };

    // レイヤメニュー作成
    for (var i = 0; i < Object.keys(Map_AddLayer).length; i++) {
        // レイヤID取得
        var id = Object.keys(Map_AddLayer)[i];
        // aタグ作成
        var link = document.createElement("a");
        link.href = "#";
        // id追加
        link.id = id;
        // 名称追加
        link.textContent = Map_AddLayer[id];

        // 初期表示全て表示
        link.className = "active";

        // aタグクリック処理
        link.onclick = function (e) {
            // id取得
            var clickedLayer = this.id;
            e.preventDefault();
            e.stopPropagation();

            // ON/OFF状態取得
            var visibility = map.getLayoutProperty(clickedLayer, "visibility");

            // ON/OFF判断
            if (visibility === 'visible') {
                // クリックしたレイヤを非表示
                map.setLayoutProperty(clickedLayer, 'visibility', 'none');
                this.className = '';
            } else {
                // クリックしたレイヤを表示
                map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
                this.className = 'active';
            }
        };

        // レイヤメニューにレイヤ追加
        var layers = document.getElementById("menu");
        layers.appendChild(link);
    }

});


// コントロール関係表示
var nav = new mapboxgl.NavigationControl();
map.addControl(nav, 'top-left');

// スケール表示
map.addControl(new mapboxgl.ScaleControl({
    maxWidth: 200,
    unit: 'metric'
}));

参考文献

8
8
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
8
8