[RUBY] [Rails] How to calculate latitude and longitude with high accuracy using Geocoding API and display it on Google Map

Target

** Display the address registered by the user in the center of the map and set a marker. ** ** ezgif.com-video-to-gif (1).gif

Development environment

・ Ruby: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ OS: macOS Catalina

Premise

The following has been implemented.

Slim introduction -Login function implementationGoogle Map display

Since the accuracy is low only with gem'geocoder' (there are areas where the address cannot be specified), We will implement it so that the latitude and longitude can be specified from the address with high accuracy using the Geocoding API.

Enable Geocoding API

1. Access the link below

Google Cloud Platform

2. Click "Go to API Overview"

スクリーンショット 2020-06-03 10.01.36.png

3. Click "Library"

スクリーンショット 2020-06-03 10.01.41.png

4. Enter "geo" in the search form and click "Geocoding API"

スクリーンショット 2020-06-03 10.02.08.png

5. Click "Enable"

スクリーンショット 2020-06-03 10.02.13.png

6. Click the part surrounded by the red frame

スクリーンショット 2020-06-03 10.02.31.png

7. A pull-down menu will be displayed. Click "All Google Maps API".

スクリーンショット 2020-06-03 10.04.02.png

8. Click "Credentials"

スクリーンショット 2020-06-03 10.12.39.png

9. Click "API Key Name"

スクリーンショット 2020-06-03 10.12.46.png

10. Set the authentication information

** ① API restrictions ** Select Restrict Keys and select Geocoding API from the pull-down menu.

** ② Make sure that Maps JavaScript API and Geocoding API are selected, and click Save **

スクリーンショット 2020-06-03 10.13.14.png

11. Check if there are two APIs

The API key will not be changed by adding the API, so this is the end.

スクリーンショット 2020-06-03 10.13.25.png

Implementation

1. Introduce Gem

Gemfile


gem 'gon'
gem 'geocoder'

gem 'gon' ➡︎ Make the instance variables defined in the controller available in the view JavaScript.

gem 'geocoder' ➡︎ Calculate latitude and longitude from the address.

Terminal


$ bundle

2. Create and edit the geocorder configuration file

Terminal


$ touch config/initializers/geocoder.rb

geocoder.rb


#Postscript
Geocoder.configure(
  lookup: :google,
  api_key: ENV['GOOGLE_MAP_API']
)

Now you can use the Geocoding API to calculate latitude and longitude with high accuracy.

3. Add column

Terminal


$ rails g migration AddColumnsToUsers address:string latitude:float longitude:float

add_columns_to_users.rb


class AddColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :address, :string
    add_column :users, :latitude, :float
    add_column :users, :longitude, :float
  end
end

Terminal


$ rails db:migrate

4. Edit the model

user.rb


  #Postscript
  geocoded_by :address
  after_validation :geocode

geocoded_by :address ➡︎ Calculate latitude and longitude based on the address column.

after_validation :geocode ➡︎ When changing the address, change the latitude and longitude.

5. Edit controller

** ① Edit ʻapplication_controller.rb` **

Add "address" to the strong parameter.

application_controller.rb


def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :address])
end

** ② ʻEdit users_controller.rb` **

users_controller.rb


def show
  @user = User.find(params[:id])
  gon.user = @user #Postscript
end

6. Edit the view

** ① Edit ʻapplication.html.slim` **

Load gon. Please note that it is loaded before CSS and JavaScript.

slim:application.html.slim


doctype html
html
  head
    title
      | Bookers2
    = csrf_meta_tags
    = csp_meta_tag
    = include_gon #Postscript
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'

** ② Added address input form to new member registration screen **

slim:resistrations/new.html.slim


= f.label :address, 'Street address'
br
= f.text_field :address, class: 'form-control'
br

** ③ Edit the map **

slim:users/show.html.erb


#map style='height: 500px; width: 500px;'

- google_api = "https://maps.googleapis.com/maps/api/js?key=#{ ENV['GOOGLE_MAP_API'] }&callback=initMap".html_safe
script{ async src=google_api }

javascript:

  let map;

  function initMap() {
    geocoder = new google.maps.Geocoder()

    map = new google.maps.Map(document.getElementById('map'), {
      //Call latitude and longitude from variables defined in the controller and display them in the center of the map
      center: {
        lat: gon.user.latitude,
        lng: gon.user.longitude
      },
      zoom: 12,
    });

    marker = new google.maps.Marker({
      //Call latitude and longitude from variables defined in the controller and set markers
      position: {
        lat: gon.user.latitude,
        lng: gon.user.longitude
      },
      map: map
    });
  }

Caution

If you do not disable turbolinks, the map will not switch, so be sure to disable it.

How to disable turbolinks

Recommended Posts

[Rails] How to calculate latitude and longitude with high accuracy using Geocoding API and display it on Google Map
How to display Map using Google Map API (Android)
[Rails] google maps api How to post and display including map information
[Rails] How to display Google Map
[Rails] How to display multiple markers on Google Map and display a balloon when clicked
[Ruby on Rails] Display and pinning of GoolgeMAP using Google API
Display Google Maps API with Rails and pin display
How to analyze with Google Colaboratory using Kaggle API
Display the address entered using Rails gem'geocoder' on Google Map
Introducing Google Map API with rails
Try to display google map and geospatial information authority map with python
[Map display] Display a map from the address registered by the user using the Google Maps JavaScript API and Geocoding API!
[Rails] Google Maps API Description when latitude and longitude cannot be saved
[Rails 6 / Google Map API] Post an address and set multiple markers on the map
How to use Service Account OAuth and API with Google API Client for python
[For beginners] How to display maps and search boxes using the GoogleMap Javascript API
[Rails] How to get location information using Geolocation API
Book registration easily with Google Books API and Rails
YOLP: Extract latitude and longitude with Yahoo! Geocoder API.
How to get the current weather data and display it on the GUI while updating it automatically
[Ruby on Rails] Multiple pins, balloons, and links on Google map
[Google Colab] How to interrupt learning and then resume it
[Ev3dev] How to display bmp image on LCD with python
How to return the data contained in django model in json format and map it on leaflet
How to install OpenCV on Cloud9 and run it in Python
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
Linking Python and Arduino to display IME On / Off with LED
How to run Jupyter and Spark on Mac with minimal settings
How to install pandas on EC2 (How to deal with MemoryError and PermissionError)
How to display PDF resolution and detailed information on Linux (pdfinfo)
Take an image with Pepper and display it on your tablet
Download Google logo → Convert to text with OCR → Display on HTML
[Google Maps API] Map is not displayed and becomes blank [Rails]
I made a music bot using discord.py and Google Drive API (tested with Docker → deployed to Heroku)
For the time being using FastAPI, I want to display how to use API like that on swagger