2
1

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.

Google mapを使って住所検索できるようにした

Last updated at Posted at 2021-10-18

Google map apiを使って住所を検索して表示できるようにした

Google map apiの利用

こちらの記事を参考にしました。
Google Maps API を使ってみた
"Maps JavaScript API”を利用してGoogle Mapをページに埋め込む方法

  • googleアカウントを作成
  • Google Cloud Pratformにアクセスし、プロジェクトを作成
  • Map JavaScript APIを有効化し、APIキーを取得

### 試してみる

html
<!DOCTYPE html>
<html lang="ja">

<head>
<meta charset="UTF-8">
<title>Sample_GoogleMap</title>

<script src="http://maps.google.com/maps/api/js?key=YOUR_KEY&language=ja"></script>

<style>
html { height: 100% }
body { height: 100% }
#map { height: 100%; width: 100%}
</style>
</head>

<body>
<div id="map"></div>

<script>
var MyLatLng = new google.maps.LatLng(35.6811673, 139.7670516);
var Options = {
 zoom: 15,      //地図の縮尺値
 center: MyLatLng,    //地図の中心座標
 mapTypeId: 'roadmap'   //地図の種類
};
var map = new google.maps.Map(document.getElementById('map'), Options);
</script>

</body>
</html>

API_Keyを環境変数にする

Gemfile
gem 'dotenv-rails'
ターミナル
bundle install

.envファイルを手動で作成する

.env
GoogleMap_API_Key = YOUR_Key
.gitignore
/.env

showページに合わせて動的に地図を変更する

  • Geocording APIを有効化する

View

institution_map.html.erb
〜略〜
    <div class="institution_show_address_container">
      <div class="institution_show_address_label show_label">住所</div>
      <%#- 表示元の住所 -%>
      <div class="institution_show_address_text show_text", id="institution_mapping_address"><%= institution.address %></div>
    </div>
〜略〜

<div class="map_container">
  <%# マップを表示する場所 %>
  <div id='institution_map'></div>
</div>

<script>
let map
let geocoder

<%# ページ呼出し時の処理 %>
function initMap(){
  geocoder = new google.maps.Geocoder()
  <%# 表示住所を取得 %>
  let putAddress = document.getElementById('institution_mapping_address').textContent;
  geocoder.geocode( { 'address': putAddress}, function(results, status) {
    if (status == 'OK') {
      <%# 表示場所にマップを表示 %>
      map = new google.maps.Map(document.getElementById('institution_map'), {
      zoom: 17,
      });
      map.setCenter(results[0].geometry.location);
      <%# マップにマーカーを表示 %>
      var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
      });
    } else {
      alert('該当する結果がありませんでした:' + status);
    }
  });
}

</script>
<%# ページを表示するときにinitMapを動作させる %>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GoogleMap_API_KEY'] %>&callback=initMap" async defer></script>

住所を検索して地図を表示できるようにする

search_address.html.erb
<div class="search_map_container">
  <h2>医療機関を検索</h2>
  <%# 検索したい住所や場所を入力するテキストボックス %>
  <input id="search_address" type="textbox" value="GeekSalon">
  <%# 処理を行うボタン %>
  <input id="search_address_button", type="button" value="検索" onclick="codeAddress()">
  <div>
    <%# 住所を表示する %>
    <div id="result_address">住所が表示されます</div>
  </div>
  <%# 地図を表示する %>
  <div id='search_map'></div>
</div>

<script>
let map
let geocoder

