SlideShare a Scribd company logo
1 of 24
Download to read offline
Intégration de GoogleMaps
dans une Application Rails 2.0
               Sébastien Gruhier
                    Xilinus
        Railscamp - Paris - 17 mai 2008
GoogleMaps
              http://code.google.com/apis/maps/
• Affichage géolocalisé d’information (point, forme vectorielle,
  trafic ...)
• Librairie Javascript
• Gratuit sous certaines conditions
• Nécessite une API key
Plugin GeoKit
              http://geokit.rubyforge.org/
• Ajout de finder geolocalisé à ActiveRecord
• MultiProvider (GoogleMap, YahooMaps...)
• Calcul de distance
• IP localisation via hostip.info
• ...
Application de demo

• Application Rails 2.0
• Visualisation des utilisateurs sur une googlemap
• Plugin restful_authenticated + geokit
Initialisation

• Assez parlé, codons un exemple
   rails gmaps_demo -d mysql; cd gmaps_demo


• plugin geokit
   ./script/plugin install svn://rubyforge.org/var/svn/geokit/trunk
   git module add git://github.com/ptb/geokit.git vendor/plugins/geokit


• plugin restful_authentication
   ./script/plugin install http://svn.techno-weenie.net/projects/plugins/
   restful_authentication
   git submodule add git://github.com/technoweenie/restful-authentication.git
   vendor/plugins/restful_authentication


• GIT:   git submodule init
GeoKit
                   Test
 ./script/console
Loading development environment (Rails 2.0.2)
include GeoKit::Geocoders
>> include GeoKit::Geocoders
=> Object
>> home = MultiGeocoder.geocode(quot;151 rue montmartre, parisquot;)
=> #<GeoKit::GeoLoc:0x27769b8 @country_code=quot;FRquot;, @lat=48.870519,
@street_address=quot;151, Rue Montmartrequot;, @full_address=quot;151, Rue Montmartre, 75002
2ème Arrondissement Paris, Paris, Francequot;, @precision=quot;addressquot;, @zip=quot;75002quot;,
@state=quot;Ile-de-Francequot;, @success=true, @provider=quot;googlequot;, @lng=2.342718,
@city=quot;Parisquot;>




Calcul “in memory”
>>   home = MultiGeocoder.geocode(quot;151 rue montmartre, parisquot;)
>>   rennes = MultiGeocoder.geocode(quot;rennes, francequot;)
>>   home.distance_to(rennes, :units => :kms)
=>   308.473068506021
Initialisation

• Editer database.yml si nécessaire
    rake db:create


• Génération de l’authentification (sans activation ni stateful)
    ./script/generate authenticated user sessions
    rake db:migrate
    rake db:fixtures:load
Initialisation

• Supprimer public/index.html
• Ajouter un layout simple
  <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
  <!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.1//ENquot;
  	   quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtdquot;>

  <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot;>
    <head>
      <meta http-equiv=quot;content-typequot; content=quot;text/html;charset=UTF-8quot; />
      <title>Google Maps Demo</title>
    </head>
    <body>
      <%= yield %>
    </body>
  </html>
Initialisation

• Ajouter une vue users/index.html.erb
    User List
    <table border=quot;0quot; cellspacing=quot;5quot; cellpadding=quot;5quot;>
      <tr>
        <th>Login</th>
        <th>Email</th>
        <th>Created At</th>
      </tr>
      <%= render :partial => quot;userquot;, :collection => @users %>
    </table>
    <br/>
    <%= link_to 'Add a new user', new_user_path %>




• Avec un partial users/_user.html.erb
    <tr>
      <td><%= user.login %></td>
      <td><%= user.email %></td>
      <td><%= user.created_at.to_s :short %></td>
    </tr>
Initialisation fin!

• On ajoute une route par défaut
   map.root :controller => 'users'


• Déplacer le code de environment.rb dans
   config/initializers/geokit.rb                 avec une
   clé google valide
• Et on peut enfin s’amuser avec GoogleMaps :)
Géolocalisation

     • Ajouter des attributs au model User
         ./script/generate migration add_geolocalisation_to_users

class AddGeolocalisationToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :address, :string
    add_column :users, :lat, :decimal,    :precision => 15, :scale => 10
    add_column :users, :lng, :decimal,    :precision => 15, :scale => 10
  end

  def self.down
    remove_column :users, :address
    remove_column :users, :lat
     •
    remove_column :users, :lng
  end
