0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【10分でわかる】ZENRIN Maps APIを使って地図に現在地を表示する - Google Maps APIとの比較で理解する

0
Posted at

はじめに

スマートフォンアプリやWebアプリで「今いる場所」を地図上に表示する機能は、ナビゲーション、店舗検索、配送アプリなど、あらゆる位置情報サービスで必須のUIです。

以前の記事「【10分でわかる】ZENRIN Maps APIを使って地図にマーカーを表示する(基本編)」ではマーカーの基本的な表示方法を解説しました。今回はそれを応用して、地図に現在地を表示する 方法を解説します。

本記事では、以下の内容を実装します。

  1. ブラウザの Geolocation API で現在地の緯度経度を取得
  2. 地図の 中心を現在地に移動
  3. マーカーと精度円 を描画

注記: 本記事では、ZENRIN Maps APIのバージョン2.0と、Google Maps APIのAdvanced Markersを使用します。

ZENRIN Maps API 2ヶ月無料お試しID

ZENRIN Maps APIを実際に試してみたい方は、2ヶ月無料のお試しIDをご利用いただけます!

📝 お申し込みはこちら
👉 ZENRIN Maps APIの始め方

お試し期間中は、本記事で紹介する機能をはじめ、ZENRIN Maps APIの豊富な機能をご利用いただけます。

現在地表示の仕組み

「現在地を地図に表示する」機能のうち、位置情報の取得はブラウザ側の仕事です。地図APIはあくまで「取得した座標を地図上に描画する」役割を担います。

[ブラウザ Geolocation API]
         ↓ 緯度・経度・精度(m)
[Maps API(ZENRIN / Google)]
  ├─ 地図の中心を現在地に移動
  ├─ 現在地マーカーを表示
  └─ 精度円を描画

精度円(accuracy circle)とは

Geolocation APIが返す座標には、必ず精度(accuracy) という値が含まれます。これは「真の現在地がこの半径(メートル)以内に入る可能性が高い」という推定値です。
精度円を重ねて描画することで、Googleマップの青い丸+薄青い円のようなUIを実現できます。

Geolocation APIはHTTPSまたはlocalhostの環境でのみ動作します。HTTPの本番環境では位置情報を取得できないため、必ずHTTPSで配信してください。

Step 1: Geolocation APIで現在地を取得する

まずはブラウザのnavigator.geolocation.getCurrentPosition()で現在地を取得します。このコードはZENRIN・Google共通です。

navigator.geolocation.getCurrentPosition(
    (position) => {
        const lat = position.coords.latitude;   // 緯度
        const lng = position.coords.longitude;  // 経度
        const accuracy = position.coords.accuracy; // 精度(メートル)

        console.log('現在地:', lat, lng, '精度:', accuracy, 'm');
    },
    (error) => {
        console.error('位置情報の取得に失敗しました:', error.message);
    },
    {
        enableHighAccuracy: true,  // GPSを優先して高精度に取得
        timeout: 10000,            // 10秒でタイムアウト
        maximumAge: 0              // キャッシュを使わず最新位置を取得
    }
);

Step 2: 現在地を地図の中心に移動する

ZENRIN Maps APIの実装

map.setCenter(new ZDC.LatLng(lat, lng));

Google Maps APIの実装

// panTo() はアニメーションで滑らかに移動する
map.panTo({ lat: lat, lng: lng });
操作 ZENRIN Maps API Google Maps API
瞬間的に移動 map.setCenter(latlng) map.setCenter({lat, lng})
アニメーションで移動 map.panTo({lat, lng})

Step 3: 現在地マーカーを表示する

ZENRIN Maps APIの実装

const marker = new ZDC.Marker(new ZDC.LatLng(lat, lng));
map.addWidget(marker);

Google Maps APIの実装

PinElementを使うと、画像ファイルなしで色指定だけで青ピンを作れます。

const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");

const pin = new PinElement({
    background: '#4285F4',   // 背景色(Google Blue)
    borderColor: '#1967D2',  // 枠線色
    glyphColor: '#FFFFFF'    // 中央アイコンの色
});

const marker = new AdvancedMarkerElement({
    map: map,
    position: { lat: lat, lng: lng },
    content: pin.element,
    title: '現在地'
});

Step 4: 精度円(accuracy circle)を描画する

ZENRIN Maps APIの実装

ZDC.Oval(楕円クラス)を使います。xyに同じ値を入れると真円になります。

const accuracyCircle = new ZDC.Oval(
    new ZDC.LatLng(lat, lng),
    { x: accuracy, y: accuracy },  // 真円にする
    {
        fill: '#4285F4',
        stroke: '#4285F4',
        strokeWidth: 1,
        opacity: 0.2
    }
);
map.addWidget(accuracyCircle);

Google Maps APIの実装

専用のCircleクラスがあり、radiusにメートルを直接指定できます。

const { Circle } = await google.maps.importLibrary("maps");

const accuracyCircle = new Circle({
    map: map,
    center: { lat: lat, lng: lng },
    radius: accuracy,  // メートル単位
    fillColor: '#4285F4',
    fillOpacity: 0.2,
    strokeColor: '#4285F4',
    strokeWeight: 1
});

Step 5: すべてを組み合わせた完成形

「現在地を表示」ボタンを押すと、地図の中心が現在地に移動し、マーカーと精度円が表示されます。

