現在、Google Spreadsheetへ住所やキーワード、ランドマーク名などを入力して、そのシートを元にマップを生成するツールを作って実際に使っていたりします。以前作っていた、GE Maniacsというサイトでは、Google Earthをネタにサイト運営をしてた関係で、こちらのサイトのツールなども利用させていただいてました。この住所やキーワードを元にマップを作る際にやっておくべき事がジオコーディングという作業で、住所等を「緯度経度」に変換しておく作業です。

実際にはマップにレンダリングする際には、緯度経度情報じゃなく住所でもそのまま投げて、サーバー側で緯度経度に変換してくれるので、問題はないのですが、都度変換されることになるので効率が悪く遅くなります。事前に緯度経度に変えておけば高速にマッピングが出来るわけです。ちなみに、メソッドにはリバースジオコーディング(緯度経度から住所を得る)のメソッドも合ったりします。

※ちなみに自分のツールは、スプレッドシート上でマップを表示させてみたり、Static Mapの画像を取得してみたりなどやってます。

今回使用するファイルとアプリケーション

※今回使用するスプレッドシートにジオコーディングキーワードに住所を入れてメニューよりジオコーディングを実施すると一括でスプレッドシートの住所一覧から緯度経度情報を返してくれます。C列~E列を消して実行するとわかります。

ジオコーディングソース

GAS側コード

  • ジオコーディングする際にUrlfetchAppでGoogle Maps APIに対して投げて取得する方法もあるのですが、UrlfetchAppは1回あたりの呼び出し時におよそ10秒ほど間を空けないとエラーになるので、懸命な手段とは言えません。
  • また、UrlfetchAppでジオコーディング結果を取得する方法は、APIキーが必要です。

HTML側コード

マッププレビューで用いてるコードです。別途Google Maps API Keyのセットアップが必要です。

  • APIキーは<HEAD>にある「https://maps.googleapis.com/maps/api/js」の参照にkey=YOUR_API_KEYという形でパラメータを追加してあげる必要があります。

Google Maps APIキーが必要となりました

有償化されました

2018年7月16日より、いよいよGoogle Maps APIを利用したサービス全てに於いて、APIキーがなければマップが表示されないように仕様変更が実施されました。それまでは、APIキーがなくともマップの表示が可能でした。APIキーは請求アカウントとキーが紐づけされていなければならず、利用自体が有償化されたことになります。

ただし、月額200ドルまでは無償枠が設けられているので、その範囲内であれば課金されないことになります。Map利用の課金枠は以下の通り。かなり複雑な料金体系になっていて、本気で使うには覚悟がいりますね・・・

項目名月額無料枠(200ドル分)1,000コールあたりの料金
月の利用量0−100,000100,000以上
Mobile Native Static Maps無制限$0.00$0.00
Mobile Native Dynamic Maps無制限$0.00$0.00
Embed無制限$0.00$0.00
Embed Advanced14,000 loadsまで$14.00$11.20
Static Maps100,000 loadsまで$2.00$1.60
Dynamic Maps28,000 loadsまで$7.00$5.60
Static Street View28,000 panosまで$7.00$5.60
Dynamic Street View14,000 panosまで$14.00$11.20

※ただし上記の料金はMapのみで、ルートと場所の検索クエリに関する課金は別に存在します。詳しい料金表はこちらから。

図:APIキーなしだとこういう表示になってしまう

APIキーの取得

Google Maps APIを使う場合には、以下の手順でAPIキーを手に入れる必要があります。別途クレジットカードが必要です(といっても、上限設定をして課金されないようにセットアップもします)。

  1. Google Maps Platformにアクセスする
  2. 右上にある「使ってみる」をクリックする
  3. Enable Google Maps Platformというダイアログが出ます。今回は、とりあえず全部選択します。continueをクリック
  4. select or Create Projectでは、Google Cloud Consoleでのプロジェクト一覧が出てきます。新規作成をしてみました。nextをクリック。GASのプロジェクトに対しては適用出来ませんでした。
  5. 請求先アカウントを指定しろと言われるので、設定をします。請求先アカウントの作成をクリック。自分はすでにG Suiteユーザであるので、課金アカウントは予め作成済みでしたので、ここは飛ばします。(最初の1回は300ドル分/1年のむ)
  6. Google マッププラットフォームの有効化というダイアログが出て、とりあえず完了です。次へをクリック。
  7. しばらく待つ(結構時間掛かります)とAPIキーが出てくるので、これを控えておきます。大事なキーなので流出などしないように!!
  8. 取得したAPIキーを「https://maps.googleapis.com/maps/api/js?key=xxxxxx」といった形で追記して呼び出すようにする。
  9. You’re all setと出たら完了となるので、DONEクリックして閉じる。

図:使用するマップのタイプ。通常はMapsのみでOK

