「駅すぱあとWebサービス」を使ったサンプルの改造(検索自動発火、GoogleMap追加)

Vue.js
スポンサーリンク

先日作った下記サンプルを自分なりに改造したので、備忘メモです。

「駅すぱあとWebサービス」を使って駅の情報を取ってくるサンプル
はじめに Vue.jsと「駅すぱあとWebサービス」を利用して、駅名の検索および駅の路線情報等々を取得するサンプルを作ってみました。 必要な準備 「駅すぱあとWebサービス」を利用するにあたり、APIキーを取得する必要があります。下記サイト...

改造項目は、下記2点にします。

  • キーワードの入力を検知して自動的に検索を実行する
  • 検索した駅周辺の地図を表示する(GoogleMapを使う)

検索処理の自動化

検索キーワードを入力後、自動的に検索できるようにJavascript側に以下を追記します。

watch: {
    searchWord: function(newKeyword, oldKeyword){
        // lodash.debounceを利用してAPI呼び出しの負荷軽減
        this.debouncedSearchList();
    }
},
created: function() {
  // lodash.debounce によって、0.5秒間操作が無くなった時点でAPI呼び出し実施
  // キー入力の度にAPIを呼び出すような負荷をかけないため
  this.debouncedSearchList = _.debounce(this.searchList, 500);
},

lodashを利用するため、HTML側に下記1行を追加します。

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

ここまで出来ると、検索ボタンが既に意味ないボタンになりますね。。。

駅周辺の地図表示

追加で、駅周辺の地図を表示できるようにGoogleMAPのAPIを利用して地図表示をします。

まずはHTMLに地図表示ボタンと地図表示エリアを用意しておきます。

地図表示ボタン

    <button v-on:click="googleMap('map',station)">地図表示</button>

地図の表示エリア

<div id="googlemap" style="width:500px; height:300px;"></div>

また、GoogleMapのAPIを利用するため、下記1行を追記します。{APIキーを指定}の部分は自分のものを指定して下さい。(取得方法は後述)

<script src="//maps.googleapis.com/maps/api/js?key={APIキーを指定}"></script>

続けて、Javascriptで地図情報を表示します。

googleMap: function (id, station){
    this.initStationInfo();
    var latlng = new google.maps.LatLng( station.GeoPoint.lati_d, station.GeoPoint.longi_d );
    var mapDiv = document.getElementById( "googlemap" );
    var map = new google.maps.Map( mapDiv, {
        center: latlng,
        zoom: 13 ,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    } ) ;
},

 

最終的に出来上がったソースは以下になります。

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>
          <button v-on:click="googleMap('map',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>
        <div id="googlemap" style="width:500px; height:300px;"></div>
      </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="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
  <script src="//maps.googleapis.com/maps/api/js?key={APIキーを指定}"></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: [],    // 駅の福祉施設情報
    },
    watch: {
        searchWord: function(newKeyword, oldKeyword){
            // lodash.debounceを利用してAPI呼び出しの負荷軽減
            this.debouncedSearchList();
        }
    },
    created: function() {
      // lodash.debounce によって、0.5秒間操作が無くなった時点でAPI呼び出し実施
      // キー入力の度にAPIを呼び出すような負荷をかけないため
      this.debouncedSearchList = _.debounce(this.searchList, 500);
    },
    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)
            })
        },
        googleMap: function (id, station){
            this.initStationInfo();
            var latlng = new google.maps.LatLng( station.GeoPoint.lati_d, station.GeoPoint.longi_d );
            var mapDiv = document.getElementById( "googlemap" );
            var map = new google.maps.Map( mapDiv, {
                center: latlng,
                zoom: 13 ,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            } ) ;
        },
    }
})

 

参考情報

GoogleMap APIの利用方法について、下記サイトを参考にさせてもらいました。

Google Maps API の使い方 利用方法
Google Maps API の基本的な使い方から簡単な応用まで。APIキーの取得から地図、マーカー、情報ウィンドウの表示やイベントの設定方法、ジオコーディング、Directions API、Places Service プレイス、Map...

 

コメント