end
Géolocalisation

       • Mettre la jour les deux fixtures
                 à
         Utilise console !!
./script/console
Loading development environment (Rails 2.0.2)
>> MultiGeocoder.geocode(quot;10 rue de la republique, paris, francequot;)

=> #<GeoKit::GeoLoc:0x1102bdc @country_code=quot;FRquot;, @lat=48.866816,

       •
@street_address=quot;10, Avenue De La Républiquequot;, @full_address=quot;10, Avenue de la
République, 75011 11ème Arrondissement Paris, Paris, Francequot;, @precision=quot;addressquot;,
@zip=quot;75011quot;, @state=quot;Ile-de-Francequot;, @success=true, @provider=quot;googlequot;,
@lng=2.366405, @city=quot;Parisquot;>
Géolocalisation

 • Ajouter au modèle User
attr_accessible ..., :address

acts_as_mappable :auto_geocode => true
before_validation_on_update :auto_geocode_address




 • Ajouter edit/update + adresse à un user (dans la vue)
GoogleMap

 • Ajouter une route users/map
map.resources :users, :collection   => {:map => :get}



 • Une action, un layout fullscreen: map.html.erb
GoogleMap
                           layouts/map.html.erb
<!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot; quot;http://www.w3.org/TR/html4/strict.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot;>
  <head>
    <meta http-equiv=quot;content-typequot; content=quot;text/html;charset=UTF-8quot; />
    <title>Google Maps Demo</title>
    <%= javascript_include_tag :all %>
    <script src=quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=<%= GeoKit::Geocoders::google %>quot;
          type=quot;text/javascriptquot;></script>
    <style type=quot;text/cssquot;>
      html, body {
        margin:0;
        height:100%
      }
      #map {
        min-height: 100%;
        background-color: #DDD;
      }
      * html #map {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
GoogleMap
                          views/users/map.html.erb

Action
def map
  @users = User.find :all
  render :layout => 'map'
end


Vue
<div id=quot;mapquot;></div>
<%= javascript_tag quot;new Application('map', '#{@users.to_json(:only => [:login, :lat, :lng])}');quot; %>
GoogleMap
                                    application.js
Application = new Class.create({
  initialize: function(map, users) {
     this.element = $(map);
     this.users   = users.evalJSON();
     document.observe(quot;dom:loadedquot;, this.init.bind(this));
  },

  init: function() {
    if (GBrowserIsCompatible()) {
      // Create a google map
      this.map = new GMap2(this.element);

          // Center on France
          this.map.setCenter(new GLatLng(46.227638, 2.213749), 6);

          // Add controls
          this.map.addControl(new GLargeMapControl());
          this.map.addControl(new GMapTypeControl());

          // Add Markers
          if (this.users) {
            this.users.each(function(user) {
              var marker = new GMarker(new GLatLng(user.lat, user.lng));

               GEvent.addListener(marker, quot;clickquot;, function() {
                 marker.openInfoWindowHtml(user.login);
               });

                this.map.addOverlay(marker);
              }.bind(this))
          }
      }
  }
});
MultiMap

         Pour le fun, ajouter un map par user sur la page index :)
<tr>
  <td><%= user.login %></td>
  <td><%= user.email %></td>
  <td><%= user.lat %></td>
  <td><%= user.lng %></td>
  <td><%= user.created_at.to_s :short %></td>
  <td><div id=quot;<%= dom_id(user) %>quot; class=quot;minimapquot;></div></td>
  <td><%= link_to 'edit', edit_user_path(user) %></td>
</tr>
<%= javascript_tag quot;new MiniMap('#{dom_id(user)}', '#{user.to_json(:only => [:login, :lat, :lng])}');quot; %>
MultiMap
                         Classe MiniMap

MiniMap = new Class.create({
  initialize: function(map, user) {
     this.element = $(map);
     this.user    = user.evalJSON();
     document.observe(quot;dom:loadedquot;, this.init.bind(this));
  },

  init: function() {
    if (GBrowserIsCompatible()) {
      // Create a google map
      this.map = new GMap2(this.element);

          // Center on France
          this.map.setCenter(new GLatLng(this.user.lat, this.user.lng), 6);

          var marker = new GMarker(new GLatLng(this.user.lat, this.user.lng));
          this.map.addOverlay(marker);
      }
  }
});
GeoKit
                    Autres fonctions
     • sort_by_distance_from
