連想語・関連語API（メタデータ株式会社）と駅すぱあと路線図を連携してみた

今回はメタデータ株式会社さんから提供されている連想語・関連語APIと駅すぱあと路線図を連携してみました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31425/e9cde24d-24b8-9209-54ae-c61886332650.png" width=20%>


## はじめに
連想語・関連語APIでは、キーワードから連想される言葉を取得することができます。
今回は駅すぱあと路線図上で選択した駅を連想語・関連語APIに渡し、返ってきた連想語のうち、駅名になっているものを表示するようにしてみます。

## 今回利用するサービスと機能
* 駅すぱあと路線図
    * 駅すぱあとPlayground
    * HTMLPopup
* 連想語・関連語API（メタデータ株式会社）

※ 今回、駅すぱあと路線図については詳しく説明しませんので、知りたい方は過去の記事を参照してください。

## 連想語・関連語APIの利用
まずは連想語・関連語APIの利用する準備をします。
連想語・関連語APIの利用を開始するには以下の手順を踏みます。

1. メタデータ株式会社さんのHPにアクセスし、[連想語・関連語APIのページ](https://metadata.co.jp/apis/word-associator-specifications.html)に移動します。
2. 「公開ページ」と書かれた部分にURL( http://ap.mextractr.net/ma9/ma9signup )が記載されているので、そちらに移動します。
3. 「JAPANESE VERSION」というボタンをクリックします。
4. 「Register」というタブがあるので、こちらにユーザ名、メールアドレス、パスワードを設定します。ここでのユーザ名とパスワードをAPI呼び出し時の認証に利用します。

これでAPIを利用する準備は完了です。

## 実装
### jQueryの追加
今回は、外部APIを利用するので、jqueryを読み込みを追加します。

```html
:
<script src="https://rmap.ekispert.jp/production/rosen.js"></script>

<!-- jqueryの追加 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
:
```

### 関連語を取得して路線図状に表示

```html
:
<script>
    :
    rosen.on('selectStation', function(data) {
      // 駅がクリックされたら既にあるポップアップなどを全てクリアします
      rosen.clearAll();

      // 選択された駅を取得（１つだけ）
      select_station = data.stations[0];
      // 選択された駅にマーカーを表示
      rosen.setStationMarker(select_station.code);

      // 中野(東京都)のような都道府県部分があると関連語が取れないため削除
      // 駅を関連語として取得しやすくするために末尾に「駅」を追加
      query_name = select_station.name.split('(')[0] + "駅";
      $.ajax
        ({
          type: "GET",
          url: "http://wordassociator.ap.mextractr.net/word_associator/api_query",
          dataType: 'json',
          async: false,
          data: {
            query: query_name,
          },
          beforeSend: function (xhr) {
            // usernameとpasswordは別途設定。値は最初に登録したもの。
            xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
          },
          success: function (data){
            // 選択した駅に結果をポップアップで表示
            var message = "■" + select_station.name + "駅\n";
            data.forEach( function(value) {
              message = message + "関連語: " + value[0] + "(" + value[1] +")\n";
            })
            var text_popup = Rosen.textPopup();
            text_popup.setComment(message);
            rosen.setStationPopup(select_station.code, text_popup);

            // 関連語から末尾が駅のものだけ抽出
            var result_stations = data.filter( function( value ) {
              return value[0].lastIndexOf('駅') == (value[0].length - 1);
            })

            // 駅名から駅コードを取得してプロット（とりあえず上位5つ）
            for(let i = 0; i < 5; i++) {
              search_st_name = result_stations[i][0].substr(0, result_stations[i][0].length - 1);
              rosen.searchStationsByName(
                search_st_name,
                {limit: 1}
              ).then(function(stations){
                console.log(stations[0].code);
                rosen.setStationMarker(stations[0].code, {type: "circle", radius: result_stations[i][1]*50, color: "#0000ff", opacity: 0.3});
              });
            }
          }
        });
    });
</script>
:
```

### 補足
#### jQueryのAjaxでBasic認証を呼ぶ
「連想語・関連語API」はBasic認証となりますので、リクエストする際には以下の設定をします。

```javascript
  beforeSend: function (xhr) {
    // usernameとpasswordは別途設定。値は最初に登録したもの。
    xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
```

#### CORSの回避
CORSのエラーを解決できなかったので、今回はSafariのクロスオリジンの制限を無効にする設定を使いました。（セキュリティ上あまり良くないです。今回はあくまで動かす目的。）
参考: [CORSエラー対策 - Qiita](https://qiita.com/ta-ke-no-bu/items/b7cd4b4719249a9c365e)

参考: [jQueryとAJAXでBasic Authを使用するには？ - コードログ](https://codeday.me/jp/qa/20181130/12788.html)

### 路線図に表示
<img width="1065" alt="スクリーンショット 2019-09-14 19.35.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31425/1d21fb22-f239-13dd-bdc0-df1bcb92e507.png">

### おわりに
今回はメタデータ株式会社さんの「連想語・関連語API」を使ってみました。
jQueryのAjaxでBasic認証をする部分にだいぶハマりましたが、外部APIの利用の幅が広がった気がします。