Skip to content

Commit

Permalink
v0.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
apneadiving committed Feb 15, 2011
0 parents commit 2681960
Show file tree
Hide file tree
Showing 44 changed files with 883 additions and 0 deletions.
123 changes: 123 additions & 0 deletions README.rdoc
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,123 @@
== Gmaps4rails

Gmaps4rails is developped to simply create a Google Map (Gmaps) from:

- model instances (say Users),

- your own json

It's based on Ruby on Rails 3 Engines and uses Google Maps API V3 with Marker Clusterer in option.


== Installation

gem install gmaps4rails

== Requirements
- <%= yield :head %> (in your header)
- <%= yield :scripts %> (in your footer)
- config.serve_static_assets = true (in your production.rb)
- jQuery (used for ajax json, not mandatory if you only use the 'json' option)

== Basic configuration
In your model, add:

acts_as_gmappable

def gmaps4rails_address
self.address #describe how to retrieve the address from your model
end

Create a migration and add the following fields to your table (here users):

add_column :users, :latitude, :float
add_column :users, :longitude, :float
add_column :users, :gmaps, :boolean

== How to?
=== QuickStart!
Say you have a User model and you want to display all the users on a map.
In your view:

<%= gmaps4rails_map("User") %>

Done!

=== Same Result, alternative solution
With this version, you won't need jQuery.
In your controller:

@json = User.all.to_gmaps4rails

In your view:

<%= gmaps4rails_map(@json, { "processing" => 'json' }) %>

Done again!

== Options

=== Add an info window
To add an info window (visible when you click a marker), add this method in your model:

def gmaps4rails_infowindow
# add here whatever html content you desire, it will be displayed when users clicks on the marker
end

=== List of Options
You can customize the following:

processing: 'rails_model', //or 'json'
marker_picture : 'http://www.mbs.edu/i/gmap_marker_default.gif,
model_scope : null,
marker_width : 22,
marker_length : 32,
map_center_latitude : 0,
map_center_longitude : 0,
map_zoom : 1,
do_clustering: true,
clusterer_gridSize: 50,
clusterer_maxZoom: 10

=== How to set your own options
Change the call in your view this way and add an additional hash containing the options you want:
<%= gmaps4rails_map("User", {"map_center_longitude" => "90", "do_clustering" => false}) %>

=== Scopes (displays a dropdown list enabling you to filter the map content)
Note that you can pass a model_scope in the options to filter the data you want to be displayed.
So as above, change the call in your view:

<%= gmaps4rails_map("User", {"model_scope" => "my_scope"}) %>

In this case, you must add in your model:

def self.gmaps4rails_trusted_scopes
["my_scope", "another_trusted_scope"]
end

Why? because you shall never trust the params, so it's a way to keep control.

=== Create from your own json
If you want to use your own json to initialize the map, create your json with the following attributes

@json = '[
{"description": "", "longitude": "", "latitude": "", "picture": "", "width": "", "height": ""},
{"longitude": "", "latitude": "" }
]'

Only `latitude` and `longitude` are mandatory. But you can customize any single marker.

Then in your view:

<%= gmaps4rails_map(@json, { "processing" => 'json' }) %>

Or with options as well:

<%= gmaps4rails_map(@json, {"processing" => 'json', "map_center_longitude" => "90"}) %>

== Todo?

Feel free ton contact me, you have your say. I hope I'll have time enough to improve it.

== Copyright
Copyright (c) 2011 apneadiving. See LICENSE for details.
16 changes: 16 additions & 0 deletions Rakefile
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,16 @@
begin
require "jeweler"
Jeweler::Tasks.new do |gem|
gem.name = "gmaps4rails"
gem.summary = "Enables easy display of items (taken from a Rails 3 model) on a Google Map. Uses Javascript API V3."
gem.description = "Enables easy display of items (taken from a Rails 3 model) on a Google Map. Uses Javascript API V3. Provides a helper and much configuration."
gem.homepage = "http://github.com/apneadiving/Gmaps4rails"
gem.email = "benjamin.roth@peachyweb.com"
gem.authors = ["Benjamin Roth", "David Ruyer"]
gem.files = Dir["{lib}/**/*", "{app}/**/*", "{public}/**/*", "{config}/**/*"]
gem.add_dependency "crack", ">= 0"
end
Jeweler::GemcutterTasks.new
rescue
puts "Jeweler or dependency not available."
end
1 change: 1 addition & 0 deletions VERSION
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
0.2.3
22 changes: 22 additions & 0 deletions app/controllers/gmaps4rails/gmaps_controller.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,22 @@
module Gmaps4rails
class GmapsController < ApplicationController
unloadable

