Spring Boot + Thymeleaf + JavaScript + 駅データAPI + GoogleMapsAPIで簡単なアプリつくってみた

## 概要
前回はSpringBootで郵便番号検索APIを使用して、JSON形式のレスポンスをjavaオブジェクトに変換することを紹介しました。
[簡単！Spring BootでWebAPIをたたいてJSON形式のレスポンスをjavaオブジェクトに変換](http://qiita.com/yk0614/items/c306bddc66ab7882c7ba)

今回は駅データ.jpが公開している駅データAPI、GoogleMapsAPIを使用して下記のような都道府県を選択→路線を選択→駅名を選択すると、GoogleMapに選択した駅名を表示させるアプリケーションをつくってみました！つくってみましたと言いますが、駅データ.jpにプルダウンの選択条件の絞り込みのjavascriptのサンプルがありましたので、ほぼほぼ使わせて頂き少しアレンジしただけです。あとはGoogleMapsAPI使用するためのキー取得して、controllerとtemplateつくって、都道府県のenumつくっただけです。。。

<strong>開発環境</strong>

- macOS Sierra 10.12
- java version 1.8.0_65
- Spring-Boot 1.3.5
 - Thymeleaf
 - Gradle

<strong>参考資料</strong>

- http://www.ajaxtower.jp/googlemaps/charset/index1.html
- http://www.ekidata.jp/api/api_line.php
- http://www.ajaxtower.jp/googlemaps/



## 完成図
    
※mapの初期値の中心座標は東京駅に設定

| 都道府県選択|      
|:-----------:|      
|     <img width="639" alt="スクリーンショット 2016-12-01 22.40.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/f40eaf9e-acde-a05f-a919-ae41bbdb9a54.png">
                          |  

| 路線選択|      
|:-----------:|      
|    <img width="636" alt="スクリーンショット 2016-12-01 22.40.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/cf2f75d9-5ae6-7d33-c71f-f6a89ef804b7.png">
                          |  

| 駅名選択|      
|:-----------:|      
|     <img width="636" alt="スクリーンショット 2016-12-01 22.41.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/acedb9a8-cfe6-611a-1184-29b9dba0c057.png">
                          |  

| はい！選択した駅名がmapの中心にきました！|      
|:-----------:|      
|     <img width="632" alt="スクリーンショット 2016-12-01 22.39.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/9cfd061a-eabc-2580-484d-10bcea5f01bd.png">
                          |  


## Controller

/にアクセスして都道府県enumから都道府県コードと名称をmodelに詰めてるだけですね。
残りはJavaScriptとthymeleafだけ。

```java:TopController.java
@Controller
public class TopController {

	@RequestMapping("/")
	public String top(HttpSession session, Model model) {
		
		PrefectureEnum[] types = PrefectureEnum.values();
		List<PrefectureDto> prefList = new ArrayList<>();
		
		for (PrefectureEnum m : types) {
			PrefectureDto dto = new PrefectureDto();
			dto.setPrefCode(m.getCode());
			dto.setPrefName(m.getFullName());
			prefList.add(dto);
		}
		model.addAttribute("prefList", prefList);
		
		return "top";
	}
}
```

## 都道府県Enum

[Github](https://github.com/keiyonekawa0614/awakenoy0614/blob/master/Sample/src/main/java/com/example/common/PrefectureEnum.java)に公開しております。ご自由にお使いください！！


## JavaScript

殆ど[こちら](http://www.ekidata.jp/api/sample_drilldown.php)のサンプルのコピペですが、一番苦戦してしまいました！！何故ならJavaScriptを初めて書いたからですw
javascriptで叩いたAPIの戻り値緯度・経度をどうやってhtmlのoptionタグのバリュー値に入れて、プルダウンで選択したバリュー値をjavascriptに引き渡せばいいのかハマりました。。
formで緯度・経度をpostパラメータで渡して、次の画面でmapを表示ならすぐ出来そうでしたが、1画面でまとめたほうがスマートでユーザビリティとして間違いなく良いので、諦めませんでした！！

結局書いたjsがこちら
↓

```javascript:station.js
var xml = {};
function setMenuItem(type, code) {

	var s = document.getElementsByTagName("head")[0].appendChild(document
			.createElement("script"));
	s.type = "text/javascript";
	s.charset = "utf-8";

	var optionIndex0 = document.form.s0.options.length; // 沿線のOPTION数取得
	var optionIndex1 = document.form.s1.options.length; // 駅のOPTION数取得
	var latlng;
	var marker;

	if (type == 0) {
		for (i = 0; i <= optionIndex0; i++) {
			document.form.s0.options[0] = null
		} // 沿線削除
		for (i = 0; i <= optionIndex1; i++) {
			document.form.s1.options[0] = null
		} // 駅削除
		document.form.s1.options[0] = new Option("----", 0); // 駅OPTIONを空に
		if (code == 0) {
			document.form.s0.options[0] = new Option("----", 0); // 沿線OPTIONを空に
		} else {
			s.src = "http://www.ekidata.jp/api/p/" + code + ".json"; // 沿線JSONデータURL
		}
	} else if (type == 1) {
		for (i = 0; i <= optionIndex1; i++) {
			document.form.s1.options[0] = null
		} // 駅削除
		if (code == 0) {
			document.form.s1.options[0] = new Option("----", 0); // 駅OPTIONを空に
		} else {
			s.src = "http://www.ekidata.jp/api/l/" + code + ".json"; // 駅JSONデータURL
		}
	} else {
		var aa = document.form.s1.value;
		var data = aa.split(",");
		latlng = new google.maps.LatLng(data[0], data[1]);
		// Mapを作成
		map = new google.maps.Map(document.getElementById("map"), {
			zoom : 16,
			mapTypeId : google.maps.MapTypeId.ROADMAP, // 通常の地図
			center : latlng,
		});
		marker = new google.maps.Marker({ // マーカーの追加
			position : latlng, // マーカーを立てる位置を指定
			map : map
		// マーカーを立てる地図を指定
		});
	}

	xml.onload = function(data) {
		var line = data["line"];
		var station_l = data["station_l"];
		if (line != null) {
			document.form.s0.options[0] = new Option("----", 0); // OPTION1番目はNull
			for (i = 0; i < line.length; i++) {
				ii = i + 1 // OPTIONは2番目から表示
				var op_line_name = line[i].line_name;
				var op_line_cd = line[i].line_cd;
				document.form.s0.options[ii] = new Option(op_line_name,
						op_line_cd);
			}
		}
		if (station_l != null) {
			document.form.s1.options[0] = new Option("----", 0); // OPTION1番目はNull
			for (i = 0; i < station_l.length; i++) {
				ii = i + 1 // OPTIONは2番目から表示
				var op_station_name = station_l[i].station_name;
				var op_station_cd = station_l[i].station_cd;
				var lat = station_l[i].lat;
				var lon = station_l[i].lon;
				document.form.s1.options[ii] = new Option(op_station_name, lat
						+ "," + lon);

			}
		}
	}
}
```

htmlがこちら
↓

```html:top.html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>都道府県から沿線/駅表示プルダウン表示</title>
<script
	src="http://maps.googleapis.com/maps/api/js?key=AIzaSyBuF7sKBPtJawa0sNDuil2ysI8vN5eXjnc"
	type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript" th:src="@{/javascript/station.js}"></script>
<script type="text/javascript" th:src="@{/javascript/googlemap.js}"
	th:inline="javascript"></script>
</head>

<body onload="init()">
<div style="width: 50%;border:#d0d0d0 ridge 5px;background-color : #000080;">
	<form name="form">
		<select name="pref"
			onChange="setMenuItem(0,this[this.selectedIndex].value)">
			<option value="0" selected="selected">-----</option>
			<th:block th:each="item : ${prefList}" th:object="${item}">
				<option th:value="*{prefCode}" th:text="*{prefName}">サンプル1</option>
			</th:block>
		</select><font color="#ffffff">>></font><select name="s0"
			onChange="setMenuItem(1,this[this.selectedIndex].value)">
			<option selected="selected">----</option>
		</select><font color="#ffffff">>></font><select name="s1"
			onChange="setMenuItem(2,this[this.selectedIndex].value)">
			<option selected="selected">----</option>
		</select><br />
		<font color="#ffffff">※都道府県から路線/駅を選択してください</font>
	</form>
	</div>
	
	<div id="map" style="width: 50%; height: 400px;border:#d0d0d0 ridge 5px;"></div>
</body>
</html>
```

サンプルに少しアレンジを加えました。何をしたかというと路線を選択したときに、駅名のオプションタグにnameに駅名、value値に緯度と経度を,(カンマ)区切りで結合させセットさせるようにしました。
そして、駅名のプルダウンで選択されたバリュー値を下記のようにjavascriptで取得し、,(カンマ)でスプリットさせ緯度、経度を取得することに成功しました！！！もっとスマートに書けそうな気がするんだけどな〜〜何かご指摘あればお願いします！
あとはGoogleMapを作成し、緯度経度をセットし、ついでにマーカーもセットしておきました。

```
var aa = document.form.s1.value;
        var data = aa.split(",");
        latlng = new google.maps.LatLng(data[0], data[1]);
        // Mapを作成
        map = new google.maps.Map(document.getElementById("map"), {
            zoom : 16,
            mapTypeId : google.maps.MapTypeId.ROADMAP, // 通常の地図
            center : latlng,
        });
        marker = new google.maps.Marker({ // マーカーの追加
            position : latlng, // マーカーを立てる位置を指定
            map : map
        });
```

初期値のGoogleMapを表示するjsはこれだけ
↓

```javascript:googlemap.js
var map;
var latlng;

function init() {
	// map初期作成 東京駅の緯度経度を設定
	latlng = new google.maps.LatLng(35.681298, 139.766247);
	// Mapを作成
	map = new google.maps.Map(document.getElementById("map"), {
		zoom : 16,
		mapTypeId : google.maps.MapTypeId.ROADMAP, // 通常の地図
		center : latlng,
	});
}
```


GoogleMapsAPIキーの取得は[こちら](http://www.ajaxtower.jp/googlemaps/charset/index1.html)をご参照ください。すぐに取得できます。
GoogleDeveloperConsolesのこんな画面で受け入れるURLを設定するだけですね。


<img width="750" alt="スクリーンショット 2016-12-01 23.40.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/dcb037ac-c4b6-c411-34f6-28e43c851a27.png">

## まとめ
この記事を見て自分でも何か作ってみようと思うきっかけになり、何かお役に立つ事が出来ましたら幸いです。最後まで読んで頂き、ありがとうございました。
何かご指摘等ございましたらコメントに記載してくださるとありがたいです。

## 使用したコード
Githubにソースコード公開しております。
https://github.com/keiyonekawa0614/awakenoy0614/tree/master/Sample

## P.S.
下記記事を参考に私のSpringBoot起動時はこんな感じですw
[Spring Bootの起動バナーの変更](http://qiita.com/5at00001040/items/15e774b8c7b6a8fb93c7)

| SpringBoot起動するゾー！|      
|:-----------:|      
|     <img width="607" alt="スクリーンショット 2016-12-02 0.40.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/119288/a3802c9b-9723-62c6-dda0-2a1623ae6825.png">
                          |