ZENRIN Maps APIの完成版

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ZENRIN Maps API - 現在地表示</title>
    <script src="https://test-js.zmaps-api.com/zma_loader.js?key=YOUR_API_KEY&auth=referer"></script>
    <style>
        body { margin: 0; font-family: sans-serif; }
        #map { width: 100%; height: 90vh; }
        #locate-btn {
            position: absolute; top: 10px; right: 10px; z-index: 100;
            padding: 10px 20px; background: #4285F4; color: white;
            border: none; border-radius: 4px; cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="locate-btn">現在地を表示</button>
    <div id="map"></div>

    <script>
        let map;
        let currentMarker = null;
        let accuracyCircle = null;

        // 地図の初期化
        ZMALoader.setOnLoad((mapOptions, error) => {
            if (error) { console.error(error); return; }

            mapOptions.center = new ZDC.LatLng(35.681406, 139.767132); // 東京駅
            mapOptions.zoom = 15;

            map = new ZDC.Map(
                document.getElementById('map'),
                mapOptions,
                () => {
                    map.addControl(new ZDC.ZoomButton('top-left'));
                    map.addControl(new ZDC.ScaleBar('bottom-left'));
                },
                () => console.error('地図の初期化に失敗しました')
            );
        });

        // 現在地を取得して表示
        document.getElementById('locate-btn').addEventListener('click', () => {
            if (!navigator.geolocation) {
                alert('このブラウザは位置情報をサポートしていません');
                return;
            }

            navigator.geolocation.getCurrentPosition(
                (position) => {
                    const lat = position.coords.latitude;
                    const lng = position.coords.longitude;
                    const accuracy = position.coords.accuracy;
                    const latlng = new ZDC.LatLng(lat, lng);

                    // 地図の中心を現在地へ
                    map.setCenter(latlng);
                    map.setZoom(16);

                    // 既存のマーカー・精度円を削除
                    if (currentMarker) map.removeWidget(currentMarker);
                    if (accuracyCircle) map.removeWidget(accuracyCircle);

                    // 精度円を描画
                    accuracyCircle = new ZDC.Oval(
                        latlng,
                        { x: accuracy, y: accuracy },
                        { fill: '#4285F4', stroke: '#4285F4', strokeWidth: 1, opacity: 0.2 }
                    );
                    map.addWidget(accuracyCircle);

                    // 現在地マーカーを表示
                    currentMarker = new ZDC.Marker(latlng);
                    map.addWidget(currentMarker);
                },
                (error) => alert('位置情報の取得に失敗しました: ' + error.message),
                { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
            );
        });
    </script>
</body>
</html>

Google Maps APIの完成版

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Google Maps API - 現在地表示</title>
    <style>
        body { margin: 0; font-family: sans-serif; }
        #map { width: 100%; height: 90vh; }
        #locate-btn {
            position: absolute; top: 10px; right: 10px; z-index: 100;
            padding: 10px 20px; background: #4285F4; color: white;
            border: none; border-radius: 4px; cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="locate-btn">現在地を表示</button>
    <div id="map"></div>

    <script>
        (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
            key: "YOUR_API_KEY",
            v: "weekly"
        });

        let map;
        let currentMarker = null;
        let accuracyCircle = null;

        async function initMap() {
            const { Map, Circle } = await google.maps.importLibrary("maps");
            const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");

            map = new Map(document.getElementById("map"), {
                center: { lat: 35.681406, lng: 139.767132 },
                zoom: 15,
                mapId: "DEMO_MAP_ID"
            });

            document.getElementById('locate-btn').addEventListener('click', () => {
                if (!navigator.geolocation) {
                    alert('このブラウザは位置情報をサポートしていません');
                    return;
                }

                navigator.geolocation.getCurrentPosition(
                    (position) => {
                        const lat = position.coords.latitude;
                        const lng = position.coords.longitude;
                        const accuracy = position.coords.accuracy;
                        const latLng = { lat, lng };

                        // 地図の中心をアニメーションで移動
                        map.panTo(latLng);
                        map.setZoom(16);

                        // 既存のマーカー・精度円を削除
                        if (currentMarker) currentMarker.map = null;
                        if (accuracyCircle) accuracyCircle.setMap(null);

                        // 精度円を描画
                        accuracyCircle = new Circle({
                            map: map,
                            center: latLng,
                            radius: accuracy,
                            fillColor: '#4285F4',
                            fillOpacity: 0.2,
                            strokeColor: '#4285F4',
                            strokeWeight: 1
                        });

                        // 現在地マーカーを表示
                        const pin = new PinElement({
                            background: '#4285F4',
                            borderColor: '#1967D2',
                            glyphColor: '#FFFFFF'
                        });
                        currentMarker = new AdvancedMarkerElement({
                            map: map,
                            position: latLng,
                            content: pin.element,
                            title: '現在地'
                        });
                    },
                    (error) => alert('位置情報の取得に失敗しました: ' + error.message),
                    { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
                );
            });
        }

        initMap();
    </script>
</body>
</html>

まとめ

本記事では、ZENRIN Maps APIとGoogle Maps APIで現在地を地図に表示する実装を5ステップで解説しました。

  • 位置取得: どちらもブラウザのGeolocation APIを使う(共通)
  • マーカー表示: ZENRINはZDC.Marker、GoogleはAdvancedMarkerElement + PinElement
  • 精度円: ZENRINはZDC.Oval、Googleは専用のCircleクラス

Step 5の完成形コードをそのままコピーして試してみてください。

ZENRIN Maps API 2ヶ月無料お試しIDのご案内

本記事でご紹介したZENRIN Maps APIの機能を実際にお試しいただけます!

📝 お申し込みはこちら
👉 ZENRIN Maps APIの始め方

お試し期間中は、ZENRIN Maps APIの豊富な機能をご利用いただけるので、本格導入前の検証にぜひご活用ください。

関連記事


※本記事で使用しているAPIキーやURLはサンプルです。実際の導入時には、公式サイトから取得した正式なAPIキーを使用してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?