WebAPIでとったデータをGoogle Mapにのせる


とりあえず、Mapにのせるデータも全部WebAPIでとってみます。
（本当は、変動しないものはローカルに持ってきちゃうのがいいんですが）

![fusho-map.png](https://qiita-image-store.s3.amazonaws.com/0/50720/47b0f3f7-5fc9-16a2-2c52-79c66324f496.png "fusho-map.png")


# 流れ

1. 府省名をWebAPIからとってくる
2. 府省名から住所をとってくる
3. Google Mapの上に府省ごとにマーカーをのせる

# 使うもの

* IT Dashboard WebAPI

府省名のマスターがあるので、それを使います。
http://www.itdashboard.go.jp/DataFeeds/webapi#300

* Google Geocoding API

住所を取得するのに使います。
https://developers.google.com/maps/documentation/webservices/?hl=ja

* Google Map API

地図に使います。
https://developers.google.com/maps/?hl=ja

# 府省名をとってくる

`fusho_array`に、連想配列で`{府省名:緯度経度}`の形でデータを入れたいと思います。

まずは、緯度経度は空で府省名だけを入れます。
IT Dashboardの以下のページにサンプルコードもあるので、簡単です。

http://www.itdashboard.go.jp/DataFeeds/webapi#300

あまりよくないかもしれませんが、上記流れをシーケンシャルに実行したいため、`async: false`を入れて、同期処理にしています。

```js
function getFushoName() {
    $.ajax({
        url: "http://www.itdashboard.go.jp/PublicApi/getData.json",
        data: {
            dataset: "OrganizationMaster"
        },
        async: false
    }).done(function(data) {
        $.each(data.raw_data, function(i, item) {
            fusho_array[item.name] = "";
        });
    });
}
```

# 府省名から住所をとってくる

どうも、府省名によっては、住所が取れないものもあるようです。
そこで、分岐を入れて、とれなかったものはログに吐いています。

こちらも、上記流れをシーケンシャルに実行したいため、`async: false`を入れて、同期処理にしています。

```js
function getFushoAddress() {
    $.each(fusho_array, function(name, location) {
        var geocoding = "http://maps.googleapis.com/maps/api/geocode/json";
        $.ajax({
            url: geocoding,
            data: {
                address: name
            },
            async: false
        }).done(function(data) {
            if (data.results[0] === undefined) {
                console.log(name);
            } else {
                fusho_array[name] = data.results[0].geometry.location;
            }
        });
    });
}
```

# Google Mapの上に府省ごとにマーカーをのせる

idがmap-canvasの要素にGoogle Mapを表示します。
mapのオプション(mapOptions)の中心地点は、とりあえず、霞が関の緯度経度をハードコーディングしています。

`$.each`の中で、とってきた府省ごとにマーカーを設定しています。
基本的には、マーカーのオプションを設定して、マーカーをセットしているだけです。
クリックしたときに、府省名がでるように情報ウィンドウもセットしています。

```js
function handleLoadGoogleMap() {
    var mapOptions = {
        center: new google.maps.LatLng(35.673838, 139.750899),
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false,
        disableDefaultUI: true
    };
    mymap = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

    $.each(fusho_array, function(name, location) {
        var markerOpts = {
            position: new google.maps.LatLng(location.lat, location.lng),
            draggable: false,
            raiseOnDrag: false,
            map: mymap,
            labelContent: name,
            labelAnchor: new google.maps.Point(22, 0),
            labelClass: 'labels',
            labelStyle: {
                opacity: 1.0
            }
        };
        var marker = new google.maps.Marker(markerOpts);
        marker.setMap(mymap);

        var iw = new google.maps.InfoWindow({
            content: name,
            position: new google.maps.LatLng(location.lat, location.lng)
        });

        google.maps.event.addListener(marker, "click", function(e) {
            iw.open(mymap, this);
        });
    });
}
```

# 完成品

```
<!DOCTYPE html>
<html lang='ja'>

<head>
    <meta charset='utf-8'>
    <title>府省map</title>

    <script type='text/javascript' src='https://maps.googleapis.com/maps/api/js?sensor=false'>
    </script>
    <script src='js/d3.min.js'></script>
    <script src='js/markerwithlabel_packed.js'></script>
    <style>
    #map-canvas {
        width: 100%;
        height: 400px;
    }
    .labels {
        color: black;
        background-color: white;
        font-family:'Lucida Grande', 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', Meiryo, メイリオ, sans-serif;
        font-size: 10px;
        text-align: center;
        border: 1px solid black;
        white-space: nowrap;
    }
    </style>
</head>

<body>
    <h1>府省マップ</h1>
    <div id='map-canvas'></div>

    <script src='js/jquery-2.1.1.min.js'></script>
    <script type="text/javascript">
    var mymap;
    var fusho_array = {};
    google.maps.event.addDomListener(window, 'load', draw);

    function draw() {
        getFushoName();
        getFushoAddress();
        handleLoadGoogleMap();
    }

    function getFushoName() {
        $.ajax({
            url: "http://www.itdashboard.go.jp/PublicApi/getData.json",
            data: {
                dataset: "OrganizationMaster"
            },
            async: false
        }).done(function(data) {
            $.each(data.raw_data, function(i, item) {
                fusho_array[item.name] = "";
            });
        });
    }

    function getFushoAddress() {
        $.each(fusho_array, function(name, location) {
            var geocoding = "http://maps.googleapis.com/maps/api/geocode/json";
            $.ajax({
                url: geocoding,
                data: {
                    address: name
                },
                async: false
            }).done(function(data) {
                if (data.results[0] === undefined) {
                    console.log(name);
                } else {
                    fusho_array[name] = data.results[0].geometry.location;
                }
            });
        });
    }

function handleLoadGoogleMap() {
    var mapOptions = {
        center: new google.maps.LatLng(35.673838, 139.750899),
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false,
        disableDefaultUI: true
    };
    mymap = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

    $.each(fusho_array, function(name, location) {
        var markerOpts = {
            position: new google.maps.LatLng(location.lat, location.lng),
            draggable: false,
            raiseOnDrag: false,
            map: mymap,
            labelContent: name,
            labelAnchor: new google.maps.Point(22, 0),
            labelClass: 'labels',
            labelStyle: {
                opacity: 1.0
            }
        };
        var marker = new google.maps.Marker(markerOpts);
        marker.setMap(mymap);

        var iw = new google.maps.InfoWindow({
            content: name,
            position: new google.maps.LatLng(location.lat, location.lng)
        });

        google.maps.event.addListener(marker, "click", function(e) {
            iw.open(mymap, this);
        });
    });
}
    </script>
</body>

</html>
```