def index
@model = params["model"]
@scope = params["scope"]
@model = @model.constantize

# The split returns the array [scope_name, arg1, arg2, ...]
if @scope && !@scope.empty? && @model.gmaps4rails_trusted_scopes.include?(@scope.split(/\(| *, *|\)/)[0])
object = eval("#{@model}.#{@scope}") # Cannot use send with lambda scope
# because the arguments have to be separated
@objects = object.to_gmaps4rails
else
@objects = @model.all.to_gmaps4rails
end

render :json => @objects
end
end
end
5 changes: 5 additions & 0 deletions app/helpers/gmaps4rails/gmaps_helper.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,5 @@
module Gmaps4rails
module GmapsHelper

end
end
28 changes: 28 additions & 0 deletions app/views/gmaps4rails/_gmaps4rails.html.erb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,28 @@
<% content_for :head do %>
<%= stylesheet_link_tag 'gmaps4rails' %>
<% end %>
<% content_for :scripts do %>
<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src='http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer.js'></script>
<%=javascript_include_tag 'gmaps4rails' %>
<script type="text/javascript" charset="utf-8">
var styles = [{
url: 'http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/images/people35.png',
height: 35,
width: 35,
opt_anchor: [16, 0],
opt_textColor: '#ff00ff',
opt_textSize: 10
}];
<% options.each do |key, value| %>
Gmaps4Rails.<%= key %> = <%=raw value.is_a?(String) ? "'#{value}'" : value %>;
<% end %>
var builder = <%=raw options["processing"] == "json" ? builder : "'#{builder}'" %>;
Gmaps4Rails.initialize(builder);
</script>
<% end %>

<div id="map-container">
<div id="gmaps4rails_map"></div>
</div>
5 changes: 5 additions & 0 deletions config/routes.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,5 @@
Rails.application.routes.draw do

resources :gmaps, :only => [ :index ], :controller => "gmaps4rails/gmaps"

end
59 changes: 59 additions & 0 deletions gmaps4rails.gemspec
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-

Gem::Specification.new do |s|
s.name = %q{gmaps4rails}
s.version = "0.2.3"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Benjamin Roth", "David Ruyer"]
s.date = %q{2011-02-15}
s.description = %q{Enables easy display of items (taken from a Rails 3 model) on a Google Map. Uses Javascript API V3. Provides a helper and much configuration.}
s.email = %q{benjamin.roth@peachyweb.com}
s.extra_rdoc_files = [
"README.rdoc"
]
s.files = [
"app/controllers/gmaps4rails/gmaps_controller.rb",
"app/helpers/gmaps4rails/gmaps_helper.rb",
"app/views/gmaps4rails/_gmaps4rails.html.erb",
"config/routes.rb",
"lib/acts_as_gmappable/base.rb",
"lib/application_helper.rb",
"lib/array.rb",
"lib/gmaps4rails.rb",
"lib/rails/generators/gmaps4rails/gmaps4rails_generator.rb",
"lib/rails/generators/gmaps4rails/templates/initializer.rb",
"lib/rails/generators/gmaps4rails/templates/migration.rb",
"lib/rails/generators/gmaps4rails/templates/schema.rb",
"lib/rails/railties/tasks.rake",
"lib/tasks/install.rake",
"public/images/marker.png",
"public/javascripts/gmaps4rails.js",
"public/javascripts/old.js",
"public/stylesheets/gmaps4rails.css"
]
s.homepage = %q{http://github.com/apneadiving/Gmaps4rails}
s.require_paths = ["lib"]
s.rubygems_version = %q{1.5.0}
s.summary = %q{Enables easy display of items (taken from a Rails 3 model) on a Google Map. Uses Javascript API V3.}
s.test_files = [
"test/test_helper.rb",
"test/unit/gmaps4rails_widget_test.rb"
]

if s.respond_to? :specification_version then
s.specification_version = 3

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<crack>, [">= 0"])
else
s.add_dependency(%q<crack>, [">= 0"])
end
else
s.add_dependency(%q<crack>, [">= 0"])
end
end

