Nhúng google map vào ứng dụng rails với gem Geocoder
This post hasn't been updated for 7 years
Hôm nay mình sẽ chuyển qua Rails và trình bày một cách đơn giản để sử dụng bản đồ trong ứng dụng rails với gem Geocoder. Về google map api mọi người có thể tham khảo bài viết Google map API .
Get Google API key
Để sử dụng được Google Maps API, chúng ta cần phải đăng ký app project trên Google API Console
và get API key để dùng.
Mọi người có thể get key đơn giản bằng cách click vào nút get a key
qua link sau:
Quick start to get API key
hoặc có thể đăng ký và quản lý key cho project qua Googel API Console
Sau khi get key xong chúng ta cần thêm đoạn script để dùng API của Google như sau:
<script src="//maps.google.com/maps/api/js?v=3.27&key=AIzaSyDEHpTjzc2CyFPY_m-_QCBWDI25w2pbnYM"></script>
Note: ở đây mình chỉ định luôn là Google map api version 3.27. đoạn script này chúng ta có thể thêm ngay trong phần view
cần dùng.
Geocoder
Ok vậy là bước chuẩn bị key đã xong. Trước hết mình sẽ giới thiệu qua gem geocoder
và tại sao mình dùng nó mà không phải 1 gem khác như gmaps4rails
.
Trước hết Geocoder
là một giải pháp mã hóa địa lý trong Ruby. Nó có một vài tính năng cụ thể như sau:
- Chuyển đổi địa điểm thành tọa độ địa lý và ngược lại
- Tìm địa điểm gần vị trí cho trước
- Chuyển đổi địa chỉ IP thành vị trí
Trước đó khi chuẩn bị làm task này mình nghĩ đến gem gmaps4rails
nhưng rồi đọc tìm hiểu thì thấy cần thêm cả thư viện js ngoài như underscore
để custom map hay việc tạo và generate JSON để tạo map khá phức tạp. Trong khi cái mình thực sự cần là latitude (vĩ độ)
và longitude (kinh độ)
. Rồi tìm hiểu thì mình thấy geocoder
làm đơn giản và khá mạnh nếu mình khai thác thêm như mấy chức năng cơ bản mình nêu trên. À ngồi vọc còn thấy ngoài author chính là Alexreisner thì còn có chị Phạm Thu Trang là contributor (xếp thứ 2 và có quyền merge pull request ).
Instruction
- Database Migration
Mình xin bỏ qua bước cài đặt gem. Chúng ta thêm 2 trường
latitude
vàlongitude
vào trong bảng mà chúng ta dùng để lưu vị trí. Cụ thể ở đây mình lưu ở bảngAddress
. Note: lưu ý chính tả nhé. khi tạo database migration team-mate mình thuận miệng và tạo là.longtitude
- Modify model:
Migrate xong thì chúng ta thêm đôi dòng như sau:
ở đây mình sẽ dựa vào trườnggeocoded_by :address after_validation :geocode, if: :address_changed?
address
để lấy vĩ độ và kinh độ cho địa điểm. vàafter_validation
là để generate lại kinh độ và vĩ độ khiaddress
thay đổi. Cũng không quá khó hiểu lắm - Generate latitude and longitude
Cái này cũng khá giống với việc re-index trong
elasticsearch
đó là chúng ta chạy lệnh để generate vĩ độ và kinh độ cho địa chỉ có sẵn trong database:rake geocode:all CLASS=Address SLEEP=0.25 BATCH=100
- Get location
Mọi việc gần như xong rồi. giờ thì chúng ta sẽ dựa vào kinh độ và vĩ độ để tạo map trên project của chúng ta.
Đầu tiên là trong controller chúng ta sẽ trả về
json
để dựa vào đó chúng ta vẽ bản đồ tương ứng cho từng địa điểm. Cụ thể ở bài viết này mình sẽ vẽ địa điểm của 1 công ty nào đó, vì vậy trong actionshow
ởCompaniesController
mình trả về như sau:
Vậy là xong việc việc trả về dữ liệu. chúng ta chuyển quadef show if request.xhr? render json: { addresses: @company.addresses } end end
view
. Đơn giản chỉ tạo 1 div chứa map và style cho nó:
Hoàn tất công việc bằng cách viết Javascript để xử lý dữ liệu trả về và tạo bản đồ tương ứng:<div id="map" class="map"></div>
Ở file javascript trên mình chia thành 2 function là$(function() { getLocation.initialize(); }); var getLocation = { initialize: function() { getLocation.fetch_data(); }, fetch_data: function() { var url_path = window.location.pathname; $.get(url_path, function(data) { var addresses = data['addresses']; const latitude = addresses[0].latitude; const longitude = addresses[0].longitude; getLocation.draw_map(latitude, longitude); }, 'json'); }, draw_map: function(lat, lng) { var companyLatlng = new google.maps.LatLng(lat, lng); var mapOptions = { zoom: 15, center: companyLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('map'), mapOptions); var marker = new google.maps.Marker({ position: companyLatlng, map: map }); } }
fetch_data
để lấy dữ liệu trả về vàdraw_map
để tạo bản đồ. Về phầndraw_map
thì mình chỉ custom thêm cái marker thôi. Cũng không có gì là khó hiểu nhỉ.
Conclusion
Mình đã nói qua về các tính cơ bản của Geocoder và nó còn khá nhiều tính năng thú vị nữa nên mọi người có thể tìm hiểu thêm qua Geocoder. Happy coding !
All Rights Reserved