[RUBY] [Rails] google maps api How to post and display including map information

Introduction

・ Maps JavaScript API ・ Geocoding API

I implemented the process of posting and displaying a map including a map in the production of a personal application using the above API. I was quite addicted to referring to various articles, so I will summarize it.

Postscript [Rails] Google Maps API Description when latitude and longitude cannot be saved I was not able to get the latitude and mildness well, so if you have a similar person, please refer to this article as well.

Implementation details / image photo

  1. Ask the user to enter a place name or address

  2. Drop the marker on google map and display it on the detail page

At the time of posting

投稿.png

Details page

投稿表示.png

Google API You have to get the API when using googlemap. Please get the API KEY from the link below. Google Maps Platform I will omit the acquisition method this time.

In the app created this time ・ Maps JavaScript API ・ Geocoding API Will be used, so please enable it.

Database creation

First, create a database. If you have already created it, add a column.

post table

Column Type Options
title string null: false
text text null: false

Association

has_one :spot

spot table

Column Type Options
address string null: false
latitude float null: false
longitude float null: false
review_id references foreign_key: true, null: false

Association

belongs_to :post

gem installation

Gemfile


gem "gmaps4rails"
gem "geocoder"
gem "gon"
gem "dotenv-rails"

If you can describe it in Gemfile, please do bundle install.

From above ・ Gem "gmaps4rails" that makes it easy to create Google Maps ・ Gem "geocoder" that can convert place names to latitude and longitude -Gem "gon" that enables JS to use controller variables -Gem "dotenv-rails" to hide the GoogleMap API key

Introduced JS

Edit application.html.haml

ruby:application.html.haml


!!!
%html
  %head
   .
   .
   .
    = include_gon
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
  %body
    = yield
    %script{src: "https://maps.googleapis.com/maps/api/js?key=#{ENV["GOOGLE_MAP_KEY"]}&callback=initMap"}
    %script{src: "//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"}
    %script{src: "//cdn.rawgit.com/printercu/google-maps-utility-library-v3-read-only/master/infobox/src/infobox_packed.js", type:"text/javascript"}

Describe in% head so that gem "gon" can be used.

There is a description for using JS in% body. I think there is a way to write it in% head, but this time I wrote it in% body.

ENV ["GOOGLE_MAP_KEY"] contains the API KEY hidden in the .env file.

.env


GOOGLE_MAP_KEY = "Please describe the acquired API KEY"

Create an .env file to write the above.

Create underscore.js

Create underscore.js under app / assets / javascripts and copy and paste the code linked below.

underscore.js

Edit application.js

Edit application.js.

application.js


//= require underscore
//= require gmaps/google

Edit model

Next, edit each model as follows.

post.rb


class Post < ApplicationRecord
  has_one :spot, dependent: :destroy
  accepts_nested_attributes_for :spot
end

spot.rb


class Spot < ApplicationRecord
  belongs_to :post
  
  geocoded_by :address
  after_validation :geocode
end

edit view

Create a post page. Posting of googlemap, description of display.

Create a form to enter the name of an address or place.

ruby:new.html.haml


= form_with(model: @post, local: true, multipart: true) do |f|
  .spot
    = f.fields_for :spot do |s|
      = s.label :address, "Review location(Search on Google Map)", class: 'spot__title'
      = s.text_field :address, placeholder: "Enter a spot", id: "address", class: 'spot__text'
    %input{onclick: "codeAddress()", type: "button", value: "Search for"}
    .map{id: "map", style: "height: 320px; width: 640px;"}

Next, describe the google map part of the posted detail page.

ruby:show.html.haml


.show
  .show__address
    = @post.spot.address
  .show__maps{id: "show_map", style: "height: 320px; width: 400px;"}

Editing controller

Edit the controller.

post.controller


def new
  @post = Review.new
  @post.build_spot
end

def create
  @review = Review.new(review_params)
  if @post.save
    redirect_to root_path
  else
    redirect_to new_review_path
  end
end

def show
  @post = Review.find(params[:id])
  @lat = @review.spot.latitude
  @lng = @review.spot.longitude
  gon.lat = @lat
  gon.lng = @lng
end

private

def review_params
  params.require(:post).permit(:title, :text,spot_attributes: [:address])
end

Since it corresponds to has_one in the .build method of the new action @post.build_spot It is said.

Described in show action

@lat = @review.spot.latitude @lng = @review.spot.longitude gon.lat = @lat gon.lng = @lng

So, the @ lat and @ lng variables defined in the controller are assigned to gon.lat and gon.lng, respectively, so that they can be handled by JavaScript.

Creating JavaScript

Next, we will create a JavaScript file.

Create googlemap.js in asset / javascripts /.

