・ 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.
Ask the user to enter a place name or address
Drop the marker on google map and display it on the detail page
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.
First, create a database. If you have already created it, add a column.
Column | Type | Options |
---|---|---|
title | string | null: false |
text | text | null: false |
Association
has_one :spot
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
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
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 under app / assets / javascripts and copy and paste the code linked below.
Edit application.js.
application.js
//= require underscore
//= require gmaps/google
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
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;"}
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.
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.
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