LoginSignup
3
4

More than 5 years have passed since last update.

Node.js で Yahoo!ローカルサーチAPI をコールするサンプルコード

Posted at

ソースコード

'use strict';

const https = require('https');
const querystring = require('querystring');
const { URL } = require('url');

class LocalSearch {

  constructor(appid) {
    this.appid = appid;
  }

  get(url, headers, callback) {

    const urlObj = new URL(url);
    const options = {
      protocol: urlObj.protocol,
      port: urlObj.port,
      host: urlObj.hostname,
      path: urlObj.pathname + urlObj.search,
      headers: headers,
      timeout: 3 * 1000
    };

    const req = https.get(options, (res) => {

      if (res.statusCode != 200) {
        let error = new Error(res.statusCode + ': ' + res.statusMessage);
        error.code = 'ERR_HTTP_INVALID_STATUS_CODE';
        callback(error, null);
        return;
      }

      res.setEncoding('utf8');
      let rawData = '';

      res.on('data', (chunk) => {
        rawData += chunk;
      });

      res.on('end', () => {
        callback(null, rawData);
      });

      res.on('error', (e) => {
        callback(e, null);
      });
    });

    let errorOrigin = null;

    req.on('timeout', () => {
      errorOrigin = new Error('TIMEOUT');
      errorOrigin.code = 'ECONNRESET';
      req.abort();
    });

    req.on('error', (e) => {
      if (errorOrigin != null) {
        callback(errorOrigin, null);
      } else {
        callback(e, null);
      }
    });

    req.end();
  }

  json2pois(json) {
    const result = [];
    const data = JSON.parse(json);
    for (let i=0; i<data.Feature.length; i++) {
      const f = data.Feature[i];
      if (f.Geometry.Type == 'point') {
        const ll = f.Geometry.Coordinates.split(',');
        result.push({ name: f.Name, lat: ll[1], lon: ll[0] });
      }
    }
    return result;
  }

  search(query, callback) {

    const baseURL = 'https://map.yahooapis.jp/search/local/V1/localSearch';

    const qs = querystring.stringify({
      query: query,
      output: 'json',
      results: '3',
      sort: 'score'
    });

    const url = baseURL + '?' + qs;

    const headers = {
      'User-Agent': 'Yahoo AppID: ' + this.appid
    };

    const self = this;
    this.get(url, headers, function(error, json) {
      if (error == null) {
        const pois = self.json2pois(json);
        callback(null, pois);
      } else {
        callback(error, null);
      }
    });
  }
}

const appid = 'YOUR APPLICATION ID';
const query = '東京タワー';
new LocalSearch(appid).search(query, function(error, pois) {
  if (error == null) {
    for (let i=0; i<pois.length; i++) {
      const p = pois[i];
      console.log(p.name);
      console.log(' ' + p.lat + ', ' + p.lon);
      console.log();
    }
  } else {
    console.log(error.code + ': ' + error.message);
  }
});

実行結果

$ node localsearch.js
東京タワー大展望台 club333特設ステージ
 35.65870316, 139.74540779

東京タワー
 34.729707500000, 136.519455833333

マザー牧場CAFE東京タワー店
 35.658703055556, 139.745407777778

参考資料

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4