Google Maps API (旧Google Ajax API) からクライアント位置情報を取得する


2019/12/17

今回は
Google Maps APIsを設定して、使ってみるまでのお話になります。

Google AJAX APIsはGoogleのサーバーから直接読み込んで、自分のhtmlスクリプトコードとして利用できるjavascriptライブラリ群です。

代表的なものにjQueryなどがあります。

昨今ではReactjs/Angularなどの主要なjavascriptフレームワークの豊富なライブラリも簡単に利用できるようになり、Google Ajax APIをガッツリプロダクトで利用する機会もめっきりなくなりました。

とはいえ、簡単なhtmlアプリのテストコードなどで、jQuery等の関数を使ってみたり、Material Design Iconsを利用してみたり、ちょっとした事を行うには、対応のnpmパッケージをインストールする手間も面倒なこともあり、未だに便利には使えます。

かつてはそんな
Google AJAX APIsの機能の一つだった、Google Maps APIですが、現在はGoogle Maps Platformへと機能統合されて、GCP上のクラウドサービスに変遷しております。

(著者の認識が古かっただけですが...)かつての
誰でもどこでも使えるAPIではなくなって、事前登録アリのAPIになっているようです。


ともあれAPI KeyなしでAPIを叩いてみる

ネットで検索すると新旧入り乱れた内容で、「今でもAPI Keyなし、事前登録なしで使える」感じに書かれているブログもあり、もうAPI Keyなしじゃ全然動かないよという内容を言及されている方もおられます。

まずはこの辺、せっかくなので、どっちなのか身を持って実験してみましょう。

まずは、
index.htmlなどのベースhtmlのheadタグに以下のように、Google Maps APIを埋め込みで利用できるコードを試してみます。

            
            ...
    <head>
        <!-- Global tag: (google) - Ex Google Ajax Api -->
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript">
            const initializeMap = () => {
                const geocoder = new google.maps.Geocoder();
                if(google.loader.ClientLocation) {
                    const latlng = new google.maps.LatLng(
                        google.loader.ClientLocation.latitude,
                        google.loader.ClientLocation.longitude
                    );
                    geocoder.geocode({'latitude_longitude': latlng}, (results, status) => {
                        if(status == google.maps.GeocoderStatus.OK) {
                            alert(results[0]['formatted_address']);
                        };
                    });
                }
            }
            google.load("maps", "3", {
                other_params: "sensor=false",
                callback: initializeMap
            });
        </script>
        
このhttps://www.google.com/jsapiがAPI本体のソースコードで、これは今も昔もUrlが変わらず使えるようです。

このコードでは
google.loader.ClientLocationの各値のうち、latitudelongitudeのクライアント側情報を取得してみるだけです。

詳しく知りたい方は、機能解説は
Google Maps API 開発者用ドキュメントでご確認ください。

検証

さて、上のindex.htmlが機能するか、webサーバーを立てて検証してみると、

合同会社タコスキングダム|蛸壺の技術ブログ

最初に
NoApiKeysのエラーが発生します。

公式のドキュメントで、
この詳細のリンク先へ飛ぶと、こうステイトメントしてあります。

            
            ApiProjectMapError:
    Either the provided API key or the API project with which it is associated, could not be resolved.
    This error may be temporary.
    If this error message persists you may need to get a new API key or create a new API project.
    For more information, see Get Started with Google Maps Platform.
        
少なくとも、API Key関連付けされたAPIプロジェクトがないと使えない、とのことです。

残念無念…


API Keyの取得

はじめにGoogleアカウントがなければ始まりませんので、アカウントを持ってない場合はこちらで新規に作成ください

Googleアカウントを設定しましたら、そのアカウントを利用して
GCP Consoleにアサインしダッシュボードへ入ります。

合同会社タコスキングダム|蛸壺の技術ブログ

APIプロジェクトの作成

最初にGCPを利用する際には、プロジェクトが何もない状態ですので、APIプロジェクトを新規に作成します。

合同会社タコスキングダム|蛸壺の技術ブログ

合同会社タコスキングダム|蛸壺の技術ブログ

APIプロジェクトを作成したら、左のメニューから
APIとサービス > ダッシュボードへ移り、先程作成したプロジェクトを選択して開きます。

合同会社タコスキングダム|蛸壺の技術ブログ

APIプロジェクトを開いたら、
APIの有効化ボタンを選択します。

