今回の環境
Mac OS X Yosemite 10.10.2
$ uname -mrsv
Darwin 14.1.0 Darwin Kernel Version 14.1.0: Thu Feb 26 19:26:47 PST 2015; root:xnu-2782.10.73~1/RELEASE_X86_64 x86_64
Node.js はインストール済み。
$ node -v
v0.10.29
$ npm -v
1.4.14
プログラム開発の準備: package.json ファイルを用意する
package.json には今回開発するプログラムの内容について記述する。
npm init コマンドを打つと、対話形式で項目を入力していき、 package.json ファイルを生成してくれる。
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (hoge) revgeo
version: (0.0.0)
description: reverse geocoder
entry point: (index.js)
test command:
git repository:
keywords:
author: nilab
license: (ISC)
About to write to /Users/alice/hoge/package.json:
{
"name": "revgeo",
"version": "0.0.0",
"description": "reverse geocoder",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "nilab",
"license": "ISC"
}
Is this ok? (yes)
生成された package.json には不要な項目もあるので、手動で修正してこんな感じに。
{
"name": "revgeo",
"version": "0.0.0",
"description": "reverse geocoder",
"main": "index.js",
"author": "nilab"
}
プログラム開発の準備: xml2js モジュールをインストールする
今回は、 xml2js モジュールを使うので、 npm install コマンドでインストールする。
--save オプションを付けると、 package.json に xml2js の情報を追加してくれる。
$ npm install --save xml2js
npm WARN package.json revgeo@0.0.0 No repository field.
npm WARN package.json revgeo@0.0.0 No README data
xml2js@0.4.6 node_modules/xml2js
├── sax@0.6.1
└── xmlbuilder@2.6.2 (lodash@3.5.0)
package.json に dependencies の項目が追加された。
{
"name": "revgeo",
"version": "0.0.0",
"description": "reverse geocoder",
"main": "index.js",
"author": "nilab",
"dependencies": {
"xml2js": "^0.4.6"
}
}
バッチプログラムを開発する
今回は、緯度,経度を指定すると、住所を出力してくれるプログラムを作る。
緯度と経度から住所を求めるために、Web API を利用する。
⇛ YOLP(地図):Yahoo!リバースジオコーダAPI - Yahoo!デベロッパーネットワーク
プログラム自体は index.js と reverse_geocoder.js の2つのファイルを追加してそこに書く。
index.js ファイル:
var revgeo = require("./reverse_geocoder");
// process.argv[2]以降にコマンドライン引数が入る
for(var i=2; i<process.argv.length; i++){
// パラメータを取得
var p = process.argv[i];
// 緯度・経度はカンマ区切りで指定
var ll = p.split(",");
// 緯度経度から場所の情報を取得する
var geo = revgeo.reverse_geocoding(ll[0], ll[1], function(data){
console.log("INPUT: " + ll[0] + "," + ll[1] + "\n");
console.log("XML:\n" + data.xml + "\n");
console.log("RESPONSE:\n");
console.dir(data.data);
console.log("\n");
console.log("ADDRESS: " + data.address + "\n");
});
}
reverse_geocoder.js ファイル:
var http = require("http");
var querystring = require("querystring");
var xml2js = require("xml2js");
// 住所文字列を返す
// lat: 緯度
// lon: 軽度
// callback: コールバック関数
function reverse_geocoding(lat, lon, callback){
// クエリー文字列を組み立てる
var qs = querystring.stringify({
lat: lat,
lon: lon,
appid: "<YOUR APPLICATION ID>"
});
var path = "/OpenLocalPlatform/V1/reverseGeoCoder?" + qs;
var opts = {
host: "reverse.search.olp.yahooapis.jp",
port: 80,
path: path,
method: "get"
};
// Web API をコールする
var req = http.request(opts, function(res){
console.log("STATUS: " + res.statusCode + "\n");
console.log("HEADERS: " + JSON.stringify(res.headers) + "\n");
var body = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
var opts = {
trim: true,
explicitArray: false
};
// Web API のレスポンス XML を JavaScript オブジェクトへ変換
xml2js.parseString(body, opts, function(err, result){
// 結果のオブジェクトを生成
var data = {
xml: body,
data: result,
address: result.YDF.Feature.Property.Address
};
// コールバック関数を呼ぶ
callback(data);
});
});
res.on('error', function (e) {
console.log("error: " + e.message);
});
});
req.end();
}
module.exports = {
reverse_geocoding: reverse_geocoding
}
開発したバッチプログラムを実行する
実行するには、node コマンドの引数に index.js を指定し、その後の引数に緯度,経度を指定する。
実行すると、住所が出力される。
また、Web API コール結果の XML などもデバッグ情報的に出力している。
実行結果:
$ node index.js 35.170914,136.882895
STATUS: 200
HEADERS: {"date":"Sat, 28 Mar 2015 10:19:03 GMT","x-frame-options":"SAMEORIGIN","cache-control":"private","vary":"Accept-Encoding","content-length":"1820","content-type":"application/xml; charset=UTF-8","age":"0","connection":"close"}
INPUT: 35.170914,136.882895
XML:
<?xml version="1.0" encoding="UTF-8"?>
<YDF firstResultPosition="1" totalResultsAvailable="1" totalResultsReturned="1" xmlns="http://olp.yahooapis.jp/ydf/1.0">
<ResultInfo>
<Count>1</Count>
<Total>1</Total>
<Start>1</Start>
<Latency>0.0029189586639404</Latency>
<Status>200</Status>
<Description>指定の地点の住所情報を取得する機能を提供します。</Description>
<Copyright>Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved.</Copyright>
<CompressType />
</ResultInfo>
<Feature>
<Property>
<Country>
<Code>JP</Code>
<Name>日本</Name>
</Country>
<Address>愛知県名古屋市中村区名駅1丁目1-4</Address>
<AddressElement>
<Name>愛知県</Name>
<Kana>あいちけん</Kana>
<Level>prefecture</Level>
<Code>23</Code>
</AddressElement>
<AddressElement>
<Name>名古屋市中村区</Name>
<Kana>なごやしなかむらく</Kana>
<Level>city</Level>
<Code>23105</Code>
</AddressElement>
<AddressElement>
<Name>名駅</Name>
<Kana>めいえき</Kana>
<Level>oaza</Level>
</AddressElement>
<AddressElement>
<Name>1丁目</Name>
<Kana>1ちょうめ</Kana>
<Level>aza</Level>
</AddressElement>
<AddressElement>
<Name>1</Name>
<Kana>1</Kana>
<Level>detail1</Level>
</AddressElement>
<Building>
<Id>B@2sMmGd9uz</Id>
<Name>JRセントラルタワーズ</Name>
<Floor>18</Floor>
<Area>6284</Area>
</Building>
</Property>
<Geometry>
<Type>point</Type>
<Coordinates>136.882895,35.170914</Coordinates>
</Geometry>
</Feature>
</YDF>
RESPONSE:
{ YDF:
{ '$':
{ firstResultPosition: '1',
totalResultsAvailable: '1',
totalResultsReturned: '1',
xmlns: 'http://olp.yahooapis.jp/ydf/1.0' },
ResultInfo:
{ Count: '1',
Total: '1',
Start: '1',
Latency: '0.0029189586639404',
Status: '200',
Description: '指定の地点の住所情報を取得する機能を提供します。',
Copyright: 'Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved.',
CompressType: '' },
Feature: { Property: [Object], Geometry: [Object] } } }
ADDRESS: 愛知県名古屋市中村区名駅1丁目1-4
緯度 35.170914 経度 136.882895 の住所は「愛知県名古屋市中村区名駅1丁目1-4」と出力された。
開発したバッチプログラムを配布する
他の環境でも同様に実行したい場合、配布に必要なファイルは package.json, index.js, reverse_geocoder.js の3ファイル。
この3ファイルを実行したい環境の任意のディレクトリに置いて、 npm install コマンドを打つと、必要なモジュール (今回は xml2js モジュール) を自動的にインストールしてくれる。
npm install コマンドは package.json の dependencies を参照して、必要なモジュールを判断している。
$ npm install
npm WARN package.json revgeo@0.0.0 No repository field.
npm WARN package.json revgeo@0.0.0 No README data
xml2js@0.4.6 node_modules/xml2js
├── sax@0.6.1
└── xmlbuilder@2.6.2 (lodash@3.5.0)
これで、開発時と同じように「$ node index.js 緯度,経度」というようなコマンドで、バッチプログラムを実行できるようになる。
参考資料
-
ref.
- npmでnode.jsのpackageを管理する - Qiita
- Modules Node.js v0.11.11 Manual & Documentation (module.exports)
- process Node.js v0.11.11 Manual & Documentation (process.argv)
- Query String Node.js v0.11.11 Manual & Documentation (querystring.stringify)
- HTTP Node.js v0.11.11 Manual & Documentation (http.request)
- xml2js
- YOLP(地図):Yahoo!リバースジオコーダAPI - Yahoo!デベロッパーネットワーク
tags: node.js
Posted by NI-Lab. (@nilab)