kintoneアプリ開発を行っていて、緯度・経度から住所の情報に変換したいという要望があり、Google MAP APIを使ってみたので、やり方をまとめていきたいと思います。
実装する機能の概要
今回はkintoneアプリに下記の機能をJavaScriptで実装していきます。
- kintoneアプリには緯度・経度・住所が登録できるフィールドを設置する
- プログラムはレコードの登録または保存時に発火する
- Google MAP APIを用いて、緯度・経度から住所に変換する
- 住所情報を該当レコードに登録する(PUT)
リバースジオコーディングのサンプルコード
早速ですが、こちらがサンプル。
(function() {
// Google Map API の指定
var script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?key=******'; // API Keyを入力する
document.body.appendChild(script);
// レコードの登録イベントを取得する
kintone.events.on(["app.record.edit.submit", "app.record.create.submit"], function(event) {
var record = event.record;
var recordNo = record.record_no.value;
var lat = record.lat.value;
var lng = record.lng.value;
var latlng = {lat: parseFloat(lat), lng: parseFloat(lng)};
getAddress(updateRecord, latlng, recordNo);
});
// GoogleAPIを使って住所を取得する
function getAddress(callback, latlng, recordNo){
var geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
var parkAddress = "";
var addressData = results[0].address_components;
if(addressData[addressData.length - 2].short_name == "JP"){
// 日本の住所取得
for(var i=addressData.length-3; i>=0; i--){
if(addressData[i].long_name != "Unnamed Road") parkAddress += addressData[i].long_name;
}
}else{
// 海外の住所取得
for(var i=addressData.length-3; i>=0; i--){
if(addressData[i].long_name != "Unnamed Road" && i==0) parkAddress += addressData[i].long_name;
else if(addressData[i].long_name != "Unnamed Road" && i!=0) parkAddress += addressData[i].long_name + ", ";
}
}
// 住所のデータを返す
callback(parkAddress, recordNo);
} else {
window.alert('Geocoder failed due to: ' + status);
return;
}
});
}
// 該当レコードに住所を登録する
function updateRecord(address, recordNo){
appId = kintone.app.getId();
var body = {
"app": appId,
"id": recordNo,
"record": {
"address": { "value": address }
}
};
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', body, function(resp) {
// 画面を更新する
window.location.reload();
}, function(error) {
// error
console.log(error);
});
}
})();
Google MAP APIのAPI Keyを設定する
まずはGoogle MAP APIのAPI Keyを取得しましょう。こちらの手順でAPI Keyを取得できるので、下記の通り設定してください。
// Google Map API の指定
var script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?key=******'; // API Keyを入力する
document.body.appendChild(script);
緯度・経度から住所を取得する
上記のサンプルでは、レコード保存時に緯度・経度情報を取得し、それをGoogle MAP APIに渡してあげて、住所に変換しています。
Google MAP APIを叩くと、下記のようなレスポンスが返ってきます。国名から番地までフルの住所を取得したい場合は、”formatted_addresss”を参照するのが良いでしょう。
その他レスポンスの詳細はこちらに記載されています。
{
"address_components" : [
{
"long_name" : "1",
"short_name" : "1",
"types" : [ "sublocality_level_4", "sublocality", "political" ]
},
{
"long_name" : "8",
"short_name" : "8",
"types" : [ "sublocality_level_3", "sublocality", "political" ]
},
{
"long_name" : "2丁目",
"short_name" : "2丁目",
"types" : [ "sublocality_level_2", "sublocality", "political" ]
},
{
"long_name" : "西新宿",
"short_name" : "西新宿",
"types" : [ "sublocality_level_1", "sublocality", "political" ]
},
{
"long_name" : "新宿区",
"short_name" : "新宿区",
"types" : [ "locality", "political" ]
},
{
"long_name" : "東京都",
"short_name" : "東京都",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "日本",
"short_name" : "JP",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "日本, 東京都新宿区西新宿2丁目8−1",
"geometry" : {
"location" : {
"lat" : 35.68918480,
"lng" : 139.69164810
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 35.69053378029150,
"lng" : 139.6929970802915
},
"southwest" : {
"lat" : 35.68783581970850,
"lng" : 139.6902991197085
}
}
}
住所が取得できたら、あとはレコードに登録するだけです。ただし、住所を取得しているのは非同期処理になるので、サンプルではcallbackを用いて該当レコードにPUTしています。
Google Map APIを使う場合の注意点
Google Map APIは非常に便利で使いやすいのですが、唯一の弱点は利用回数に制限があることです。それも、1日に2,500回までなので、多くのデータの取扱いがある場合は割とすぐに制限を超えてしまうでしょう。
その場合に便利なのが、Yahoo APIです。こちらは利用制限が50,000回/日になるので、既にある緯度・経度データを一気に処理したい場合は、こちらを使うのが良いです。
Yahoo APIを用いたリバースジオコーディングについては、次回執筆します!

