みかづきブログ・カスタム

基本的にはちょちょいのほいです。

鎌倉駅までの直線距離を表示するウェブサイトをつくりました 📱

リポジトリ

github.com

制作経緯

navigator.geolocation.watchPositionの検証のために、現在地から鎌倉駅までの直線距離を表示するだけのウェブサイトをつくりました。

developer.mozilla.org

navigator.geolocation.watchPositionを使っているので、ページを更新せずとも、移動のたびに距離が書き換わります。

GPS座標の取得する

navigator.geolocation.watchPositionを使って実装しました。

mozillaのサイトのサンプルを見ればだいたい使い方がわかります。

developer.mozilla.org

ソースコード(抜粋)
navigator.geolocation.watchPosition(handleWatchPosition, null, {
  enableHighAccuracy: true,
  timeout: 60000,
  maximumAge: 0
});

function handleWatchPosition(evt) {
  // const latitude = evt.coords.latitude;
  // const longitude = evt.coords.longitude;
  // const accuracy = evt.coords.accuracy;
  // const altitude = evt.coords.altitude;
  // const altitudeAccuracy = evt.coords.altitudeAccuracy;
  // const heading = evt.coords.heading;
  // const speed = evt.coords.speed;
  // const timestamp = evt.timestamp;

  console.log(evt);
}

とりあえずこんな感じのコードで、移動の度に緯度経度を含んだ様々な情報をログに出力できます。

2つのGPS座標から距離を算出する

ぱぱっと調べた感じ、さまざまな方法が見つかったのですが、こちらのライブラリを使って計算しました。

geographiclib.sourceforge.io

ソースコードは確認していないのですが、国土地理院の計算方法とほぼほぼ同じ結果が返ってくることを確認しています。

vldb.gsi.go.jp

ソースコード(抜粋)
const goalLatLong = [35.31902777, 139.55041666]; // 目標地点の緯度,経度(今回は鎌倉駅)
const geod = geodesic.Geodesic.WGS84;

const r = geod.Inverse(
  latitude, // 現在地の緯度をいれる
  longitude, // 現在地の経度をいれる
  ...goalLatLong
);

console.log(`${ r.s12.toFixed(2) }m`);

とりあえずこんな感じのコードで、2点間の距離をメートルで算出できます。

これらを組み合わせて、鎌倉駅までの距離を表示するウェブサイトが完成しました。
なぜ、鎌倉駅をターゲットにしたかというと、「いざ鎌倉」というセリフが頭をよぎったからです。

ちなみに鎌倉駅の緯度経度はWikipediaで調べました。

ja.wikipedia.org

ここです。

www.google.com

ソースコード(抜粋)

<html>
  <head>
    <meta charset="utf-8">
    <title>iza-kamakura</title>
    <meta name="viewport" content="width=device-width" />
    <meta name="description" content="Displays the straight line distance to Kamakura Station." />
    <script src="https://geographiclib.sourceforge.io/scripts/geographiclib-geodesic.min.js"></script>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      body {
        display: flex;
        align-items: center;
        justify-content: center;
        color: #FAFAFA;
        font-size: 24px;
        font-weight: 900;
        background: #1565C0;
      }

      .display {
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      #m {
        font-size: 40px;
      }

      #timestamp {
        position: fixed;
        bottom: 8px; right: 8px;
        color: #0D47A1;
        font-size: 12px;
      }
    </style>
  </head>
  <body>
    <div>
      <div class="display">
        <p id="m"></p>
        <p>to Kamakura Station</p>
      </div>
      <p id="timestamp"></p>
    </div>
    <script>
      const goalLatLong = [35.31902777, 139.55041666]; // 目標地点の緯度,経度(今回は鎌倉駅)

      navigator.geolocation.watchPosition(handleWatchPosition, null, {
        enableHighAccuracy: true,
        timeout: 60000,
        maximumAge: 0
      });

      function handleWatchPosition(evt) {
        const latitude = evt.coords.latitude;
        const longitude = evt.coords.longitude;
        const accuracy = evt.coords.accuracy;
        const altitude = evt.coords.altitude;
        const altitudeAccuracy = evt.coords.altitudeAccuracy;
        const heading = evt.coords.heading || 0;
        const speed = evt.coords.speed;
        const timestamp = evt.timestamp;

        document.getElementById('timestamp').textContent = timestamp;

        if (latitude && longitude) {
          const geod = window.geodesic.Geodesic.WGS84;
          const r = geod.Inverse(
            latitude, longitude,
            ...goalLatLong
          );

          document.getElementById('m').textContent = `${ r.s12.toFixed(2) }m`;
        }
      }
    </script>
  </body>
</html>

コードの必要最低限な部分だけを抜粋するとこんな感じです。
コピペして、サーバにホスティングすれば動作すると思われます。

ちなみに、https://iza-kamakura.kimizuka.fm では、OGPを設定したり、ウェブフォントを読み込んだり、右下のタイムスタンプをタップすると、取得したJSONを確認できたりするようにしています。

実際に実装してみて、navigator.geolocation.watchPositionの手軽さを痛感したので、今後とも贔屓にしていこうと思った今日この頃でした。