「駅すぱあとWebサービス」を使って駅の情報を取ってくるサンプル

Vue.js
スポンサーリンク

はじめに

Vue.jsと「駅すぱあとWebサービス」を利用して、駅名の検索および駅の路線情報等々を取得するサンプルを作ってみました。

必要な準備

「駅すぱあとWebサービス」を利用するにあたり、APIキーを取得する必要があります。下記サイトから申請すると、数営業日で無料発行してもらえます。(今回は即日発行していただけました)

ご利用の手引き
経路検索・公共交通機関データの「駅すぱあと API」の開発者向けドキュメントサイトです。駅データ利用、乗り換え案内などのTipsやリファレンスが満載です。

やること

  • 「駅すぱあとWebサービス」を使って駅名を検索して結果を取得
  • 「駅すぱあとWebサービス」を使って駅の路線情報などを取得
  • 上記の取得した情報をVue.jsで画面に表示

駅すぱあとWebサービスへのアクセスには axios というHTTPクライアントを利用します。

検索結果の取得

検索結果が1件だけの場合は連想配列が直接返ってきますが、複数件あった場合は連想配列の配列が返ってくるので、条件分岐を追加してます。

こんな感じ。

           .then(function(response){
                if(response.data.ResultSet.max == '0'){
                    // 検索結果が0件→何も入れない
                    self.stations = [];
                }else if( response.data.ResultSet.max == '1' ){
                    // 検索結果が1件→オブジェクトを配列に追加
                    self.stations.push(response.data.ResultSet.Point);
                }else{
                    // 検索結果が複数件→オブジェクトの配列を追加
                    self.stations = response.data.ResultSet.Point;
                }
            })
            .catch(function(error){
                self.stations = [];
                console.log("API ERROR by searchList!", error);
            });

同様に、駅個別の情報(例えば出口情報など)も結果が1件のみの場合と複数件ある場合とで返り方が違うので、条件分岐してます。