合同会社タコスキングダム|蛸壺の技術ブログ

すると、APIのサービスタイプが選択できますので、今回は
Maps Javascrtip APIを選択し、そのまま有効化させます。

合同会社タコスキングダム|蛸壺の技術ブログ

合同会社タコスキングダム|蛸壺の技術ブログ


API Keyの作成

次に、API Keyを発行する手順に移ります。

まずメインのダッシュボード画面から
APIとサービス > 認証情報を選択すると、新しくAPI Keyを作成する項目が選べるので、そのまま進みます。

合同会社タコスキングダム|蛸壺の技術ブログ

しばらくすると、API Keyが生成されるので、このKey値を控えておきましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


API Keyの保護

このままでは、このAPIが世界中の第三者から利用されてしまうので、何かしらの利用制限を課す必要があります。

APIとサービス > ダッシュボードに移り、APIリストの中からMaps JavaScript APIを選択し、Maps用のダッシュボードへ移ります。

移ったら
認証のタグを選んで、API Keyを操作する画面に切り替えます

合同会社タコスキングダム|蛸壺の技術ブログ

リファラの設定

まずは特定のサイトでしか利用できないような制限を設定します。例えば、弊社のサイトでしか使えなくする場合には以下のように、リファラを追加します。

合同会社タコスキングダム|蛸壺の技術ブログ

項目には2つ設定しましたが、一つは
Zone Apex(wwwとかを含まないドメイン名)で、もう一つはそれ以外のドメイン名です。

ワイルドカード表記が利用できるので、ご自分のwebサイトにあった設定を行いましょう。

ターゲットAPIの設定

よりセキュアに運用するために、利用したいAPIの種類も制限します。

これは複数のAPIを指定することもできますが、今回は
Maps Javascript APIのみに限定してみます。

設定すると以下のような感じになります。

合同会社タコスキングダム|蛸壺の技術ブログ

なお、設定が反映されるまで、5分程度かかるようですので、設定値変更後は焦らずしばらく待つ必要があります。


再度検証

このAPI Keyが機能しているか確かめてみましょう。

先程生成した
API Keyを利用して、index.htmlなどのベースhtmlのheadタグに埋め込みで利用できるコードを以下のように大改修します。

            
            ...
    <head>
        <!-- Global tag: (google) - Ex Google Ajax Api -->
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript">
            const initializeMap = () => {
                const geocoder = new google.maps.Geocoder();
                if(google.loader.ClientLocation) {
                    const latlng = new google.maps.LatLng(
                        google.loader.ClientLocation.latitude,
                        google.loader.ClientLocation.longitude
                    );
                    geocoder.geocode({'latitude_longitude': latlng}, (results, status) => {
                        if(status == google.maps.GeocoderStatus.OK) {
                            alert(results[0]['formatted_address']);
                        };
                    });
                }
            }

            google.load("maps", "3", {
                'other_params': 'key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // Your API Key
            });
            google.setOnLoadCallback(initializeMap);
        </script>
        
これで、google.loadother_parameskeyとしてAPI Keyを登録したことになるようです。

さて、Chromeのアドオンで、
Google Maps Platform API Checkerというアプリがありますので、これで正常動作しているかを検証できます。

これをapiの動作中のWebページでチェックさせてみると、

合同会社タコスキングダム|蛸壺の技術ブログ

のように、正常に動いていることがわかります。

さて、では肝心の
google.loader.ClientLocationでクライアント側の情報が受け取れているかというと…

合同会社タコスキングダム|蛸壺の技術ブログ

...null...ヌルヌルです。

これは
ここでだいぶ昔に議論されていることのようです。

google.loader.ClientLocationの機能は随分と前に開発終了しており、それ以降サポートされないままで現在まで生き残っているサービスです。

おそらくバックで動いている位置情報データベースも古いママの状態で、クライアント側のIP等を送信したとしても、正しく検証できないんだろうという結論です。

...つまりは、もうGoogle Maps Api 単体では
GeoIP風には使えない...と言い切っていいようです。


まとめ

Google Maps Apiは時代とともに大きく変遷しており、一昔前とは使える・使えない機能も様変わりしていることが分かりました。

今後自身のWebページに地図サービスを取り入れる際には、多いに利用させてもらうとして、
GeoIP的なサービスは別に実装しないと分かっただけでも個人的には今回は収穫でした。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。