H5プロジェクトで百度地図と腾讯地図を用いたautomaticな位置情報取得実装

前提と注意点

  • HTTPSプロトコルが必要:CSSやJSに定義されたGeolocation APIは、セキュリティの観点からHTTPではブラウザ側で制限される場合があり、正確な位置情報が取得できない可能性があります。
  • 座標系の違いによる誤差
    • WGS-84:GPSモジュールが直接出力する国際基準座標
    • GCJ-02(MERCATOR):中国国内の地図サービス(高徳・腾讯・Google中国版)で使用される加密座標
    • BD-09:百度地図が独自に採用する座標系
    相互間で数十~数百メートルのずれが生じるため、ズレを許容できない場合は座標変換処理を実装する必要があります。

百度地図(Baidu Maps)での位置取得

APIキー取得先百度地図開発者コンソール

ドキュメント参考Browser Geolocation Guide

基本実装手順

  1. APIスクリプトのロード(scriptタグによる動的読み込み)
  2. Geolocationオブジェクトの生成と位置情報取得
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&type=webgl&ak=YOUR_BAIDU_AK"></script>

Vueコンポーネント内での実装例

<template>
  <div id="app"></div>
</template>

<script>
export default {
  name: "BaiduMapDemo",
  mounted() {
    this.fetchBaiduPosition();
  },
  methods: {
    fetchBaiduPosition() {
      if (!window.BMapGL) {
        console.warn("Baidu Maps GL API loading failed or not loaded yet.");
        return;
      }
      const baiduApi = window.BMapGL;
      const geo = new baiduApi.Geolocation();
      geo.getCurrentPosition((result) => {
        if (result.latitude && result.longitude) {
          console.log("百度位置情報:", result);
          this.handleBaiduSuccess(result);
        } else {
          console.error("百度定位結果に座標なし:", result);
        }
      }, { enableHighAccuracy: true });
    },
    handleBaiduSuccess(place) {
      // BD-09 → GCJ-02 変換が必要な場合は外部ライブラリ或多段処理を挿入
      const lng = place.longitude;
      const lat = place.latitude;
      console.log(`百度座標(BD-09): 緯度=${lat}, 経度=${lng}`);
      alert(`百度定位成功: ${lat}, ${lng}`);
    }
  }
};
</script>

騰訊地図(Tencent Maps)での位置取得

API Key取得先騰迅地図コンソール

公式ガイドGeolocation Component

API読み込み

<script type="text/javascript" src="https://mapapi.qq.com/web/mapComponents/geoLocation/v/geolocation.min.js"></script>

Vueコンポーネントでの応用実装

<template>
  <div id="tencent-location"></div>
</template>

<script>
export default {
  name: "TencentMapDemo",
  mounted() {
    this.loadTencentLocation();
  },
  methods: {
    loadTencentLocation() {
      if (!window.qq || !window.qq.maps) {
        console.warn("Tencent Maps SDKが読み込まれていません。");
        return;
      }

      const tencentKey = "YOUR_TENCENT_KEY";
      const companyName = "MyApp"; // 注意:登録時のアプリ名称と一致させる必要あり

      const geo = new qq.maps.Geolocation(tencentKey, companyName);
      const options = {
        // geolocationTimeout: 10000,
        enableHighAccuracy: true
      };

      const onSuccess = (pos) => {
        if (pos.lat !== undefined && pos.lng !== undefined) {
          console.log("騰訊位置情報:", pos);
          this.handleTencentSuccess(pos);
        } else {
          console.error("騰訊定位情報異常");
        }
      };

      const onError = (err) => {
        console.error("騰訊定位失敗:", err);
        // 必要に応じてリトライ処理や代替手段を実施可
      };

      geo.getLocation(onSuccess, onError, options);
    },
    handleTencentSuccess(locationData) {
      const latitude = locationData.lat;
      const longitude = locationData.lng;
      console.log(`騰訊座標(GCJ-02): ${latitude}, ${longitude}`);
      alert(`騰訊定位成功: ${latitude}, ${longitude}`);
    }
  }
};
</script>

補足:座標変換の推奨手法

  • 百度座標(BD-09)→ 高徳/騰訊座標(GCJ-02)変換には、以下の公式/非公式変換スクリプトが広く利用されています。
    // 例: BD-09 to GCJ-02 の簡易変換関数(精度保証付きではありません)
    function bd09togcj02(bd_lon, bd_lat) {
      const x_pi = 3.14159265358979324 * 3000.0 / 180.0;
      const x = bd_lon - 0.0065;
      const y = bd_lat - 0.006;
      const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
      const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
      const gg_lon = z * Math.cos(theta);
      const gg_lat = z * Math.sin(theta);
      return { lng: gg_lon, lat: gg_lat };
    }
  • 线上座標変換ツール(ルーツー)で手動チェック可能
  • 本番環境では offset の誤差を解消するには、必ず 百度地図'Coordinate Transform API' もしくは既知のTPC/JS ライブラリ(例: transformers)経由での処理を推奨

タグ: BaiduMap TencentMap HTML5Geolocation GCJ-02 BD-09

8月6日 07:05 投稿