Google Apps Scriptの中では、実に地味でそれでいてあまり活用されていないけれど、自分としては結構ありがたいと思ったのがこの機能(Maps Class)。自分自身が以前、Google Earth関係でサイトをやっていたからというのもあるのですが、非常に簡単にジオコーディングや逆ジオコーディングが出来てしまうのは、とてもありがたい。他にもこのクラスには、Static Map(完全固定の地図生成)やらありますが、あまり利用価値がありませんので、スルーします。
但し、このジオコーディングやら逆ジオコーディングは、完全にGoogle Mapsの検索機能を利用して答えを貰ってる機能なので、クセがあります。今回は、とりわけもっとも利用頻度の高い「ジオコーディング」に的を絞ってます。
概要といっても、与えられたキーワードから、緯度経度を取得する。ただそれだけなのですが、このただそれだけが非常に問題だったりします。Googleが悪い点もあり、そうでない点もあり、其の結果としてジオコーディングしたのに、全く目的の場所から違う緯度経度が帰ってきて精度が悪いなんてことも非常に多くあります。以下に、このジオコーディングを利用した時の問題点をGoogleが悪いケースとそうではないケースの2つで説明してみたいと思います。尚、今回は、スプレッドシートを1枚用意して、キーワード列と緯度列、経度列、プレイスマークの列の4つの列を設けたものに、この機能を使って、一括でジオコーディングをするのが目的です。
function allgeocode(){
//シートデータ取得準備
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("mainsheet");
var range = sheet.getRange("A2:U").getValues();
var num = range.length;
var finalrow = sheet.getLastRow()-1;
//緯度経度情報格納用二次元配列を作成
//二次元配列を作成する(4列・行数分+1)
var msgcnt =3;
var dataArray = new Array(finalrow);
for(i = 0; i < finalrow; i++){
dataArray[i] = new Array(msgcnt);
}
//住所データ列よりジオコーディングをし、結果をとなりの3列に書き込む
for(var i = 0;i<finalrow;i++){
//住所キーワードを取得
var address = range[i][0];
//住所が空の場合はスルーする
if(address == ""){
dataArray[i][0] = "";
dataArray[i][1] = "";
dataArray[i][2] = "";
continue;
}
//ジオコーディングして値を配列に格納する
var latlng = georeturn(address,0);
var kekka = latlng.split(",");
dataArray[i][0] = kekka[0];
dataArray[i][1] = kekka[1];
dataArray[i][2] = latlng;
}
//配列データをスプレッドシートに反映させる
var lastColumn = dataArray[1].length; //カラムの数を取得する
var lastRow = dataArray.length; //行の数を取得する
sheet.getRange(2,22,finalrow,3).setValues(dataArray);
}
//ジオコーダー用ラッピング関数
function georeturn(address,option){
//ジオコーダクラスの宣言
var geocoder = Maps.newGeocoder();
//空のアドレスの場合には、スルーする
if(address == ""){
return "";
}
//ジオコーディング実施
var response = geocoder.geocode(address);
//optionによって値を返す。本来はresultsは配列で複数の答えが帰ってくることがあるが、0固定で今回はコーディングしてます。
var ret = "";
var result = response.results[0];
switch(option){
case 0: //全部を取得
ret = result.geometry.location.lat + "," + result.geometry.location.lng;
break;
case 1: //緯度だけ取得
ret = result.geometry.location.lat;
break;
case 2: //経度だけ取得
ret = result.geometry.location.lng
break;
default:
ret = "オプションが指定されていません"
break;
}
return ret;
}
※今回は、これらのクラスはいちいち書くのもアレなので、関数(georeturn)でラッピングしてます。