HTMLとJavaScriptライブラリを使って自分だけの地図表示ノートを構築した筆者(記事)。HTML一枚とJavaScriptによるカスタマイズだけなので、痒いところに手が届く改良を簡単にできるのと、スマートフォンで使えば位置情報と併せて実用的な使い方ができる。

国土地理院の地図

国土交通省 国土地理院

国土交通省 国土地理院

手軽にできそうなものは無いかと思案していると、地図の変更が簡単そうだ。OpenStreetMapをレイヤーに使っているが、同様の枠組みで使える地図は案外多い。国土交通省 国土地理院のマップもそのひとつだ。"国土を測る・描く・守る・伝える"を掲げる国土地理院では、社会インフラを支えるため、日本の位置の基準を整備。産学官が連携するGeospatial Technologyのイベント「G空間EXPO」なども開催している。

国土地理院のマップはhttps://maps.gsi.go.jp/で何種類かを変えながら確認できるが、標高や等高線、地形分類の詳細さに特徴がある。

  • https://maps.gsi.go.jp/。左上のメニューから地図の種類を変えられる

    https://maps.gsi.go.jp/。左上のメニューから地図の種類を変えられる

  • 建物の平面形状がとても詳細なデフォルトの標準地図

    建物の平面形状がとても詳細なデフォルトの標準地図

  • マーカーなどが上に重ねる情報が目立ちやすい淡色地図

    マーカーなどが上に重ねる情報が目立ちやすい淡色地図

  • 行政境界区分しか表示されない白地図

    行政境界区分しか表示されない白地図

  • 航空写真で構成される地図

    航空写真で構成される地図

  • 英語表記の地図

    英語表記の地図

国土地理院タイルを読み込んでみる

国土地理院タイルの詳細はこちらのページに掲載されているが、Webサイトやソフトウェア、アプリケーション上でリアルタイムに読み込んで利用する場合、地理院タイルは出典の明示のみで申請不要で、地理院タイル一覧ページ(https://maps.gsi.go.jp/development/ichiran.html)へのリンクを貼る。

データの変更はLeaflet.jsでは簡単にできる。以下のレイヤー読み込み部分

  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

を下記の公式配信サーバに変える。

L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
attribution: '<a href="https://www.gsi.go.jp/">国土地理院タイル</a>'
}).addTo(map);

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Leaflet Test</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  <style>
    #map { height: 400px; }
    #memos {
      margin-top: 10px;
      font-family: sans-serif;
    }
  </style>
</head>
<body>
  <div id="map"></div>



  <div id="memos"></div>
<script>
  const map = L.map('map').setView([35.68, 139.76], 13);
  // ★New 国土地理院タイルに(2行)
L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
attribution: '<a href="https://maps.gsi.go.jp/development/ichiran.html">国土地理院タイル</a>'
}).addTo(map);


  //  永続化されたメモを復元(最短3行)
  const list = JSON.parse(localStorage.getItem("memoList") || "[]");
  list.forEach(m => {
    L.marker([m.lat, m.lng]).addTo(map).bindPopup(m.memo);
  });
  // メモ一覧表示
 document.getElementById("memos").innerHTML = list.map(m => m.date + " " + m.lat + "," + m.lng + " " + m.memo).join("<br>");
  const locateControl = L.control({ position: 'topleft' });

  locateControl.onAdd = function () {
    const btn = L.DomUtil.create('button', '');
    btn.innerHTML = '🚩 現在地';

    btn.onclick = function () {
      navigator.geolocation.getCurrentPosition((pos) => {
        const lat = pos.coords.latitude;
        const lng = pos.coords.longitude;

        L.marker([lat, lng]).addTo(map)
          .bindPopup('あなたの現在地')
          .openPopup();

        map.setView([lat, lng], 15);

        //  メモ追加(永続化3行だけ)
        const memo = prompt("この場所のメモを入力");
        if (memo) {
          L.marker([lat, lng]).addTo(map).bindPopup(memo);

          const list = JSON.parse(localStorage.getItem("memoList") || "[]");
          list.push({
             lat,
             lng,
             memo,
             date: new Date().toLocaleString()
          });
          localStorage.setItem("memoList", JSON.stringify(list));

        // 一覧更新
          document.getElementById("memos").innerHTML = list.map(m => m.date + " " + m.lat + "," + m.lng + " " + m.memo).join("<br>");
        }
      });
    };

    return btn;
  };

  locateControl.addTo(map);
</script>

</body>
</html>

これをアップロードしてブラウザでアクセスすると

  • 地理院タイルのデフォルト地図で表示される

    地理院タイルのデフォルト地図で表示される

航空写真をタイルに表示させてみる

今度は航空写真に変えてみよう。航空写真は以下に変える。

https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg

これを実行すると航空写真に切り替わる。キャッシュが強いので変わらない場合はF5キーの再読み込みなどをするとよい。

  • 航空写真で現在位置クリック

    航空写真で現在位置クリック

都心部を散策していると思わず緑の公園を探してしまうこともあるが、これなら現在位置から直感で探し出すことができる。地図といってもGoogleMapsだけではなく、多様なマップがあるので、細かく趣味に用途に応じたマップを取り込んでいくと、より深掘りした面白さがありそうだ。そうおもた。