<%# 初期化処理 %>
function initMap(){
  geocoder = new google.maps.Geocoder()
  
  <%# 参考にする住所がないので初期設定を行う。 lat:緯度、lng:経度。サンプルは東京駅 %>
  map = new google.maps.Map(document.getElementById('search_map'), {
    center: {lat: 35.6809591, lng: 139.7673068},
    zoom: 15,
  });
  <%# マーカーを配置 %>
  marker = new google.maps.Marker({
    position:  {lat: 35.6809591, lng: 139.7673068},
    map: map
  });
}
<%# ボタンを押した時の処理 %>
function codeAddress(){
  <%# 検索したいアドレスを取得 %>
  let inputAddress = document.getElementById('search_address').value;
  
  geocoder.geocode( { 'address': inputAddress}, function(results, status) {
    if (status == 'OK') {
      <%# マップを表示
      map.setCenter(results[0].geometry.location);
      <%# 検索で得られた住所を取得 %>
      result_address = results[0].formatted_address;
      <%# 取得した住所を表示 %>
      document.getElementById('result_address').textContent = result_address
      <%# マーカーを表示 %>
      var 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['GoogleMap_API_KEY'] %>&callback=initMap" async defer></script>

周辺の施設を表示する

place_map.html.erb
<%# 初期住所 %>
<div class="place_medicalstaff_address"></div>
<%# 地図表示部分 %>
<div class="place_map_container">
  <h2>周辺の医療機関検索</h2>
  <div class="place_map_search_area">
    <%# 検索したい住所を入力 %>
    <input type="text" size="55" id="place_search">
    <%# 処理するボタン %>
    <input type="button" size="55" value="検索" id="place_search_button" onClick="SearchGo()">
  </div>
  <div id="place_map style="width: 300px; height: 300px;">"></div>
</div>

<%# 先にapiへアクセスしないと、googleメソッドがエラーになる %>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GoogleMap_API_KEY'] %>&libraries=places"></script>


<script>
var myMap;
var service;

<%# 初期処理 %>
function initialize() {
  geocoder = new google.maps.Geocoder()
<%# 初期住所の場所を取得する %>
  let defaultAddress = document.getElementById('place_medicalstaff_address').textContent;
  geocoder.geocode( { 'address': defaultAddress}, function(results, status) {
    if (status == 'OK') {
<%# 取得した住所情報からmapを表示 %>
      let lat = results[0].geometry.location.lat();
      let lng = results[0].geometry.location.lng();
      var initPos = new google.maps.LatLng(lat, lng);
<%# オプション(MapOptionクラス)で地図のプロパティを設定(倍率、マーカー表示位置、地図の種類) %>
      var myOptions = {
          zoom: 15,
          center: initPos,
      };
      myMap = new google.maps.Map(document.getElementById("place_map"), myOptions);
<%# 検索の条件を指定(緯度経度、半径、検索の分類) %>
      var request = {
      location: initPos,
      radius: 1000,             <%# ※1 表示する半径領域を設定(1 = 1M) %>
      types: ['hospital']       <%# ※2 typesプロパティの施設タイプを設定 %>
      };
<%# placeAPIを使用して周辺情報を取得する %>
      var service = new google.maps.places.PlacesService(myMap);
      service.search(request, Result_Places);
    } else {
      alert('該当する結果がありませんでした:' + status);
    }
  });
}

<%# 検索結果を受け取る %>
function Result_Places(results, status){
<%# Placesが検索に成功したかとマうかをチェック %>
    if(status == google.maps.places.PlacesServiceStatus.OK) {
<%# 検索結果の数だけ反復処理を変数placeに格納 %>
        for (var i = 0; i < results.length; i++) {
            var place = results[i];
<%# 定義したcreateMarker関数で、取得したplaceにマーカーを表示 %>
            createMarker({
              text : place.name,
              position : place.geometry.location
            });
        }
    }
}

<%# 検索フォームから検索したとき %>
function SearchGo() {
  geocoder = new google.maps.Geocoder()
  <%# 検索したい住所を受け取る %>
  let defaultAddress = document.getElementById('place_search').value;
  geocoder.geocode( { 'address': defaultAddress}, function(results, status) {
    if (status == 'OK') {
      let lat = results[0].geometry.location.lat();
      let lng = results[0].geometry.location.lng();
      var initPos = new google.maps.LatLng(lat, lng);
      var myOptions = {
          center : initPos,
          zoom: 15
      };
      myMap = new google.maps.Map(document.getElementById("place_map"), myOptions);
      var request = {
        location: initPos,
        radius: 1000,
        types: ['hospital']
      };
      var service = new google.maps.places.PlacesService(myMap);
      service.search(request, Result_Places);
    } else {
      alert('該当する結果がありませんでした:' + status);
    }
  });
}

<%# 検索フォームで検索した場合の、map検索結果を受け取る %>
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);
    }
<%# Map.fitBounds()で、マーカーの場所を全て表示するように地図のビューポート(位置座標とズーム値)を変更 %>
    myMap.fitBounds(bounds);
}

<%# 該当する位置にマーカーを表示 %>
function createMarker(options) {
<%# マップ情報を保持しているmyMapオブジェクトを指定 %>
    options.map = myMap;
<%# Markcrクラスのオブジェクトmarkerを作成 %>
    var marker = new google.maps.Marker(options);
<%# 各施設の吹き出し(情報ウインドウ)に表示させる処理 %>
    var infoWnd = new google.maps.InfoWindow();
    infoWnd.setContent(options.text);
<%# addListenerメソッドを使ってイベントリスナーを登録 %>
    google.maps.event.addListener(marker, 'click', function(){
        infoWnd.open(myMap, marker);
    });
    return marker;
}

<%# ページ読み込み完了後、Googleマップを表示 %>
google.maps.event.addDomListener(window, 'load', initialize);
</script>

Turbolinks

viewにscriptを記述する場合は、Turbolinksを切る方がいいらしい。

views/layouts/application.html.erb
<%= link_to "home", root_path, "data-turbolinks": false %>

全部切る場合は、app/javascript/application.jsGemfileなどから、Turbolinksを削除すればOK(非推奨)

参考記事

Google Maps API の使い方・利用方法
【Google MAP】名称から場所を検索・特定する
Google Maps APIで住所から緯度経度を求める
【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
GoogleMapsAPIでマップで施設検索してやんよ!!!
Google API 第8回
SYNCER (Google Maps API)
Rails Turbolinksをページ毎に無効化する方法

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?