1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails6】ポートフォリオへのGoogleMapの導入

Last updated at Posted at 2020-12-22

#はじめに

ポートフォリオ作成時によくWebサービスで見る、GoogleMapを導入してみたい!!と思い、実装したので、今回備忘録と復習のため記事を記述します。
内容は、表示ページに遷移すると、現在地の取得の有無が表示され、許可をすると、
現在地を表示することができ、検索フォームで検索したい場所を入力することで、その場所も表示できるような仕様です。

参考にさせていただいた記事は、【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
です!本当にありがとうございました。

#環境

Ruby on Rails '6.0.0'
Ruby '2.6.5'

#前提

  • Google Cloud PlatformにてAPIキーを取得済み。
    ※GeocodingAPIとMaps JavaScript APIを選択。
    ※APIキーの取得方法については今回は割愛します。
  • 私のポートフォリオでは、記事(articleテーブル)の詳細ページに表示するものとして記述していきます。

#viewファイルの編集

APIキーを取得することができたら、ほとんどviewファイルの編集で完了しました。。表示させたいhtml.erbに以下の記述をしました。

app/views/layouts/_map.html.erb
<div class="search-form">
  <input id="address" class="search-name" type="textbox" placeholder="現在地から近くの役所が検索できます">
  <input type="button" class="btn btn-outline-success" value="検索する" onclick="codeAddress()">
</div>

<div id='map'></div>

<style>
#map {
  height: 50vh;
  width: 60vw;
  margin: 0 auto;
}
</style>

<script>
  let map
  let geocoder

  function initMap(){
    geocoder = new google.maps.Geocoder()
    if(!navigator.geolocation) {
      alert('Geolocation APIに対応していません');
      return false;
    }

    navigator.geolocation.getCurrentPosition(function(position) {
      latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

      map = new google.maps.Map(document.getElementById('map'), {
        center: latLng,
        zoom: 12,
      });

      marker = new google.maps.Marker({
        position:  latLng,
        map: map
      });
    }, function() {
        alert('位置情報取得に失敗しました');
      });
  }

  function codeAddress(){
    let inputAddress = document.getElementById('address').value;

    geocoder.geocode( { 'address': inputAddress}, function(results, status) {
      if (status == 'OK') {
        map.setCenter(results[0].geometry.location);
        let marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
        });
      } else {
          alert('該当する結果がありませんでした:' + status);
      }
    });   
  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAP_SECRET_KEY'] %>&callback=initMap" async defer></script>

では、部分的に分けて解説していきます。

app/views/layouts/_map.html.erb
<div class="search-form">
  <input id="address" class="search-name" type="textbox" placeholder="現在地から近くの役所が検索できます">
  <input type="button" class="btn btn-outline-success" value="検索する" onclick="codeAddress()">
</div>

上段のこの部分でまず検索フォームを実装しています。ボタンなどはbootstrapを使用しています。

app/views/layouts/_map.html.erb
<style>
#map {
  height: 50vh;
  width: 60vw;
  margin: 0 auto;
}
</style>

こちらの部分では、地図の大きさや配置を決めています。

app/views/layouts/_map.html.erb
#↓現在地の取得処理
function initMap(){
    geocoder = new google.maps.Geocoder()
    if(!navigator.geolocation) {
      alert('Geolocation APIに対応していません');
      return false;
    }
#↑ユーザーの端末がGoogleMapに対応していなければ、地図は表示されないようにしています。
    navigator.geolocation.getCurrentPosition(function(position) {
      latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

      map = new google.maps.Map(document.getElementById('map'), {
        center: latLng,
        zoom: 12,
      });
#↑位置情報の取得ができれば、latLngに現在地の緯度と軽度の情報が定義され、マップに表示する処理を行なっています。
#「center: latLng」で現在地を地図の中央に表示し、「zoom: 12」は拡大の倍率になっています。

      marker = new google.maps.Marker({
        position:  latLng,
        map: map
      });
#↑現在地にマーカーを表示しています。
    }, function() {
        alert('位置情報取得に失敗しました');
      });
  }
#なんらかの形で取得に失敗した場合、alertで表示するようにしています。

上記はページを開いた初期表示の段階です。コメントアウトで処理内容について記述しています。

app/views/layouts/_map.html.erb
#検索ボタンをクリックすることで処理が走りだします。
  function codeAddress(){
    let inputAddress = document.getElementById('address').value;
#↑検索フォームに入力された位置を取得しています。
    geocoder.geocode( { 'address': inputAddress}, function(results, status) {
      if (status == 'OK') {
        map.setCenter(results[0].geometry.location);
        let marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
        });
#↑検索結果がヒットしたときに、検索結果の緯度と経度を地図に表示するとともに、マーカーを設置しています。
      } else {
          alert('該当する結果がありませんでした:' + status);
      }
    });   
  }
#↑検索結果が該当なしであれば上記を表示しています。

上記は検索結果を表示する際の処理になります。

app/views/layouts/_map.html.erb
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAP_SECRET_KEY'] %>&callback=initMap" async defer></script>

最後の行で、APIキーの取得を行なっています。
取得したキーは環境変数にて取扱を行なってください。

#おわりに

以上で実装は完了です。表示ページに遷移すると、位置情報の取得について有無が問われるため、許可をすると、現在地が表示されます。
今回は検索を行うと、自分の位置情報と、検索結果の該当する場所の2点にマーカーが刺さるような仕組みになっています。ここから、検索結果までの距離や時間の表示までできれば、なお使いやすいアプリケーションになるかと思いますので、勉強します。
相違点ありましたら、ご指摘ください。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?