図:プロジェクトの選択画面

図:APIキーは大切に保管しておきましょう。

APIキーに制限を付ける

続けて、認証情報を作成する必要があります。新しいAPIキーを保護する必要がありますと表示されているので、クリックします。これを行わないと、誰かれ問わずキーを使われてしまいます。

  1. キー制限にて「アプリケーションの制限」を選びます。
  2. HTTPリファラー」を選びます。
  3. どこからの呼び出しにだけ応じるか?URLを追加します。通常は埋め込むウェブサイトのURLを入力します。
  4. Google Apps Scriptのウェブアプリケーションやスプレッドシート上のダイアログから呼び出す場合には、一回Keyを入れた状態で呼び出し、F12のデベロッパーコンソールを開きます。
  5. Google Maps JavaScript API error: RefererNotAllowedMapErrorというエラーがあるはず。この中にあるYour site URL to be authorized以下のURLをHTTPリファラーに登録してあげると良い。
  6. 適用してから反映するまで5分ほど時間差があるので注意!
  7. 無事に表示できるか確認する。

図:HTTPリファラーで制限する

図:GASで使うにはひと手間が必要なHTTPリファラーの取得

図:無事に表示できるようになりました。

無料枠以上に利用しないよう制限をつける

Google Cloud Console上にて、まずは一旦ダッシュボードまで戻ります。テストをしてみるとわかりますが、リクエスト数がわかるようになっています。また、17個くらいのAPIがオンになっています。多分全部は要らないので、不要なものは無効化しておくと良いでしょう。しかしこのままでは、リクエストのあるAPIによって課金されかねないので、以下の手順で制限をつけます。

  1. Maps JavaScript APIがリクエストされてるので、その右側の歯車をクリック。
  2. 次の画面で左サイドバーの「割り当て」をクリック。
  3. Map loads per dayの項目が下にあります。無制限になってるので隣の鉛筆アイコンをクリック。
  4. 出てきたダイアログにて無制限のチェックを外してあげる。
  5. 無料の割当が25000くらいなので、20000くらいで値を入れる。確認にチェックを入れて、保存をクリック。
  6. アクセス数が大したことがなければ、これで十分無料枠で毎月利用が出来ます。

図:利用者の多いサイトではさじ加減が重要

Fusion Tablesを使うという選択肢は・・・

自分は1回使っただけで、Google Apps Scriptで使うにはパフォーマンスが悪く、マッピングに関しても、正直自由度が低いということで使っていなかったFusion Tables。G Suitesの見捨てられていたサービスの1つで、データベースを担当!?するような存在でした。結局は殆どメンテされる事もなく、半ば放置されていたので消えるだろうなぁと思っていたら、2019年8月に消えることが確定しました。

SQLみたいな形でデータを取得できる点だけが評価できましたが、パフォーマンスがとっても悪く、スプレッドシートのほうが全然使いやすいので、想定していた通り終焉の日が来ました。ということで、マップ関係ではFusion Tablesを使うのは辞めましょう。せっかく、ライブラリもありましたが。。。そういえば、Google Baseなんてのもありましたね・・・

Mapsに関係なく、Fusion Tables使っちゃってる人は早めに他に移行しましょう。というか、制限が厳しいアプリだったので、まともに使っていた人がいるとは思えないのですが。。。

ネットワークリンク配信してみる

ネットワークリンクとは、Google Earth上でビューを移動した時に、現在見ているエリア等に応じてサーバから情報をリアルタイム要求する為の、KMLの機能の一つ。表示されているエリアやその高さなどに応じてピンやオブジェクトを含んだデータを取得出来るので、非常によく利用されている機能の一つ。

ビューを移動すると東西南北のポイント(緯度経度)に関する情報をサーバに送ってくれるので、それを元にデータを返す仕組みを今回Google Apps Scriptで生成してやろうというのがミッションです。

KML側のコード

上記のKMLは移動後に1秒後にhrefに設定したURLに対して情報を要求します。URLの最後には必ず「?」を付けることを忘れずに。URLはGAS側のウェブアプリケーションURLを指定します。其のため、ネットワークリンク用にdoGet()が必要になります。

GAS側のコード

  • 緯度経度の範囲情報は、Google Earth側から受信したe.parameter.BBOXにて、カンマ区切りで取得可能です。
  • 受信した緯度経度範囲の情報をスプレッドシートのGPSデータに記述しています。
  • 緯度経度範囲内にあるプレイスマークだけをmapsheetからフィルタしてKMLを生成しています。
  • makeplacemark関数にてmapsheetからのデータよりKMLを生成しています。
  • 最後にContentServiceにてKMLを出力しています。mimetypeとしてContentService.MimeType.XMLをセットしています。
  • 更にカスタマイズすればラインデータやポリゴンデータなど、また、バルーンの中にデータを表示など可能です。