99 changes: 99 additions & 0 deletions lib/acts_as_gmappable/base.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,99 @@
require 'net/http'
require 'uri'
require 'crack'

module Gmaps4rails

def Gmaps4rails.create_json(object)
"{\"description\": \"#{object.gmaps4rails_infowindow}\",
\"longitude\": \"#{object.gmaps4rails_longitude}\",
\"latitude\": \"#{object.gmaps4rails_latitude}\",
\"picture\": \"#{object.gmaps4rails_marker_picture['picture']}\",
\"width\": \"#{object.gmaps4rails_marker_picture['width']}\",
\"height\": \"#{object.gmaps4rails_marker_picture['height']}\"
}"
end

module ActsAsGmappable

module Base
def self.included(klass)
klass.class_eval do
extend Config
end
end

module Config
def acts_as_gmappable options = {}
before_save :get_coordinates
include Gmaps4rails::ActsAsGmappable::Base::InstanceMethods
end
end

module InstanceMethods

def gmaps4rails_infowindow
self.gmaps4rails_picture.blank? ? "" : "<img width='40' heigth='40' src='" + self.gmaps4rails_picture + "'>"
end

def gmaps4rails_picture
""
end

def gmaps4rails_marker_picture
{
"picture" => "",
"width" => "",
"height" => ""
}
end

def self.gmaps4rails_trusted_scopes
[]
end

def to_gmaps4rails
json = "["
if (!(self.gmaps4rails_latitude == "" || self.gmaps4rails_longitude == ""))
json += Gmaps4rails.create_json(self)
json += ","
end
json.chop!
json += "]"
end

def get_coordinates
if self.gmaps4rails_address.nil? || self.gmaps4rails_address.empty?
self.gmaps = false
else
geocoder = "http://maps.googleapis.com/maps/api/geocode/json?address="
output = "&sensor=false"
#send request to the google api to get the lat/lng
request = geocoder + self.gmaps4rails_address + output
url = URI.escape(request)
resp = Net::HTTP.get_response(URI.parse(url))
#parse result if result received properly
if resp.inspect.include?('HTTPOK 200 OK')
#parse the json
parse = Crack::JSON.parse(resp.body)
#check if google went well
if parse["status"] == "OK"
#TODO maybe handle case when there are many results
#TODO store the country name and maybe other details?
self.gmaps4rails_latitude = parse["results"].first["geometry"]["location"]["lat"]
self.gmaps4rails_longitude = parse["results"].first["geometry"]["location"]["lng"]
#saves a boolean to remind the status
self.gmaps = true
end
else
self.gmaps = false
end
end
return true
end
end # InstanceMethods
end
end
end

::ActiveRecord::Base.send :include, Gmaps4rails::ActsAsGmappable::Base
7 changes: 7 additions & 0 deletions lib/application_helper.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,7 @@
module ApplicationHelper

def gmaps4rails_map(builder, options = {})
render :partial => 'gmaps4rails/gmaps4rails', :locals => { :builder => builder, :options => options }
end

end
13 changes: 13 additions & 0 deletions lib/array.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,13 @@
class Array
def to_gmaps4rails
json = "["
each do |object|
if (!(object.gmaps4rails_latitude == "" || object.gmaps4rails_longitude == ""))
json += Gmaps4rails.create_json(object)
json += ","
end
end
json.chop!
json += "]"
end
end
Loading

0 comments on commit 2681960

Please sign in to comment.