1
2

More than 1 year has passed since last update.

サイクルコンピュータのGPSログデータをMapbox GL JSで表示してみました

Posted at

はじめに

  • サイクルコンピュータ(Garmin)のGPSログデータ(gpxファイルをgeojsonファイルに変換したデータ)をMapbox GL JSで表示してみました。
  • Mapbox GL JSでの表示部分は、こちらのMapboxさんのドキュメントを参考にさせていただきました。
  • Mapbox GL JSのバージョンはv2になります。
  • Mapboxのアクセストークンが必要になります。

アウトプットイメージ

前提条件

  • GPSログデータ(gpxファイル)は、予めQGIS等でgeojsonファイルに変換したデータを用いています。
  • gpxファイルの中からtracksというLineString形式(ジオメトリオブジェクトのtype)のデータをgeojsonファイルに変換しています。
  • QGISでのLineString形式のデータ(geojsonファイル)の抽出イメージは以下のとおりです。 image.png
  • 抽出したgeojsonファイルの形式は以下のとおりです。 image.png
  • GPSログデータ(geojsonファイル)を読み込んでいます。
  • また、3D地形データ3D建物データを読み込んでいます。

html

GPSLog_Animation.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>GPSログアニメーション</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.css" rel="stylesheet">
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.js"></script>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <div id="map"></div>
    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="script.js"></script>
</body>

</html>

CSS

style.css
body {
  margin: 0;
  padding: 0;
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

JavaScript

script.js
mapboxgl.accessToken = 'Mapboxのアクセストークンを入力してください';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox-map-design/ckhqrf2tz0dt119ny6azh975y',
    zoom: 0
});

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
        }
    });
    // We use D3 to fetch the JSON here so that we can parse and use it separately
    // from GL JS's use in the added source. You can use any request method (library
    // or otherwise) that you want.
    d3.json(
        'data/activity_6257932835 tracks.geojson',
        function (err, data) {
            if (err) throw err;

            // save full coordinate list for later
            var coordinates = data.features[0].geometry.coordinates;

            // start by showing just the first coordinate
            data.features[0].geometry.coordinates = [coordinates[0]];

            // add it to the map
            map.addSource('trace', { type: 'geojson', data: data });
            map.addLayer({
                'id': 'trace',
                'type': 'line',
                'source': 'trace',
                'paint': {
                    'line-color': 'yellow',
                    'line-opacity': 0.75,
                    'line-width': 7
                }
            });

            // setup the viewport
            map.jumpTo({ 'center': coordinates[0], 'zoom': 14 });
            map.setPitch(30);

            // on a regular basis, add more coordinates from the saved list and update the map
            var i = 0;
            var timer = window.setInterval(function () {
                if (i < coordinates.length) {
                    data.features[0].geometry.coordinates.push(
                        coordinates[i]
                    );
                    map.getSource('trace').setData(data);
                    map.panTo(coordinates[i]);
                    i++;
                } else {
                    window.clearInterval(timer);
                }
            }, 10);
        }
    );
});

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

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

参考文献

1
2
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
2