こんな感じ。

                    if( typeof response.data.ResultSet.Information.Exit != 'undefined' ){
                        if( typeof response.data.ResultSet.Information.Exit.length == 'undefined'){
                            //1つだけ
                            self.stationInfoExits.push(response.data.ResultSet.Information.Exit);
                        }else{
                            //複数ある場合、オブジェクトの配列が返ってくるので、そのまま入れる。
                            self.stationInfoExits = response.data.ResultSet.Information.Exit;
                        }

Vue.jsで表示

v-forを使って取得情報を一覧表示します。また、駅個別の情報は最初非表示にしておきたいので、v-ifを使って非表示にしておきます。

こんな感じ。

v-for

        <li v-for="station in stations" v-bind:id="station.Station.code">
        {{station.Station.Name}}
          <button v-on:click="searchInfo('rail',station)">路線</button>
          <button v-on:click="searchInfo('nearrail',station)">最寄路線</button>
          <button v-on:click="searchInfo('exit',station)">出口</button>
          <button v-on:click="searchInfo('welfare', station)">福祉施設</button>
        </li>

v-if

        <h2 v-if="selectedStation.Station.Name">{{selectedStation.Station.Name}}の情報</h2>
        <ul v-if="selectedStation.Station.Name">
          <li>駅名:{{selectedStation.Station.Name}}</li>
          <li>よみ:{{selectedStation.Station.Yomi}}</li>
          <li>都道府県:{{selectedStation.Prefecture.Name}}</li>
          <li>緯度,経度:{{selectedStation.GeoPoint.lati_d}},{{selectedStation.GeoPoint.longi_d}}</li>
        </ul>

最終的な出来上がり

ソース全体はこんな感じ。うーん、改善の余地ありそうですが。。。

HTML

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8" />
  <title>駅情報一覧</title>
  <style>
    li{
      list-style-type: none;
    }
    .List {
      float: left;
      color: red;
    }
    .Info {
      float: left;
      color: blue;
    }
  </style>
</head>
<body>
  <div id="app">
    <input type="text" v-model="searchWord"></input>
    <button v-on:click="searchList">検索</button>
    <p>{{searchWord}}</p>
    <div class="List">
      <ul>
        <li v-for="station in stations" v-bind:id="station.Station.code">
        {{station.Station.Name}}
          <button v-on:click="searchInfo('rail',station)">路線</button>
          <button v-on:click="searchInfo('nearrail',station)">最寄路線</button>
          <button v-on:click="searchInfo('exit',station)">出口</button>
          <button v-on:click="searchInfo('welfare', station)">福祉施設</button>
        </li>
      </ul>
    </div>
    <div class="Info">
      <ul>
        <h2 v-if="selectedStation.Station.Name">{{selectedStation.Station.Name}}の情報</h2>
        <ul v-if="selectedStation.Station.Name">
          <li>駅名:{{selectedStation.Station.Name}}</li>
          <li>よみ:{{selectedStation.Station.Yomi}}</li>
          <li>都道府県:{{selectedStation.Prefecture.Name}}</li>
          <li>緯度,経度:{{selectedStation.GeoPoint.lati_d}},{{selectedStation.GeoPoint.longi_d}}</li>
        </ul>
        <h2>{{infoTitle}}</h2>
        <ul>
          <li v-for="rail in stationInfoRails">
            {{rail}}
          </li>
          <li v-for="nearrail in stationInfoNearRails">
            {{nearrail}}
          </li>
          <li v-for="exit in stationInfoExits">
            {{exit.Name}}:
            <ul>
              <!-- 改行が含まれるので preタグで -->
              <li><pre>{{exit.Comment}}</pre></li>
            </ul>
          </li>
          <li v-for="welfare in stationInfoWelfares">
            {{welfare.Name}}:
            <ul>
              <!-- 改行が含まれるので preタグで -->
              <li><pre>{{welfare.Comment}}</pre></li>
            </ul>
          </li>
        </ul>
      </ul>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js"></script>
  <script src="./js/main.js"></script>
  </body>
</html>

Javascript

var ACCESSKEY = "ここにAPIキー";
var API_LIST_URL = "https://api.ekispert.jp/v1/json/station?key=" + ACCESSKEY;
var API_INFO_URL = "https://api.ekispert.jp/v1/json/station/info?key=" + ACCESSKEY;

var app = new Vue({
    el: '#app',
    data: {
        searchWord: '',
        stations: [],               // 駅一覧
        infoTitle: '',              // 情報のタイトル(路線、最寄路線、出口、福祉施設)
        selectedStation: {'Station': {}, 'GeoPoint': {}, 'Prefecture': {}},        // 駅
        stationInfoCorps: [],       // 駅の会社名
        stationInfoRails: [],       // 駅の路線情報
        stationInfoNearRails: [],   // 駅の最寄路線情報
        stationInfoExits: [],       // 駅の出口情報
        stationInfoWelfares: [],    // 駅の福祉施設情報
    },
    methods: {
        initStationInfo: function(){
            this.stationInfoCorps = [];
            this.stationInfoRails = [];
            this.stationInfoNearRails = [];
            this.stationInfoExits = [];
            this.stationInfoWelfares = [];
            this.selectedStation = {'Station': {}, 'GeoPoint': {}, 'Prefecture': {}};
            this.infoTitle = "";
        },
        // 駅一覧を取得
        searchList: function (e) {
            this.stations = [];
            this.initStationInfo();
            var URL = API_LIST_URL + "&name=" + this.searchWord;
            var self = this;
            if(this.searchWord === '') return;
            axios.get(URL)
            .then(function(response){
                if(response.data.ResultSet.max == '0'){
                    // 検索結果が0件→何も入れない
                    self.stations = [];
                }else if( response.data.ResultSet.max == '1' ){
                    // 検索結果が1件→オブジェクトを配列に追加
                    self.stations.push(response.data.ResultSet.Point);
                }else{
                    // 検索結果が複数件→オブジェクトの配列を追加
                    self.stations = response.data.ResultSet.Point;
                }
            })
            .catch(function(error){
                self.stations = [];
                console.log("API ERROR by searchList!", error);
            });
        },
        // 駅の情報を取得
        searchInfo: function (id, station) {
            this.initStationInfo();
            this.selectedStation = station;
            // station.Station.code ・・・ 駅コード
            // id ・・・ 取得する情報種別(rail, nearrail, exit, welfare)
            var URL = API_INFO_URL + "&code=" + station.Station.code + "&type=" + id;
            console.log(URL);
            var self = this;
            axios.get(URL)
            .then(function(response){
                // 会社情報を取得する ←取得するけど路線情報で十分だと思うので、表示しない
                if( typeof response.data.ResultSet.Information.Corporation != 'undefined'){
                    if( typeof response.data.ResultSet.Information.Corporation.length == 'undefined' )
                    {
                        //1つだけ
                        self.stationInfoCorps.push(response.data.ResultSet.Information.Corporation.Name);
                    }else{
                        //複数ある場合
                        for(var i = 0; i < response.data.ResultSet.Information.Corporation.length; i ++){
                            self.stationInfoCorps.push( response.data.ResultSet.Information.Corporation[i].Name);
                        }
                    }
                }
                // 路線情報を取得する
                if( response.data.ResultSet.Information.Type == "rail"){
                    self.infoTitle = '路線情報';
                    if( typeof response.data.ResultSet.Information.Line != 'undefined' ){
                        if( typeof response.data.ResultSet.Information.Line.length == 'undefined' ){
                            //1つだけ
                            self.stationInfoRails.push(response.data.ResultSet.Information.Line.Name);
                        }else{
                            //複数ある場合
                            for(var i= 0; i < response.data.ResultSet.Information.Line.length; i++){
                                self.stationInfoRails.push(response.data.ResultSet.Information.Line[i].Name);
                            }
                        }
                    }else{
                        self.stationInfoRails.push("路線なし");
                    }
                // 最寄路線情報を取得する
                }else if (response.data.ResultSet.Information.Type == "nearrail"){
                    self.infoTitle = '最寄路線';
                    if( typeof response.data.ResultSet.Information.Line != 'undefined' ){
                        if( typeof response.data.ResultSet.Information.Line.length == 'undefined'){
                            //1つだけ
                            self.stationInfoNearRails.push(response.data.ResultSet.Information.Line.Name);
                        }else{
                            //複数
                            for(var i= 0; i < response.data.ResultSet.Information.Line.length; i++){
                                self.stationInfoNearRails.push(response.data.ResultSet.Information.Line[i].Name);
                            }
                        }
                    }else{
                        self.stationInfoNearRails.push("最寄路線なし");
                    }
                // 出口情報を取得する
                }else if (response.data.ResultSet.Information.Type == "exit"){
                    self.infoTitle = '出口情報';
                    if( typeof response.data.ResultSet.Information.Exit != 'undefined' ){
                        if( typeof response.data.ResultSet.Information.Exit.length == 'undefined'){
                            //1つだけ
                            self.stationInfoExits.push(response.data.ResultSet.Information.Exit);
                        }else{
                            //複数ある場合、オブジェクトの配列が返ってくるので、そのまま入れる。
                            self.stationInfoExits = response.data.ResultSet.Information.Exit;
                        }
                    }else{
                        self.stationInfoExits.push({"Name": "出口情報なし"});
                    }
                // 福祉施設情報を取得する
                }else if (response.data.ResultSet.Information.Type == "welfare"){
                    self.infoTitle = '福祉施設情報';
                    if( typeof response.data.ResultSet.Information.WelfareFacilities != 'undefined' ){
                        if( typeof response.data.ResultSet.Information.WelfareFacilities.length == 'undefined'){
                            //1つだけ
                            self.stationInfoWelfares.push(response.data.ResultSet.Information.WelfareFacilities);
                        }else{
                            //複数ある場合、オブジェクトの配列が返ってくるので、そのまま入れる。
                            self.stationInfoWelfares = response.data.ResultSet.Information.WelfareFacilities;
                        }
                    }else{
                        self.stationInfoWelfares.push({"Name": "福祉施設情報なし"});
                    }
                }
            })
            .catch(function(error){
                self.stationInfo = {};
                console.log("API_ERROR by searchInfo!", error)
            })
        },
    }
})

駅名検索をインクリメントサーチ化できれば、、、というところですが、ひとまず今日はココまでです。

参考

フリープランAPI概要
経路検索・公共交通機関データの「駅すぱあと API」の開発者向けドキュメントサイトです。駅データ利用、乗り換え案内などのTipsやリファレンスが満載です。

 

 

コメント