googlemap.js


let map //Variable definition
let geocoder //Variable definition

function initMap(){ //Callback function
  geocoder = new google.maps.Geocoder() //Access GoogleMapsAPI Geocoding Service
  if(document.getElementById('map')){ //'map'Execute if you can get the id
    map = new google.maps.Map(document.getElementById('map'), { //'map'Get the id and display the map
      center: {lat: 35.6594666, lng: 139.7005536}, //The place to display first (this time, "Shibuya Scramble Crossing" is the initial value)
      zoom: 15, //Enlargement rate (can be set from 1 to 21)
    });
  }else{ //'map'If there is no id
    map = new google.maps.Map(document.getElementById('show_map'), { //'show_map'Get the id and display the map
      center: {lat: gon.lat, lng: gon.lng}, //Use the variables defined in controller as latitude / longitude values (values are in the DB)
      zoom: 15, //Enlargement rate (can be set from 1 to 21)
    });

    marker = new google.maps.Marker({ //Drop a marker on Google Map
      position:  {lat: gon.lat, lng: gon.lng}, //Decide where to drop the marker (values are in the DB)
      map: map //Specify the map to drop the marker
    });
  }
}

function codeAddress(){ //Callback function
  let inputAddress = document.getElementById('address').value; //'address'Get the id value (value)

  geocoder.geocode( { 'address': inputAddress}, function(results, status) { //Pass the address you want to geocode as an argument
    if (status == 'OK') {
      let lat = results[0].geometry.location.lat(); //Latitude of geocoded results
      let lng = results[0].geometry.location.lng(); //Longitude as a result of geocoding
      let mark = {
          lat: lat, //latitude
          lng: lng  //longitude
      };
      map.setCenter(results[0].geometry.location); //Latitude / longitude of the nearest place where you want to get a readable address
      let marker = new google.maps.Marker({
          map: map, //Specify the map to drop the marker
          position: results[0].geometry.location //Decide where to drop the marker
      });
    } else {
      alert('There was no corresponding result');
    }
  });   
}

For the above description, see https://qiita.com/kanato4/items/f2f3f7accd880224616a I was allowed to refer to.

At the end

That's it! I spent a considerable amount of time on this part alone when creating an application using the google API for the first time, so I hope it will be helpful for later scholars.

Recommended Posts

[Rails] google maps api How to post and display including map information
[Rails] How to display Google Map
How to display Map using Google Map API (Android)
Display Google Maps API with Rails and pin display
[Rails] How to display multiple markers on Google Map and display a balloon when clicked
[Rails] How to calculate latitude and longitude with high accuracy using Geocoding API and display it on Google Map
[Google Maps API] Map is not displayed and becomes blank [Rails]
Try to display google map and geospatial information authority map with python
[Rails 6 / Google Map API] Post an address and set multiple markers on the map
[Rails] How to get location information using Geolocation API
[For beginners] How to display maps and search boxes using the GoogleMap Javascript API
How to hide your Google Maps API key from HTML
Beginners of Google Maps API and Twitter API made "tweet map"
Introducing Google Map API with rails
How to display PDF resolution and detailed information on Linux (pdfinfo)
[Ruby on Rails] Display and pinning of GoolgeMAP using Google API
[Map display] Display a map from the address registered by the user using the Google Maps JavaScript API and Geocoding API!
[Rails] How to introduce Google Analytics [Easy]
[Rails] Google Maps API Description when latitude and longitude cannot be saved
[Rails] Displaying Google Maps using Google Maps API and searching routes between multiple points
How to use the Google Cloud Translation API
How to use Service Account OAuth and API with Google API Client for python
How to display videos inline in Google Colab
Book registration easily with Google Books API and Rails
[Python] How to create Correlation Matrix and Heat Map
How to analyze with Google Colaboratory using Kaggle API
How to post a ticket from the Shogun API
[Super easy! ] How to display the contents of dictionaries and lists including Japanese in Python
[Ruby on Rails] Multiple pins, balloons, and links on Google map
[Django] Google map display of GIS data and graphing of parameters
[Google Colab] How to interrupt learning and then resume it
Display the address entered using Rails gem'geocoder' on Google Map
Create a model to store information from the Google Books API for intuitive handling and testing
How to use Google Colaboratory
How to auto-update App Store description in Google Sheets and Fastlane
How to display formulas in latex when using sympy (> = 1.4) in Google Colaboratory
Get conversions and revenue with Google Analytics API and report to Slack
How to get followers and followers from python using the Mastodon API
How to use Google Colaboratory and usage example (PyTorch x DCGAN)
How to display bytes in the same way in Java and Python
[Rails 6] Embed Google Map in the app and add a marker to the entered address. [Confirmation of details]