Geocoding, Places and Maps

#84 Geocoding, Places and Maps
6/11/2017

Summary

Using the Geocoder gem and Google APIs, learn how to add some geolocation functionality to your application.
7
rails javascript api maps 11:29 min

Resources

Geocoder Site - http://www.rubygeocoder.com/
Geocoder Github - https://github.com/alexreisner/geocoder
Google Developer Console - https://console.developers.google.com
Source - https://github.com/driftingruby/084-geocoding-places-and-maps

Forgot to mention in the video that there is a collection on the places resource in the routes. This is part of the request to get the list of nearby places.

routes.rbRails.application.routes.draw do
  resources :places do
    collection do
      put :get_locations
    end
  end
  root 'places#index'
end



Summary

Gemfilegem 'geocoder'

Add Latitude and Longitude floats to your model.

Terminal# rails g scaffold places name address latitude:float longitude:float
- or -
# rails g migration add_coordinates_to_places latitude:float longitude:float

# rails db:migrate
place.rbclass Place < ApplicationRecord
  geocoded_by :address
  after_validation :geocode, if: :address_changed?
end
rails consolePlace.near("Big Ben")
Place.first.nearbys
place = Place.first
place.distance_to("Eiffel Tower")
place.distance_to(Place.second)

Generate Geocoder Config

Terminalrails generate geocoder:config
index.html.erb  <%= content_tag :tbody, id: :places do %>
    <%= render @places %>
  <% end %>

  ...

<%= content_tag :button, 'Get Places', class: 'btn btn-info get_location' %>
<%= tag :div, class: 'location_results_list' %>
get_places.coffee@getPlaces = ->
  failure = ->
    alert 'problem getting location' 
  $('.get_location').each (index) ->
    $(this).on 'click', (event) ->
      if navigator.geolocation
        navigator.geolocation.getCurrentPosition ((position) ->
          $.ajax
            type: 'PUT'
            url: '/places/get_locations' + '?latitude=' + position.coords.latitude + '&longitude=' + position.coords.longitude
        ), failure,
          enableHighAccuracy: true
          timeout: 5000
      event.preventDefault()

$(document).on('turbolinks:load', @getPlaces)

@createPlace = ->
  $('.location_results_list button').on 'click', (event) ->
    data = JSON.parse(JSON.stringify($(this).data('attributes')))
    $.ajax '/places', 
      type: 'POST'
      dataType: 'script'
      data: {
        place: {
          name: data['name']
          address: data['vicinity']
          latitude: data['geometry']['location']['lat']
          longitude: data['geometry']['location']['lng']
        }
      }
      success: (data, status) ->
        # console.log 'Data: ' + data + '\nStatus: ' + status

    event.preventDefault()
places_controller.rb  def get_locations
    url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=#{params[:latitude]},#{params[:longitude]}&radius=500&key=#{Rails.application.secrets.google_places_key}"
    http_call = open(url).read
    response = JSON.parse(http_call, {:symbolize_names => true})
    @locations = response[:results]
  end
routes.rbRails.application.routes.draw do
  resources :places do
    collection do
      put :get_locations
    end
  end
  root 'places#index'
end
get_locations.js.erb<% @locations.each do |loc| %>
  $('.location_results_list').append('<li><button data-attributes="<%= j loc.to_json.to_s %>"><%= loc[:name] %></button></li>');
<% end %>
createPlace();
create.js.erb$('#places').append('<%= j render @place %>');
show.html.erb<%= image_tag "http://maps.google.com/maps/api/staticmap?size=450x300&sensor=false&zoom=16&markers=#{@place.latitude}%2C#{@place.longitude}" %>


672989?v=3&s=64
sadiqmmm said 2 months ago:

Thanks a lot :)

00000000000000000000000000000000?d=mm&f=y&s=64
Nickiam said 2 months ago:

This was great, thanks for making this Dave!

I'm definitely interested in seeing more videos involving maps and Geocoding!

Photo
Rubén Ibáñez Carmona said 2 months ago:

Hi Dave,


Thanks for this episode, I'm a huge fan of your way of coding rails.

I was wondering if geocoder could also be used for the classical autocompletion forms with addresses (you select the country, then it gives you the states for that country, then the regions for the selected state and finally the cities).

It looks like a very common task, but I havent seen any gem specific for that (city-state looks very uncompleted and non-flexible).

Thanks a lot,


Rubén

Login to Comment