はじめに
今回のビジボットでは、ビジボット初の★3つ難易度『GASでリバースジオコーディングする』方法を紹介していきます!リバースジオコーディングとは緯度経度を住所情報に変換することです!今回は住所と最寄駅とその距離までを取得してみました!会社のクライアントがどういった属性か?分析するのに非常に役立ってくれてます!
それでは早速始めていきます!
1.完成コード
今回は『今日の運勢』を取得するのと同じく外部サービスのAPIを利用して取得しています!
コードの詳細については後ほど説明していきますので、まずは以下同様にシートの作成をしていきます。
※今回は色々時間がなくてヘッダー(prefとかcityとか)をコードで作成する処理を入れれませんでした…
取得したい情報の部分には『エリア』と『駅情報』を選択できるようにプルダウンで入力規則の登録を行っておきます。
『エリア』を選択した場合は住所情報、『駅情報』を選択した場合は最寄駅などの情報が取得されていきます。

それでは全体のコードを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
//*** http://express.heartrails.com/api.html 路線 //*** http://express.heartrails.com/api/xml?method=getStations&x=139.645683&y=35.443591 sampleAPIレスポンス //*** http://geoapi.heartrails.com/api.html 緯度経度 //*** http://geoapi.heartrails.com/api/xml?method=searchByGeoLocation&x=139.77456498&y=35.68381981 sampleAPIレスポンス var sheet = SpreadsheetApp.getActiveSheet(); function getGeocode(){ var getflg = sheet.getRange(2,2).getValue(); var test = Browser.msgBox("「" + getflg + "」で実行しますか?", "続けますか", Browser.Buttons.OK_CANCEL); if (test == 'ok') { //緯度経度の最終行を取得して、配列で取得 var lr = sheet.getLastRow(); var y = sheet.getRange(4, 1, lr).getValues(); var x = sheet.getRange(4, 2, lr).getValues(); var getflg = sheet.getRange(2,2).getValue(); for(var i = 0; i <= lr-4; i++) { var lat = y[i]; var lon = x[i]; Logger.log(lat); Logger.log(lon); //分岐処理(エリアか駅情報か) if (getflg === "エリア"){ //エリア取得Call(引数に緯度経度をトス) ; getArea(lat,lon,i) }else{ //駅情報取得Call(引数に緯度経度をトス) getStation(lat,lon,i); } } if (test == 'cancel') { Browser.msgBox("キャンセルを押しました"); } } function getArea(y,x,i) { var url = "http://geoapi.heartrails.com/api/xml?method=searchByGeoLocation&x="+x+"&y="+y; var response = UrlFetchApp.fetch(url); // Logger.log(response.getContentText()); //レスポンス確認用 var xml = XmlService.parse(response.getContentText()); var entries = xml.getRootElement().getChildren("location"); var err = xml.getRootElement().getChildren("error"); var err_num = Number(err); if (err_num === 0.0){ sheet.getRange(4 + i,3).setValue(entries[0].getChildText("prefecture")); sheet.getRange(4 + i,4).setValue(entries[0].getChildText("city")); sheet.getRange(4 + i,5).setValue(entries[0].getChildText("town")); } } function getStation(y,x,i) { var url = "http://express.heartrails.com/api/xml?method=getStations&x="+x+"&y="+y; var response = UrlFetchApp.fetch(url); // Logger.log(response.getContentText()); //レスポンス確認用 // 名前空間 var namespace = XmlService.getNamespace("urn:heartrails:express"); var xml = XmlService.parse(response.getContentText()); var entries = xml.getRootElement().getChildren("station",namespace); var err_num = Number(entries); if (err_num !== 0.0){ sheet.getRange(4 + i,6).setValue(entries[0].getChildText("name",namespace)); sheet.getRange(4 + i,7).setValue(entries[0].getChildText("line",namespace)); sheet.getRange(4 + i,8).setValue(entries[0].getChildText("distance",namespace)); } } } |
2.コード説明
まず、スプレッドシートサイドで指定したgetflg(『エリア』か『駅情報』)をポップアップで表示して、取得する情報に誤りがないか確認します。
※『キャンセル』を選択したら処理中止、『OK』を選択したら処理開始