>> u = User.find :first
>> users.User.find :all
>> users.sort_by_distance_from u



     • Column distance
>> User.find :all, :origin => u, :within => 500, :order => 'distance'



     • GeoKit::Bounds
>> bounds = GeoKit::Bounds.new(sw_point, ne_point)
>> users = User.find :all, :bounds => bounds
GeoKit
                     Autres fonctions
     • eager loading
>> users = Users.find :all,
                      :origin    =>   home,
                      :include   =>   [:articles],

     •                :within
                      :order
                                 =>
                                 =>
                                      5,
                                      'distance'



     • IP Geocoding
>> location = GeoKit::Geocoders::IpGeocoder.geocode('82.236.140.196')
=> #<GeoKit::GeoLoc:0x2784fe0 @country_code=quot;FRquot;, @lat=48.0833,


     •
@street_address=nil, @precision=quot;unknownquot;, @zip=nil, @state=nil, @success=true,
@provider=quot;hostipquot;, @lng=-1.68333, @city=quot;Rennesquot;>
GeoKit
                   Autres fonctions
    • IP Geocoding
class ApplicationController < ActionController::Base
  # Auto-geocode the user's ip address and store
  # it in the session.
  geocode_ip_address

  def loc
    # @location is a GeoLoc instance.
    @location = session[:geo_location]
  end
end
GeoKit
                      Autres fonctions
     • Et encore!
# Finds within a distance radius.
def find_within(distance, options={})
alias find_inside find_within

# Finds beyond a distance radius.
def find_beyond(distance, options={})
alias find_outside find_beyond

# Finds according to a range. Accepts inclusive or exclusive ranges.
def find_by_range(range, options={})

# Finds the closest to the origin.
def find_closest(options={})
alias find_nearest find_closest

# Finds the farthest from the origin.
def find_farthest(options={})

# Finds within rectangular bounds (sw,ne).
def find_within_bounds(bounds, options={})
Done!!

• Code disponible sur github
  git://github.com/xilinus/gmaps_demo.git

More Related Content

What's hot

Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQuery
Remy Sharp
 
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
Ontico
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at Nackademin
Robert Nyman
 

What's hot (20)

OL4JSF - Latinoware 2010
OL4JSF - Latinoware 2010OL4JSF - Latinoware 2010
OL4JSF - Latinoware 2010
 
Navigation Architecture Component(京都Devかふぇ バージョン)
Navigation Architecture Component(京都Devかふぇ バージョン)Navigation Architecture Component(京都Devかふぇ バージョン)
Navigation Architecture Component(京都Devかふぇ バージョン)
 
Angular&node js upload file
Angular&node js upload fileAngular&node js upload file
Angular&node js upload file
 
navigation-uiライブラリは、既存のアプリを置き換える ことができないかもしれない
navigation-uiライブラリは、既存のアプリを置き換える ことができないかもしれないnavigation-uiライブラリは、既存のアプリを置き換える ことができないかもしれない
navigation-uiライブラリは、既存のアプリを置き換える ことができないかもしれない
 
Seti 09
Seti 09Seti 09
Seti 09
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
 
Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQuery
 
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
 
AngularJS Routing
AngularJS RoutingAngularJS Routing
AngularJS Routing
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
YUI 3
YUI 3YUI 3
YUI 3
 
AngularJS Services
AngularJS ServicesAngularJS Services
AngularJS Services
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 
Angular Promises and Advanced Routing
Angular Promises and Advanced RoutingAngular Promises and Advanced Routing
Angular Promises and Advanced Routing
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at Nackademin
 
Cyclejs introduction
Cyclejs introductionCyclejs introduction
Cyclejs introduction
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Pengenalan blaast platform sdk
Pengenalan blaast platform sdkPengenalan blaast platform sdk
Pengenalan blaast platform sdk
 
Android in practice
Android in practiceAndroid in practice
Android in practice
 

Viewers also liked (8)

Anupama resume
Anupama resumeAnupama resume
Anupama resume
 
Presentation1
Presentation1Presentation1
Presentation1
 
Viva file
Viva fileViva file
Viva file
 