使い方と結果

搭載してる機能

マッププレビュー機能では、以下の機能を搭載しています。

  • Google Drive内の指定のフォルダの画像類をプレイスマークのアイコンとして利用出来るようにしています。
  • トラフィックレイヤーを追加する
  • マップに検索窓を用意して、検索した場所にジャンプする機能
  • センターマーカーを装備
  • 特定の列の数式をマッピング時に自動的に補完する機能(vfatmerge関数)
  • Google Earthからのリクエストから緯度経度情報を取得しスプレッドシートに書き込む機能

セットアップ

また、セットアップが必要です。メニューより「作業用」⇒「セットアップ」を実行します。スプレッドシートのIDがスクリプトプロパティに格納され、プログラム側で利用されます。

またアイコンフォルダの指定では、Google Pickerを利用しているので、Google Cloud ConsoleよりAPIキーを取得してコードに追加する必要があります。追加しないとPicker APIが動きません。マーカーアイコンの追加でこれらの情報を利用しています。

マップ表示プレビュー

APIキーを設定していれば、マッププレビューが見られます。また、今回のスプレッドシートには更に別にmap表示専用というプロジェクトも入れてあります。このスプレッドシートのIDを入れてあげて、map.htmlの中にAPIキーを追記してあげれば、フルスクリーンでマップ表示が可能になっています。

別のプロジェクトなので、HTTPリファラーが別になりますので、制限を掛けている場合には追加で登録してあげましょう。

図:この状態でブログに埋め込むことも可能

ネットワークリンクを表示

GPS2KMLのネットワークリンクのKMLをGoogle Earthに読み込ませて、恵比寿駅に飛ぶと、Google Apps Scriptから出力されたKMLデータが返されて表示されます。現在見ている緯度経度の範囲内にあるプレイスマークのみを絞って表示するので、負荷を低減できるようになっています。

スプレッドシートのデータを利用しているので拡張すればより面白いデータをGoogleスプレッドシートに記述するだけで配信が可能になります。PHPといったサーバー不要でデータ配信が出来るので非常にオススメです。

図:ネットワークリンクで恵比寿周辺に行くと現れるようになった

ポイント

  • geocoderに投げるとJSON形式で返ってきます。但し、複数返すことも可能なので(例えばキーワードなど)、そこは注意。住所ならば1個しか返ってこないはずなので、result[0]で指定し、rezult.geometry.location.latと指定すれば緯度が取得、lonとすれば経度が取得できます。
  • Googleのジオコーディングサービスは必ずしも住所を入れれば確実な緯度経度に変換されて返って来るわけではありません。日本の住所は非常に複雑なので、精度の低いアバウトな緯度経度で返ってきたり、エラーになって返ってこなかったりします。
  • 建物名などはジオコーディングのキーワードに入れてはなりません。エラーになります。
  • どうしてもエラーになる住所の場合には、その場所をピンポイントにヒットできるキーワードを考えます。ランドマーク名やGoogle検索ワードなどがそれです。一度googleでそれを検索しポイントを教えてくれるかどうかを調べてみると良いでしょう。
  • 【施設名:市までの住所】といった検索ワードも有効です。これはGoogle Maps上で検索したプレイスマークがこのような仕組みを利用しています。
  • 【カテゴリー名:施設名】なんて検索ワードも使えたりしますが、カテゴリー名はマップ上で調べておかないといけません。
  • マップの精度として小数点以下7桁です。それより桁数が小さいと精度が落ちてアバウトなマッピングになってしまいます。
  • マッピングで利用するのは緯度経度の情報なので、片方だけではマッピング出来ません。
  • mapsheetシートの説明文の列は、HTMLコードがそのまま使えます。セルの中にHTMLでコードを記述するとバルーンの中に表示がされます。
  • サイドバーメニューのマーカーアイコンセクションでアイコン登録用のダイアログ表示が出来ます。指定したフォルダ内の画像を自動的にリストアップし、画像をクリックするとURLボックスにURLが組み立てられて入る仕組みになっています。
  • Google Driveの画像に直リンクする為には、https://drive.google.com/uc?export=view&id=というURLに続けて画像ファイルのIDをつなげれば良いです。これで、参照することが出来ます。
  • ESCキーとマップ上でのクリックでバルーンが閉じるようにちょっとだけイベント追加して細工を加えています。
  • Google Maps API v3を使うためには、このURLのようにライブラリへの参照が必要です。
  • 情報ウィンドウのサイズは、#infodivにてCSSで制御することが可能です。
  • 個人的にはこれに追加のマップや、fckeditor入力画面とマップ上でプレイスマークの追加とスプレッドシートへの登録、リバースジオコーディングの実装などをやりたいと思っています。
  • マーカーアイコンは32×32のサイズでスケールするようにオプション指定しています。

関連リンク

共有してみる: