たかが方角、されど方角。ウェブアプリ開発でハマりがちな落とし穴に注意!

みなさん、こんにちは!
今年の8月にアイレットに新しく入社しました森です、どうぞお見知りおきを!

Webアプリ上でモバイル端末の情報を取得するという要件はたまにあると思います。なんとなく Web API を使って「位置情報」と共に端末が向いている方角」くらいはセットで簡単に取れるものだと思い込んでいませんか?かつての私は思っていました…。

今回は、私が実際に直面した「端末の向いている方角を知りたいだけなのに…」という苦渋の経験を元に、知っておくと役に立つ情報をお伝えします。これ以上、私のような犠牲者を出さないために、ぜひ最後まで読んでいってください!

前提条件

  • Webview を使ったモバイルアプリケーション(内部的にはWebアプリ)
  • ユーザーの位置情報をリアルタイムに取得して地図上に表示したい
  • 同時に、ユーザーの向いている方角も表示したい

パッと見使えそうな Geolocation API

まず、端末の位置情報を取得するWeb APIといえば、ほとんどの人が「Geolocation API」を思い浮かべるでしょう。緯度や経度、高度といった座標系の情報を取得できる便利なAPIです。

window.addEventListener('startWatchingPosition', startWatchingPosition);

const startWatchingPosition = () => {
    const watchId = navigator.geolocation.watchPosition((position) => {
            // 成功時の処理:位置が変化するたびに実行される
            const lat = position.coords.latitude;
            const lon = position.coords.longitude;
            const heading = position.coords.heading;

            console.log(`
                緯度: ${lat.toFixed(6)}°
                経度: ${lon.toFixed(6)}°
                移動方向 (heading): ${heading.toFixed(2)}°
            `);
        },
        (error) => {
            // 失敗時の処理
            console.error(`監視エラー: エラーコード ${error.code}`);

            // エラーが発生したら自動的に監視を停止
            navigator.geolocation.clearWatch(watchId);
        },
        { enableHighAccuracy: true } // 高精度を要求
    );
}

しかし!ここで注意が必要です。このAPIで取得できるのは「緯度、経度、高度、精度、速度、移動方向」です。

公式ドキュメントに「heading(移動方向)」という、いかにもそれっぽい情報があるため、私も最初はこれで方角も取れるはずだと信じて疑いませんでした。しかし、これが大きな思い込みだったのです…。

この heading は、実はそれなりの速度で移動していないと取得できません。なんとか取得できないかと家の周りを必死にグルグル回ってみましたが、歩く程度の速度では永遠に「0(北)」が返ってきました…。「静止状態での方角」が必要なケースは多いので、このAPIはあくまで「位置情報専用」と割り切って考えた方が良いでしょう。

代わりに「DeviceOrientationイベント」を使ってみよう


Geolocation API で方角が取れないとなると、他に手段はないのか?

しばらく代替となる Web API がなく、私は別の方法(Flutter SDKを経由)で対応していましたが、今では「DeviceOrientation イベント」が使えるようになりました。

このイベントは、モバイル端末のジャイロセンサーや加速度センサーを使って端末の傾きや方角を検知する機能です。ブラウザ上で簡単に方角を取得できるようになりました。

詳しい値については 公式ドキュメントの表 が非常に分かりやすいので、ぜひ参考にしてみてください。

シンプルに端末の向いている方角が知りたい場合は、「alpha値」を参照すればOKです。

window.addEventListener('deviceorientation', handleOrientation);

const handleOrientation = (event) => {
    // alpha値: Z軸周りの回転(コンパスの方角)。真北が0度、時計回りに増加します。
    const alpha = event.alpha;

    if (alpha !== null) {
        console.log(`
        端末が向いている方角 (alpha): ${alpha.toFixed(2)}°
    `);
    } else {
        console.error("方角情報の取得に失敗しました。対応ブラウザ/OSを確認してください。");
    }
}

ただし、この機能は比較的新しいため、古いデバイスやブラウザでは動作しない場合がある点には注意が必要です。

2023年9月以降、この機能は最新のデバイスとブラウザのバージョンで動作します。 古いデバイスやブラウザでは動作しない場合があります。

まとめ | 両方の技術を組み合わせるべし

いかがでしたでしょうか?
Webアプリでモバイル端末の「位置情報」と「向いている方角」の両方を正確に取得したい場合は、今回ご紹介した「Geolocation API」と「DeviceOrientationイベント」を併用する必要があります。
開発の見積もり段階で、このことを知っていれば、自分のように無駄な検証に時間を取られることもありません。
もし同じような要件に直面した際は、ぜひこれらの技術を組み合わせてみてください。そして、ユーザーをあっと驚かせるようなアプリを開発してください!
それでは、良い開発ライフを!