Google maps
Google mapsGoogle maps
Google maps
 
Verona orienteering
Verona orienteeringVerona orienteering
Verona orienteering
 
Google maps
Google mapsGoogle maps
Google maps
 
Bulleting Orienteering
Bulleting OrienteeringBulleting Orienteering
Bulleting Orienteering
 
DIY Cartography
DIY CartographyDIY Cartography
DIY Cartography
 

Similar to Gmaps Railscamp2008

Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
OSCON Byrum
 
Sapo GIS Hands-On
Sapo GIS Hands-OnSapo GIS Hands-On
Sapo GIS Hands-On
codebits
 
Gis SAPO Hands On
Gis SAPO Hands OnGis SAPO Hands On
Gis SAPO Hands On
codebits
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
Ganesh Gembali
 
Barcamp GoogleMaps - praktické ukázky kódu
Barcamp GoogleMaps - praktické ukázky kóduBarcamp GoogleMaps - praktické ukázky kódu
Barcamp GoogleMaps - praktické ukázky kódu
Milos Lenoch
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
Anton Narusberg
 

Similar to Gmaps Railscamp2008 (20)

Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Google Maps API 101
Google Maps API 101Google Maps API 101
Google Maps API 101
 
Sapo GIS Hands-On
Sapo GIS Hands-OnSapo GIS Hands-On
Sapo GIS Hands-On
 
Gis SAPO Hands On
Gis SAPO Hands OnGis SAPO Hands On
Gis SAPO Hands On
 
@Ionic native/google-maps
@Ionic native/google-maps@Ionic native/google-maps
@Ionic native/google-maps
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
 
Google Maps JS API
Google Maps JS APIGoogle Maps JS API
Google Maps JS API
 
Rails Gis Hacks
Rails Gis HacksRails Gis Hacks
Rails Gis Hacks
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
ESRI Dev Meetup: Building Distributed JavaScript Map Widgets
ESRI Dev Meetup: Building Distributed JavaScript Map WidgetsESRI Dev Meetup: Building Distributed JavaScript Map Widgets
ESRI Dev Meetup: Building Distributed JavaScript Map Widgets
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Building Real-Time Applications with Android and WebSockets
Building Real-Time Applications with Android and WebSocketsBuilding Real-Time Applications with Android and WebSockets
Building Real-Time Applications with Android and WebSockets
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 
Worskhop Leicester 2010
Worskhop Leicester 2010Worskhop Leicester 2010
Worskhop Leicester 2010
 
Barcamp GoogleMaps - praktické ukázky kódu
Barcamp GoogleMaps - praktické ukázky kóduBarcamp GoogleMaps - praktické ukázky kódu
Barcamp GoogleMaps - praktické ukázky kódu
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with React
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
How data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield HeroesHow data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield Heroes
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 