処理が開始したら緯度経度情報をスプレッドシート上から取得してそれぞれの関数(『getArea()』『getStation()』)に引数として渡して処理が進んでいきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var sheet = SpreadsheetApp.getActiveSheet(); function getGeocode(){ var getflg = sheet.getRange(2,2).getValue(); var test = Browser.msgBox("「" + getflg + "」で実行しますか?", "続けますか", Browser.Buttons.OK_CANCEL); if (popup == 'ok') { //緯度経度の最終行を取得して、配列で取得 var lr = sheet.getLastRow(); var y = sheet.getRange(4, 1, lr).getValues(); var x = sheet.getRange(4, 2, lr).getValues(); var getflg = sheet.getRange(2,2).getValue(); for(var i = 0; i <= lr-4; i++) { var lat = y[i]; var lon = x[i]; Logger.log(lat); Logger.log(lon); //分岐処理(エリアか駅情報か) if (getflg === "エリア"){ //エリア取得Call(引数に緯度経度をトス) ; getArea(lat,lon,i) }else{ //駅情報取得Call(引数に緯度経度をトス) getStation(lat,lon,i); } } if (popup == 'cancel') { Browser.msgBox("キャンセルを押しました"); } } |
getArea()の場合
住所情報を取得します。
リクエスト用のURLを作成し、APIのレスポンス結果を取得します。
形式はxml形式だったのですが、全くやったことなかったので物凄く調べて苦労しました。。(笑)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function getArea(y,x,i) { var url = "http://geoapi.heartrails.com/api/xml?method=searchByGeoLocation&x="+x+"&y="+y; var response = UrlFetchApp.fetch(url); // Logger.log(response.getContentText()); //レスポンス確認用 var xml = XmlService.parse(response.getContentText()); var entries = xml.getRootElement().getChildren("location"); var err = xml.getRootElement().getChildren("error"); var err_num = Number(err); if (err_num === 0.0){ sheet.getRange(4 + i,3).setValue(entries[0].getChildText("prefecture")); sheet.getRange(4 + i,4).setValue(entries[0].getChildText("city")); sheet.getRange(4 + i,5).setValue(entries[0].getChildText("town")); } } |
getStation()の場合
駅情報を取得します。
これも同様にリクエスト用のURLを作成し、APIのレスポンス結果を取得します。
形式はxml形式なので、Areaと同じように進めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function getStation(y,x,i) { var url = "http://express.heartrails.com/api/xml?method=getStations&x="+x+"&y="+y; var response = UrlFetchApp.fetch(url); // Logger.log(response.getContentText()); //レスポンス確認用 // 名前空間 var namespace = XmlService.getNamespace("urn:heartrails:express"); var xml = XmlService.parse(response.getContentText()); var entries = xml.getRootElement().getChildren("station",namespace); var err_num = Number(entries); if (err_num !== 0.0){ sheet.getRange(4 + i,6).setValue(entries[0].getChildText("name",namespace)); sheet.getRange(4 + i,7).setValue(entries[0].getChildText("line",namespace)); sheet.getRange(4 + i,8).setValue(entries[0].getChildText("distance",namespace)); } } |
上記、それぞれ実行するとエリア情報と駅情報が取得できました!
GoogleMapAPIも登録に色々かかるようになってしまったので、気軽にできないかな?ってことで始めたのが本コードを作ったきっかけでした。
なかなかリバースジオコーディングの情報でいい記事が見つからなかったので参考になればいいなと思います!

最後までお付き合い頂き、ありがとうございました!
今回は時間の都合上、あまり詳しい記事としてアップできなかったので、後日またトライさせてください!(笑)
全然できていないですが、GAS以外もSEOやマーケティングを勉強した記事を書いていきたいと思ってます…(笑)