[ヅ] Node.js でバッチプログラムを開発する (2015-03-29) で作ったプログラムの焼き直し。
緯度・経度から住所への変換には YOLP(地図):Yahoo!リバースジオコーダAPI - Yahoo!デベロッパーネットワーク を利用する。
環境: Mac OS X Yosemite + Node.js
$ uname -mrsv
Darwin 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64
$ node --version
v0.10.29
作成したファイルは3つ
- package.json (バッチプログラムの設定ファイル)
- app.js (バッチプログラムのメインファイル)
- reverse_geocoder.js (緯度・経度を住所へ変換するモジュール)
package.json
今回は HTTP 通信の処理を手軽に書きたいので request モジュールを使う。
package.json の書き方は npm package.json 日本語版 取扱説明書 が参考になる。
$ cat package.json
{
"name": "address-getter",
"version": "0.0.1",
"description": "address getter",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"author": "nilab",
"dependencies": {
"request": "^2.55.0"
}
}
メインのスクリプト app.js
緯度・経度をリバースジオコーダに渡して、住所へ変換する。
$ cat app.js
// 緯度・経度のリスト
var list = [
[35.170608, 136.882315], // 名古屋駅
[35.444415, 139.640174], // 横浜公園
[35.911567, 140.182261], // 茨城県龍ケ崎市
[20.425602, 136.081200], // 沖ノ鳥島
[33.912891, 107.344120], // 中国
[37.733883, -122.383787], // アメリカ
[24.812141, 79.812915], // インド
[ 0, 0]
];
// WebAPIコール用のアプリケーションID
var appid = '<YOUR APPLICATION ID (自分のappidを指定する)>';
// リバースジオコーダオブジェクトを取得
var revgeo = require('./reverse_geocoder');
var rg = revgeo.getReverseGeocoder(appid);
// 緯度経度を住所文字列に変換
list.forEach(function(latlon){
rg.getAddress(latlon[0], latlon[1], function(address, err, res){
if(address){
console.log(
latlon[0] + ',' +
latlon[1] + ' => ' +
address.getText());
}else{
console.log('error: ' + err);
console.log('status code: ' + res.statusCode);
}
});
}, this);
緯度・経度を住所へ変換する reverse_geocoder.js
緯度・経度を YOLP(地図):Yahoo!リバースジオコーダAPI に渡して、住所文字列へ変換する。
$ cat reverse_geocoder.js
var request = require('request');
var querystring = require('querystring');
// リバースジオコーダオブジェクト
// appid: WebAPIコール用のアプリケーションID
function ReverseGeocoder(appid){
this.appid = appid;
}
// 住所オブジェクトを返す
// lat: 緯度
// lon: 軽度
// callback: コールバック関数
ReverseGeocoder.prototype.getAddress = function(lat, lon, callback){
// クエリー文字列を組み立てる
var qs = querystring.stringify({
lat: lat,
lon: lon,
output: 'json',
appid: this.appid
});
var url = 'http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?' + qs;
var opts = {
url: url,
json: true // JSONレスポンスを自動処理する設定
};
// Web API をコールする
request.get(opts, function(error, response, body){
if(!error && response.statusCode == 200){
// JSONレスポンスがJavaScriptオブジェクトに変換されて
// 変数bodyに入っている
callback(new Address(body));
}else{
callback(null, error, response);
}
});
};
// 住所オブジェクト
function Address(data){
this.data = data;
}
// 住所文字列を返す(シンプル)
Address.prototype.getSimpleText = function(){
return this.data.Feature[0].Property.Address;
};
// 住所文字列を返す
Address.prototype.getText = function(){
if(this.data.ResultInfo.Count === 0){
// 住所が見つからない場合
return '';
}
var property = this.data.Feature[0].Property;
if(property.Country.Code == 'JP'){
// 日本の場合
return property.AddressElement
.filter(function(x){
// 都道府県・市区町村・大字の住所レベル項目だけ残す
switch(x.Level){
case 'prefecture':
case 'city':
case 'oaza':
return true;
default:
return false;
}
}, this)
.map(function(x){
// 住所レベル項目の名称
return x.Name;
},this)
.join(''); // 住所レベル項目の名称をつなげる
}else{
// 日本以外
if(property.Address){
return property.Country.Name + ' ' + property.Address;
}else{
return property.Country.Name;
}
}
};
// リバースジオコーダオブジェクトを取得する
// appid: WebAPIコール用のアプリケーションID
function getReverseGeocoder(appid){
return new ReverseGeocoder(appid);
}
module.exports = {
getReverseGeocoder: getReverseGeocoder
}
npm install で必要なパッケージをインストール
npm install コマンドは、 package.json の dependencies の内容を見て、必要なパッケージをインストールしてくれる。
$ npm install
npm WARN package.json address-getter@0.0.1 No repository field.
npm WARN package.json address-getter@0.0.1 No README data
request@2.55.0 node_modules/request
├── caseless@0.9.0
├── json-stringify-safe@5.0.0
├── aws-sign2@0.5.0
├── forever-agent@0.6.1
├── stringstream@0.0.4
├── oauth-sign@0.6.0
├── tunnel-agent@0.4.0
├── isstream@0.1.2
├── node-uuid@1.4.3
├── qs@2.4.1
├── combined-stream@0.0.7 (delayed-stream@0.0.5)
├── mime-types@2.0.10 (mime-db@1.8.0)
├── http-signature@0.10.1 (assert-plus@0.1.5, asn1@0.1.11, ctype@0.5.3)
├── form-data@0.2.0 (async@0.9.0)
├── bl@0.9.4 (readable-stream@1.0.33)
├── tough-cookie@0.13.0 (punycode@1.3.2)
├── hawk@2.3.1 (cryptiles@2.0.4, sntp@1.0.9, boom@2.7.1, hoek@2.12.0)
└── har-validator@1.6.1 (commander@2.8.0, chalk@1.0.0, bluebird@2.9.24, is-my-json-valid@2.10.1)
npm start コマンドで実行
実行方法を package.json の scripts start の項目に書いておくと、 npm start コマンドで実行できる。
$ npm start
> address-getter@0.0.1 start /Users/alice/hogehoge
> node app.js
33.912891,107.34412 => 中華人民共和国 陝西省
35.911567,140.182261 => 茨城県龍ケ崎市寺後
35.444415,139.640174 => 神奈川県横浜市中区横浜公園
35.170608,136.882315 => 愛知県名古屋市中村区名駅
20.425602,136.0812 => 東京都小笠原村沖ノ鳥島
37.733883,-122.383787 => アメリカ合衆国 カリフォルニア州
24.812141,79.812915 => インド
0,0 =>
無事に、緯度と経度を住所へ変換できた。
非同期処理なので、リストの順番に結果が返ってくるとは限らない (実際にちがう順で住所文字列が返ってきている)。
参考資料
-
ref.
- [ヅ] Node.js でバッチプログラムを開発する (2015-03-29)
- Node.js
- npm package.json 日本語版 取扱説明書
- Array - JavaScript | MDN ← Array#filter や Array#map のドキュメントが参考になる。
- request ← request モジュール
- Node.js: request モジュールを使って GET リクエストを行う - Sarabande.jp
- YOLP(地図):Yahoo!リバースジオコーダAPI - Yahoo!デベロッパーネットワーク ← 緯度・経度を住所へ変換する WebAPI
tags: node.js
Posted by NI-Lab. (@nilab)