Yahoo!ジオコーダAPIで行政区ではなく政令指定都市を検索する

## 概要

- [YOLP\(地図\):Yahoo\!ジオコーダAPI](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html) で検索文字列に「名古屋市」を指定すると、「愛知県名古屋市中区」という「区」がヒットし、「愛知県名古屋市」がヒットしない
- 「愛知県名古屋市」をヒットさせるには exclude_seireishi=false というパラメータをつける必要がある

## exclude_seireishi パラメータ

[YOLP\(地図\):Yahoo\!ジオコーダAPI \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html)

> falseを指定すると、検索対象に政令指定都市レコードを含めて検索します。（デフォルト: true）

「名古屋市」は政令指定都市なので、「名古屋市」を検索対象から除外したくなければ exclude_seireishi=false を指定する。

[政令指定都市 \- Wikipedia](https://ja.wikipedia.org/wiki/%E6%94%BF%E4%BB%A4%E6%8C%87%E5%AE%9A%E9%83%BD%E5%B8%82)

> 政令指定都市（せいれいしていとし）は、日本の大都市制度の1つ。2018年（平成30年）現在、全国に20市が存在する。

> 指定都市は、条例で区を設けるものとされている（第252条の20第1項）。この区は、東京都の特別区（東京23区の各区）と区別して、「行政区」と通称される。

2018年(平成30年)現在の政令指定都市(20市)

- 北海道 札幌市
- 宮城県 仙台市
- 埼玉県 さいたま市
- 千葉県 千葉市
- 神奈川県 横浜市
- 神奈川県 川崎市
- 神奈川県 相模原市
- 新潟県 新潟市
- 静岡県 静岡市
- 静岡県 浜松市
- 愛知県 名古屋市
- 京都府 京都市
- 大阪府 大阪市
- 大阪府 堺市
- 兵庫県 神戸市
- 岡山県 岡山市
- 広島県 広島市
- 福岡県 北九州市
- 福岡県 福岡市
- 熊本県 熊本市

## URLとレスポンスの例

### 検索対象に政令指定都市レコードを含めないで検索する場合

URL

```
https://map.yahooapis.jp/geocode/V1/geoCoder?appid=<YOUR APPLICATION ID>&query=名古屋市&al=2&results=1&output=json
```

整形済みのレスポンス例

```
{
  "ResultInfo": {
    "Count": 1,
    "Total": 16,
    "Start": 1,
    "Status": 200,
    "Description": "",
    "Copyright": "",
    "Latency": 0.013
  },
  "Feature": [
    {
      "Id": "23106",
      "Gid": "",
      "Name": "愛知県名古屋市中区",
      "Geometry": {
        "Type": "point",
        "Coordinates": "136.91018390,35.16860040",
        "BoundingBox": "136.89194200,35.14216100 136.92979500,35.18750800"
      },
      "Category": [],
      "Description": "",
      "Style": [],
      "Property": {
        "Uid": "1fa68b73785c1fcf590777f4acb229013a88643d",
        "CassetteId": "b22fee69b0dcaf2c2fe2d6a27906dafc",
        "Yomi": "アイチケンナゴヤシナカク",
        "Country": {
          "Code": "JP",
          "Name": "日本"
        },
        "Address": "愛知県名古屋市中区",
        "GovernmentCode": "23106",
        "AddressMatchingLevel": "2",
        "AddressType": "区"
      }
    }
  ]
}
```

### 検索対象に政令指定都市レコードを含めて検索する場合

URL

```
https://map.yahooapis.jp/geocode/V1/geoCoder?appid=<YOUR APPLICATION ID>&query=名古屋市&al=2&results=1&output=json&exclude_seireishi=false
```

整形済みのレスポンス例

```
{
  "ResultInfo": {
    "Count": 1,
    "Total": 17,
    "Start": 1,
    "Status": 200,
    "Description": "",
    "Copyright": "",
    "Latency": 0.015
  },
  "Feature": [
    {
      "Id": "23100",
      "Gid": "",
      "Name": "愛知県名古屋市",
      "Geometry": {
        "Type": "point",
        "Coordinates": "136.90648920,35.18130390",
        "BoundingBox": "136.79180800,35.03387300 137.06092800,35.26045300"
      },
      "Category": [],
      "Description": "",
      "Style": [],
      "Property": {
        "Uid": "a528dbd990667e271a8a0dca98fc1b227980fb2a",
        "CassetteId": "b22fee69b0dcaf2c2fe2d6a27906dafc",
        "Yomi": "アイチケンナゴヤシ",
        "Country": {
          "Code": "JP",
          "Name": "日本"
        },
        "Address": "愛知県名古屋市",
        "GovernmentCode": "23100",
        "AddressMatchingLevel": "2",
        "AddressType": "政令指定都市"
      }
    }
  ]
}
```

## Node.js によるサンプル

### request モジュールを使う

HTTP 通信部分をラクに処理するため、 [request](https://www.npmjs.com/package/request) モジュールを使う。

npm で request パッケージをインストールしておく。

```
$ npm install request
```

### ソースコード

```js
'use strict';

// 都道府県を緯度経度に変換する
function geocode(address, appid) {
    const qs = require('querystring');
    const params = qs.stringify({
        'appid': appid,
        'query': address,
        'al': 2, // 市区町村レベルの住所を検索
        'exclude_seireishi': false, // 検索対象から政令指定都市レコードを除外するか
        'results': 3, // 検索結果を3件以内に設定
        'output': 'json'
    });
    const url = 'https://map.yahooapis.jp/geocode/V1/geoCoder?' + params;
    return new Promise(function (resolve, reject) {
        const request = require('request');
        request(url, function (error, response, body) {
            const ydf = JSON.parse(body);
            if (!error && response.statusCode === 200) {
                resolve(ydf);
            } else {
                reject({error: response});
            }
        });
    });
}

const address = '名古屋市';
const appid = '<YOUR APPLICATION ID>'; // アプリケーションIDを指定する
geocode(address, appid)
    .then(ydf => {
        for (const feature of ydf.Feature) {
            const name = feature.Name;
            const lonlat = feature.Geometry.Coordinates.split(',');
            console.log('------------------------------');
            console.log('Name: ' + name);
            console.log('Latitude: ' + lonlat[1]);
            console.log('Longitude: ' + lonlat[0]);
        }
    })
    .catch(reason => {
        console.log('ERROR!!!');
        console.log(reason);
    });
```

### 実行結果

パラメータ exclude_seireishi=false を指定することで、「愛知県名古屋市」が検索結果の最初に出現する。

```
$ node --version
v8.10.0

$ node geocoder.js
------------------------------
Name: 愛知県名古屋市
Latitude: 35.18130390
Longitude: 136.90648920
------------------------------
Name: 愛知県名古屋市中区
Latitude: 35.16860040
Longitude: 136.91018390
------------------------------
Name: 愛知県名古屋市中村区
Latitude: 35.16874910
Longitude: 136.87301510
```

## 参考資料

- [YOLP\(地図\):Yahoo\!ジオコーダAPI \- Yahoo\!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html)
- [政令指定都市 \- Wikipedia](https://ja.wikipedia.org/wiki/%E6%94%BF%E4%BB%A4%E6%8C%87%E5%AE%9A%E9%83%BD%E5%B8%82)