Slide de ma session sur l'integration d'une google map dans une application Rails. Le code est disponible sur github: http://github.com/xilinus/gmaps_demo/
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
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
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);
}
}
});
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={})