地図データを扱うJavaScriptライブラリ「Leaflet」を使って、GPSログ(GPXファイル)の地図表示を試している。
今回、GPXファイルをURLで任意指定できるようにした。
サーバーローカルにGPXファイルを置いて指定するか、任意のサーバーにGPXファイルを置いて指定する。ただ、別サーバーのGPXファイルが指定可能かどうかは環境による。
今まで、GPXのルートログを地図表示するのに、「Leaflet」のプラグイン「leaflet-gpx」を使ってきた。今回、「leaflet-gpx」を使わないバージョンも作成。
■「leaflet-gpx」を使うバージョン
https://ok2nd.github.io/leaflet/gpx-leaflet-gpx.html
使用形式: https://ok2nd.github.io/leaflet/gpx-leaflet-gpx.html?gpx=xxx.gpx
サンプル >>> https://ok2nd.github.io/leaflet/gpx-leaflet-gpx.html?gpx=gpx/2020_12_05_10_43_35.gpx
■「leaflet-gpx」を使わないバージョン
https://ok2nd.github.io/leaflet/gpx.html
使用形式: https://ok2nd.github.io/leaflet/gpx.html?gpx=xxx.gpx
サンプル >>> https://ok2nd.github.io/leaflet/gpx.html?gpx=gpx/2020_12_05_10_43_35.gpx
【GPX形式サンプル】
<trkpt lat="34.724837" lon="135.158676"> <ele>326.27</ele> <time>2021-05-04T01:34:20.000Z</time> <extensions> <geotracker:meta c="2.91" s="0" /> </extensions> </trkpt>
【プログラムソース抜粋】
URLからのGPXファイル取得は以下。
<script> // https://........./gpx.html?gpx=xxx/xxx.gpx let arg = new Object; let pair = location.search.substring(1).split('&'); for (var i=0; pair[i]; i++) { let kv = pair[i].split('='); arg[kv[0]] = kv[1]; } if (typeof arg.gpx === 'undefined' || arg.gpx == '') { // arg.gpx: gpxファイル名('xxx/xxx.gpx') let div = document.getElementById('container'); let href = location.href.split('?'); div.innerHTML = '<div class="msg"><p>GPXファイルを指定してください。</p><p>例:' + href[0] + '<span class="emp">?gpx=xxx/xxx.gpx</span></p></div>'; } else { var request = new XMLHttpRequest(); request.open('get', arg.gpx, false); request.send(null); if (request.status == 404) { let div = document.getElementById('container'); div.innerHTML = '<div class="msg"><p>GPXファイル(<span class="emp">' + arg.gpx + '</span>)が見つかりません。</span></p></div>'; } else { gpx2map(request.responseText); // request.responseText: gpxデータ } } </script>
gpx2map()の中の抜粋。L.polyline()でルートを表示。
function gpx2map(gpxStr, resetBtn=false) { map = L.map('map'); var parser = new DOMParser(); var gpx = parser.parseFromString(gpxStr, 'text/xml'); var elements = gpx.getElementsByTagName('trkpt'); var routeLatLng = []; for (var i=0; i<(elements.length); i++) { let pos = gpxParse(elements.item(i)); routeLatLng[i] = [pos['lat'], pos['lon']]; } L.polyline(routeLatLng, {color: '#3B83CC', weight: 5}).addTo(map); } function gpxParse(trkpt) { var timeTxt = trkpt.getElementsByTagName('time')[0].textContent; var time = new Date(timeTxt); return { lat: parseFloat(trkpt.getAttribute('lat')), lon: parseFloat(trkpt.getAttribute('lon')), time: time, dateStr: time.toLocaleDateString(), timeStr: time.toLocaleTimeString(), ele: trkpt.getElementsByTagName('ele')[0].textContent }; }