Gmaps Railscamp2008

  • 1. Intégration de GoogleMaps dans une Application Rails 2.0 Sébastien Gruhier Xilinus Railscamp - Paris - 17 mai 2008
  • 2. GoogleMaps http://code.google.com/apis/maps/ • Affichage géolocalisé d’information (point, forme vectorielle, trafic ...) • Librairie Javascript • Gratuit sous certaines conditions • Nécessite une API key
  • 3. Plugin GeoKit http://geokit.rubyforge.org/ • Ajout de finder geolocalisé à ActiveRecord • MultiProvider (GoogleMap, YahooMaps...) • Calcul de distance • IP localisation via hostip.info • ...
  • 4. Application de demo • Application Rails 2.0 • Visualisation des utilisateurs sur une googlemap • Plugin restful_authenticated + geokit
  • 5. Initialisation • Assez parlé, codons un exemple rails gmaps_demo -d mysql; cd gmaps_demo • plugin geokit ./script/plugin install svn://rubyforge.org/var/svn/geokit/trunk git module add git://github.com/ptb/geokit.git vendor/plugins/geokit • plugin restful_authentication ./script/plugin install http://svn.techno-weenie.net/projects/plugins/ restful_authentication git submodule add git://github.com/technoweenie/restful-authentication.git vendor/plugins/restful_authentication • GIT: git submodule init
  • 6. GeoKit Test ./script/console Loading development environment (Rails 2.0.2) include GeoKit::Geocoders >> include GeoKit::Geocoders => Object >> home = MultiGeocoder.geocode(quot;151 rue montmartre, parisquot;) => #<GeoKit::GeoLoc:0x27769b8 @country_code=quot;FRquot;, @lat=48.870519, @street_address=quot;151, Rue Montmartrequot;, @full_address=quot;151, Rue Montmartre, 75002 2ème Arrondissement Paris, Paris, Francequot;, @precision=quot;addressquot;, @zip=quot;75002quot;, @state=quot;Ile-de-Francequot;, @success=true, @provider=quot;googlequot;, @lng=2.342718, @city=quot;Parisquot;> Calcul “in memory” >> home = MultiGeocoder.geocode(quot;151 rue montmartre, parisquot;) >> rennes = MultiGeocoder.geocode(quot;rennes, francequot;) >> home.distance_to(rennes, :units => :kms) => 308.473068506021
  • 7. Initialisation • Editer database.yml si nécessaire rake db:create • Génération de l’authentification (sans activation ni stateful) ./script/generate authenticated user sessions rake db:migrate rake db:fixtures:load
  • 8. Initialisation • Supprimer public/index.html • Ajouter un layout simple <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.1//ENquot; quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtdquot;> <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot;> <head> <meta http-equiv=quot;content-typequot; content=quot;text/html;charset=UTF-8quot; /> <title>Google Maps Demo</title> </head> <body> <%= yield %> </body> </html>
  • 9. Initialisation • Ajouter une vue users/index.html.erb User List <table border=quot;0quot; cellspacing=quot;5quot; cellpadding=quot;5quot;> <tr> <th>Login</th> <th>Email</th> <th>Created At</th> </tr> <%= render :partial => quot;userquot;, :collection => @users %> </table> <br/> <%= link_to 'Add a new user', new_user_path %> • Avec un partial users/_user.html.erb <tr> <td><%= user.login %></td> <td><%= user.email %></td> <td><%= user.created_at.to_s :short %></td> </tr>
  • 10. Initialisation fin! • On ajoute une route par défaut map.root :controller => 'users' • Déplacer le code de environment.rb dans config/initializers/geokit.rb avec une clé google valide • Et on peut enfin s’amuser avec GoogleMaps :)
  • 11. Géolocalisation • Ajouter des attributs au model User ./script/generate migration add_geolocalisation_to_users class AddGeolocalisationToUsers < ActiveRecord::Migration def self.up add_column :users, :address, :string add_column :users, :lat, :decimal, :precision => 15, :scale => 10 add_column :users, :lng, :decimal, :precision => 15, :scale => 10 end def self.down remove_column :users, :address remove_column :users, :lat • remove_column :users, :lng end end
  • 12. Géolocalisation • Mettre la jour les deux fixtures à Utilise console !! ./script/console Loading development environment (Rails 2.0.2) >> MultiGeocoder.geocode(quot;10 rue de la republique, paris, francequot;) => #<GeoKit::GeoLoc:0x1102bdc @country_code=quot;FRquot;, @lat=48.866816, • @street_address=quot;10, Avenue De La Républiquequot;, @full_address=quot;10, Avenue de la République, 75011 11ème Arrondissement Paris, Paris, Francequot;, @precision=quot;addressquot;, @zip=quot;75011quot;, @state=quot;Ile-de-Francequot;, @success=true, @provider=quot;googlequot;, @lng=2.366405, @city=quot;Parisquot;>
  • 13. Géolocalisation • Ajouter au modèle User attr_accessible ..., :address acts_as_mappable :auto_geocode => true before_validation_on_update :auto_geocode_address • Ajouter edit/update + adresse à un user (dans la vue)
  • 14. GoogleMap • Ajouter une route users/map map.resources :users, :collection => {:map => :get} • Une action, un layout fullscreen: map.html.erb
  • 15. GoogleMap layouts/map.html.erb <!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot; quot;http://www.w3.org/TR/html4/strict.dtdquot;> <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot;> <head> <meta http-equiv=quot;content-typequot; content=quot;text/html;charset=UTF-8quot; /> <title>Google Maps Demo</title> <%= javascript_include_tag :all %> <script src=quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=<%= GeoKit::Geocoders::google %>quot; type=quot;text/javascriptquot;></script> <style type=quot;text/cssquot;> html, body { margin:0; height:100% } #map { min-height: 100%; background-color: #DDD; } * html #map { height: 100%; } </style> </head> <body> <%= yield %> </body> </html>
  • 16. GoogleMap views/users/map.html.erb Action def map @users = User.find :all render :layout => 'map' end Vue <div id=quot;mapquot;></div> <%= javascript_tag quot;new Application('map', '#{@users.to_json(:only => [:login, :lat, :lng])}');quot; %>
  • 17. GoogleMap application.js Application = new Class.create({ initialize: function(map, users) { this.element = $(map); this.users = users.evalJSON(); document.observe(quot;dom:loadedquot;, this.init.bind(this)); }, init: function() { if (GBrowserIsCompatible()) { // Create a google map this.map = new GMap2(this.element); // Center on France this.map.setCenter(new GLatLng(46.227638, 2.213749), 6); // Add controls this.map.addControl(new GLargeMapControl()); this.map.addControl(new GMapTypeControl()); // Add Markers if (this.users) { this.users.each(function(user) { var marker = new GMarker(new GLatLng(user.lat, user.lng)); GEvent.addListener(marker, quot;clickquot;, function() { marker.openInfoWindowHtml(user.login); }); this.map.addOverlay(marker); }.bind(this)) } } } });
  • 18. MultiMap Pour le fun, ajouter un map par user sur la page index :) <tr> <td><%= user.login %></td> <td><%= user.email %></td> <td><%= user.lat %></td> <td><%= user.lng %></td> <td><%= user.created_at.to_s :short %></td> <td><div id=quot;<%= dom_id(user) %>quot; class=quot;minimapquot;></div></td> <td><%= link_to 'edit', edit_user_path(user) %></td> </tr> <%= javascript_tag quot;new MiniMap('#{dom_id(user)}', '#{user.to_json(:only => [:login, :lat, :lng])}');quot; %>
  • 19. MultiMap Classe MiniMap MiniMap = new Class.create({ initialize: function(map, user) { this.element = $(map); this.user = user.evalJSON(); document.observe(quot;dom:loadedquot;, this.init.bind(this)); }, init: function() { if (GBrowserIsCompatible()) { // Create a google map this.map = new GMap2(this.element); // Center on France this.map.setCenter(new GLatLng(this.user.lat, this.user.lng), 6); var marker = new GMarker(new GLatLng(this.user.lat, this.user.lng)); this.map.addOverlay(marker); } } });
  • 20. GeoKit Autres fonctions • sort_by_distance_from >> u = User.find :first >> users.User.find :all >> users.sort_by_distance_from u • Column distance >> User.find :all, :origin => u, :within => 500, :order => 'distance' • GeoKit::Bounds >> bounds = GeoKit::Bounds.new(sw_point, ne_point) >> users = User.find :all, :bounds => bounds
  • 21. GeoKit Autres fonctions • eager loading >> users = Users.find :all, :origin => home, :include => [:articles], • :within :order => => 5, 'distance' • IP Geocoding >> location = GeoKit::Geocoders::IpGeocoder.geocode('82.236.140.196') => #<GeoKit::GeoLoc:0x2784fe0 @country_code=quot;FRquot;, @lat=48.0833, • @street_address=nil, @precision=quot;unknownquot;, @zip=nil, @state=nil, @success=true, @provider=quot;hostipquot;, @lng=-1.68333, @city=quot;Rennesquot;>
  • 22. GeoKit Autres fonctions • IP Geocoding class ApplicationController < ActionController::Base # Auto-geocode the user's ip address and store # it in the session. geocode_ip_address def loc # @location is a GeoLoc instance. @location = session[:geo_location] end end
  • 23. GeoKit Autres fonctions • Et encore! # Finds within a distance radius. def find_within(distance, options={}) alias find_inside find_within # Finds beyond a distance radius. def find_beyond(distance, options={}) alias find_outside find_beyond # Finds according to a range. Accepts inclusive or exclusive ranges. def find_by_range(range, options={}) # Finds the closest to the origin. def find_closest(options={}) alias find_nearest find_closest # Finds the farthest from the origin. def find_farthest(options={}) # Finds within rectangular bounds (sw,ne). def find_within_bounds(bounds, options={})
  • 24. Done!! • Code disponible sur github git://github.com/xilinus/gmaps_demo.git