dayjournal memo

Total 975 articles!!

Try #012 – MapboxGLJSで大量のGeoJSONを表示してみた

Yasunori Kirimoto's avatar

画像


画像



大量のポイントデータをMapboxGLJSで表示してみました!


これまでは、Leaflet等のライブラリを利用すると、大量のGeoJSONを一度で表示すると表示が重くなったりブラウザが落ちていました。(Leaflet v1.x.だと表示の重さはだいぶ改善されていますが)


MapboxGLJSを利用すると、GeoJSONを表示する時に内部でベクトルタイル化しているらしくかなり早く描画されます。


初期読み込みさえしてしまえば、大量のGeoJSONを問題なく読み込むことができます。


それでも重くなってしまった場合は、既存でクラスタリングが利用できたり、バイナリベクトルタイルを作成するとさらに描画に耐えることができます。



利用データとビルド環境

表示データ国土数値情報の都市公園データを利用
ビルド環境mapboxgljs-starterを利用


example


mapboxgljs-starterに下記コードを追加すると構築可能です。GeoJSONはお好きなデータを利用してください。


./_resouce/js

script.js

// MIERUNE MONO読み込み
var map = new mapboxgl.Map({
    container: "map",
    style: {
        "version": 8,
        "sources": {
            "MIERUNEMAP": {
                "type": "raster",
                "tiles": ['https://tile.mierune.co.jp/mierune_mono/{z}/{x}/{y}.png'],
                "tileSize": 256
            }
        },
        "layers": [{
            "id": "MIERUNEMAP",
            "type": "raster",
            "source": "MIERUNEMAP",
            "minzoom": 0,
            "maxzoom": 18
        }]
    },
    center: [139.767, 35.681],
    zoom: 9
});

map.on('load', function () {

    // ポイント設定
    map.addSource('park', {
        type: 'geojson',
        data: './vector/park.geojson'
    });

    // スタイル設定
    map.addLayer({
        "id": "park",
        "type": "circle",
        "source": "park",
        "layout": {},
        "paint": {
            "circle-color": "#1253A4",
            "circle-radius": 7,
            "circle-opacity": 0.7
        }
    });

    //ポイントクリックイベント
    map.on('click', 'park', function (e) {
        var coordinates = e.lngLat;
        // 属性設定
        var description =
            '公園名: ' + e.features[0].properties.P13_003 + '<br>' +
            '住所: ' + e.features[0].properties.P13_006 + '<br>' ;
        while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
        }
        new mapboxgl.Popup()
            .setLngLat(coordinates)
            .setHTML(description)
            .addTo(map);
    });
    // カーソルON,OFF
    map.on('mouseenter', 'park', function () {
        map.getCanvas().style.cursor = 'pointer';
    });
    map.on('mouseleave', 'park', function () {
        map.getCanvas().style.cursor = '';
    });

});

// コントロール表示
map.addControl(new mapboxgl.NavigationControl());


./dist/vector

park.geojson


{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "P13_001": "神奈川県", "P13_002": null, "P13_003": "三ツ池公園", "P13_004": 4, "P13_005": "神奈川県", "P13_006": "横浜市", "P13_007": 1957, "P13_008": 296800, "P13_009": 2, "P13_010": null }, "geometry": { "type": "Point", "coordinates": [ 139.66264437000001, 35.52145024 ] } },
{ "type": "Feature", "properties": { "P13_001": "神奈川県", "P13_002": null, "P13_003": "保土ケ谷公園", "P13_004": 5, "P13_005": "神奈川県", "P13_006": "横浜市", "P13_007": 1957, "P13_008": 340000, "P13_009": 2, "P13_010": null }, "geometry": { "type": "Point", "coordinates": [ 139.58379783, 35.45396035 ] } },
{ "type": "Feature", "properties": { "P13_001": "神奈川県", "P13_002": null, "P13_003": "四季の森公園", "P13_004": 9, "P13_005": "神奈川県", "P13_006": "横浜市", "P13_007": 1988, "P13_008": 452800, "P13_009": 2, "P13_010": null }, "geometry": { "type": "Point", "coordinates": [ 139.53694834, 35.50580062 ] } },

・・・・・



今まで表示が重かった大量のGeoJSONでも、MapboxGLJSを利用するとさくっとフロントエンドだけで表示できますね!



book

Q&A