【rails】Google map にて周辺施設の情報を取得・表示する  

備忘録です。

railsアプリ内で実装したのでAPIキーの管理部分がrubyの表記になっていますが、そこ以外はhtml javascriptなのでrails以外でも実装できるかと思います。

# この記事でできる事
- 現在地周辺の施設（カフェ、コンビニ、病院etc）を検索しピン留めする。
- 指定した地域の周辺施設の検索も可

以下イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874115/14eba299-410d-4691-78b5-89690007ac57.png)


# 前提

https://cloud.google.com/?hl=ja

上記Google Cloud Platformにて以下の３つのAPIの有効化と制限を行ったAPIキーを発行している。

- Maps JavaScript API
- Geocoding API
- Places API

APIの登録・制限・発行の方法は以下記事を参考にしてみてください。

https://www.zenrin-datacom.net/solution/gmapsapi/api_key

# 実装

```erb:search.html.erb
<input type="text" size="55" id="search" placeholder="地域と施設を指定" />
<input type="button" size="55" value="検索" onClick="SearchGo()" />
<div id="map_canvas"></div>


<style>
    #map_canvas{
        height: 600px;
        width: 600px;
    }
</style>
<script>
var myMap;
var service;

// マップの初期設定
function initMap() {
    if (navigator.geolocation) {
        // ユーザーの現在の位置情報を取得
        navigator.geolocation.getCurrentPosition(function(position) {
            var initPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            
            // 地図のプロパティを設定
            var myOptions = {
                zoom: 15,
                center: initPos,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            myMap = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

            // 検索の条件を指定（位置情報、半径、検索の分類）
            var request = {
                location: initPos,
                radius: 1000,
                type: ["hospital"] //初期値の施設は https://developers.google.com/maps/documentation/javascript/supported_types?hl=ja 参照
            };
            service = new google.maps.places.PlacesService(myMap);
            service.search(request, Result_Places);
        });
    }
}

// 検索結果を受け取る
function Result_Places(results, status){
    if(status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; i++) {
            var place = results[i];
            createMarker({
                 text: place.name,
                 position: place.geometry.location
            });
        }
    }
}

// 検索を行う
function SearchGo() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            var initPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            var myOptions = {
                center: initPos,
                zoom: 15,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            myMap = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
            service = new google.maps.places.PlacesService(myMap);
            var myword = document.getElementById("search").value;
            var request = {
                query: myword,
                radius: 5000,
                location: initPos
            };
            service.textSearch(request, result_search);
        });
    }
}

// 検索の結果を受け取る
function result_search(results, status) {
    var bounds = new google.maps.LatLngBounds();
    for(var i = 0; i < results.length; i++){
        createMarker({
             position: results[i].geometry.location,
             text: results[i].name,
             map: myMap
         });
        bounds.extend(results[i].geometry.location);
    }
    myMap.fitBounds(bounds);
}

// マーカーを作成
function createMarker(options) {
    options.map = myMap;
    var marker = new google.maps.Marker(options);
    var infoWnd = new google.maps.InfoWindow();
    infoWnd.setContent(options.text);
    google.maps.event.addListener(marker, 'click', function(){
        infoWnd.open(myMap, marker);
    });
    return marker;
}
</script>

<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAPS_API_KEY'] %>&libraries=places&callback=initMap" async defer></script>

```

- view一つで完結するので任意のviewファイルに記述してください。
- apiキーは`.env`ファイルにて`GOOGLE_MAPS_API_KEY`という環境変数に代入しています。
- `type: ["hospital"]`の所を任意の施設（下の記事参照）に変更することで起動時に表示するマーカーを変更できます。

:::note info
**具体的には以下のドキュメントを参考にしてください**
:::

https://developers.google.com/maps/documentation/javascript/supported_types?hl=ja


実装は以上です

# 参考記事

http://tokidoki-web.com/2015/11/googlemapsapi%E3%81%A7%E3%83%9E%E3%83%83%E3%83%97%E3%81%A7%E6%96%BD%E8%A8%AD%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%A6%E3%82%84%E3%82%93%E3%82%88/

https://qiita.com/kakeru0520sou1/items/9a39b3a122a8be5b9b65

https://developers.google.com/maps/documentation/javascript/supported_types?hl=ja