gmaps4rails 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -0,0 +1,48 @@
1
+ == Gmaps4rails
2
+
3
+ Gmaps4rails is developed to simply create a map with model instances (say Users).
4
+ It's still in heavy dev and I have a bug with engines (I can't find enough doc on this topic). See http://github.com/krschacht/rails_3_engine_demo/issues/issue/3/ for the bug report.
5
+
6
+
7
+
8
+ == Installation
9
+
10
+ gem install gmaps4rails
11
+
12
+ == Requirements
13
+ - jQuery (for ajax json)
14
+ - <%= yield :head %> in your header
15
+
16
+ == Examples
17
+
18
+ === In your model
19
+ acts_as_gmappable
20
+
21
+ def gmaps4rails_address
22
+ self.address #describe how to retrieve the address from your model
23
+ end
24
+
25
+ def gmaps4rails_picture
26
+ self.picture #describe how to retrieve the picture from your model
27
+ end
28
+
29
+ def gmaps4rails_description
30
+ self.name #could be html
31
+ end
32
+
33
+ === Create a migration and add the following fields to your table:
34
+ t.string "gmaps4rails_latitude"
35
+ t.string "gmaps4rails_longitude"
36
+ t.boolean "gmaps"
37
+
38
+ === In your view
39
+ <%= render :partial => 'gmaps4rails/gmaps4rails', :locals => { :model => "User"} %>
40
+
41
+ == Todo
42
+ Many customization will be available (at least, those already developed but not written here):
43
+ - integration of scopes to decide what you want to display precisely
44
+ - distance filter
45
+
46
+ == Copyright
47
+
48
+ Copyright (c) 2010 apneadiving. See LICENSE for details.
@@ -4,8 +4,10 @@ module Gmaps4rails
4
4
 
5
5
  def index
6
6
  @model = params["model"]
7
+ @filter = params["filter"]
8
+ @options = params["options"]
7
9
  if @model.constantize.is_gmappable? == true
8
- @objects = @model.constantize.gmaps4rails_filter(params["filter"], params["options"])
10
+ @objects = @model.constantize.gmaps4rails_filter(@filter, @options)
9
11
  end
10
12
  end
11
13
 
@@ -1,7 +1,5 @@
1
1
  module Gmaps4rails
2
2
  module GmapsHelper
3
- def gmaps_sanitize(entity)
4
- entity.nil? ? "" : entity
5
- end
3
+
6
4
  end
7
5
  end
@@ -0,0 +1,66 @@
1
+ <% content_for :head do %>
2
+ <style type="text/css">
3
+
4
+ #map-container {
5
+ padding: 6px;
6
+ border-width: 1px;
7
+ border-style: solid;
8
+ border-color: #ccc #ccc #999 #ccc;
9
+ -webkit-box-shadow: rgba(64, 64, 64, 0.5) 0 2px 5px;
10
+ -moz-box-shadow: rgba(64, 64, 64, 0.5) 0 2px 5px;
11
+ box-shadow: rgba(64, 64, 64, 0.1) 0 2px 5px;
12
+ width: 800px;
13
+ }
14
+
15
+ #gmaps4rails_map {
16
+ width: 800px;
17
+ height: 400px;
18
+ }
19
+
20
+ #actions {
21
+ list-style: none;
22
+ padding: 0;
23
+ }
24
+
25
+ #inline-actions {
26
+ padding-top: 10px;
27
+ }
28
+
29
+ .item {
30
+ margin-left: 20px;
31
+ }
32
+ </style>
33
+ <script src="http://www.google.com/jsapi"></script>
34
+ <script type="text/javascript" src='http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer.js'>
35
+ </script>
36
+ <script type="text/javascript">
37
+ var styles = [{
38
+ url: 'http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/images/people35.png',
39
+ height: 35,
40
+ width: 35,
41
+ opt_anchor: [16, 0],
42
+ opt_textColor: '#ff00ff',
43
+ opt_textSize: 10
44
+ }];
45
+ var gmaps4rails_ref_lat = <%= defined?(ref_latitude) ? ref_latitude : 'null' %>;
46
+ var gmaps4rails_ref_long = <%= defined?(ref_longitude) ? ref_longitude : 'null' %>;
47
+ var gmaps4rails_marker_picture = '<%= model.constantize.gmaps4rails_markers_pic["picture"] %>';
48
+ var gmaps4rails_marker_width = <%= model.constantize.gmaps4rails_markers_pic["width"] %>;
49
+ var gmaps4rails_marker_length = <%= model.constantize.gmaps4rails_markers_pic["length"] %>;
50
+ var gmaps4rails_model = '<%= model %>';
51
+ var gmaps4rails_map_center_lat = <%= model.constantize.gmaps4rails_map_options["latitude"] %>;
52
+ var gmaps4rails_map_center_long = <%= model.constantize.gmaps4rails_map_options["longitude"] %>;
53
+ var gmaps4rails_map_zoom = <%= model.constantize.gmaps4rails_map_options["zoom"] %>;
54
+ var gmaps4rails_base_url = '<%= url_for gmaps_path%>';
55
+ </script>
56
+ <script src="/javascripts/gmaps4rails.js" type="text/javascript"></script>
57
+ <% end %>
58
+ <div id="map-container">
59
+ <div id="gmaps4rails_map"></div>
60
+ </div>
61
+ <% if defined?(ref_longitude) && defined?(ref_latitude)%>
62
+ <div id="inline-actions">
63
+ <input id="gmaps4rails_user_distance" >
64
+ <input type="submit" value="Filter" class="item" onclick="filter_distance()">
65
+ </div>
66
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  <% content_for(:head) do %>
2
- <meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
2
+ <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
3
3
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script>
4
4
  <script type="text/javascript" src="/javascripts/gmaps4rails.js"> </script>
5
5
  <script type="text/javascript">
@@ -17,7 +17,7 @@
17
17
  gmaps4rails_model = model;
18
18
  var myLatLng = new google.maps.LatLng(0,0);
19
19
  gmaps4rails_Options = {
20
- zoom: 2,
20
+ zoom: 0,
21
21
  center: myLatLng,
22
22
  mapTypeId: google.maps.MapTypeId.ROADMAP
23
23
  }
@@ -41,7 +41,6 @@
41
41
  request += '&options=' + split_filter_value[1];
42
42
  }
43
43
  }
44
- alert(request); //TODO remove for real production
45
44
  gmaps4rails_ctaLayer = new google.maps.KmlLayer(request);
46
45
  gmaps4rails_ctaLayer.setMap(gmaps4rails_map);
47
46
  }
@@ -0,0 +1,27 @@
1
+ { "count": <%= @objects.size.to_s %>,
2
+ "markers": [
3
+ <% if @objects.first.respond_to?('gmaps4rails_info')
4
+ @objects.each do |object|
5
+ desc = object.gmaps4rails_info.nil? ? "No description provided" : CGI::escapeHTML(object.gmaps4rails_info)
6
+ lat = object.gmaps4rails_latitude.nil? ? "" : object.gmaps4rails_latitude
7
+ long = object.gmaps4rails_longitude.nil? ? "" : object.gmaps4rails_longitude
8
+ %>
9
+ {"description": "<%=raw desc %>", "longitude": <%= long %>, "latitude": <%= lat %>, "marker_object": "null"}
10
+ <% end
11
+
12
+ else
13
+ @objects.each do |object|
14
+ stat = object.status.nil? ? "" : CGI::escapeHTML(object.status)
15
+ desc = object.picture.nil? ? "No description provided" : "<img width='40' heigth='40' src='" + object.gmaps4rails_picture + "'>" + stat
16
+
17
+ lat = object.gmaps4rails_latitude.nil? ? "" : object.gmaps4rails_latitude
18
+ long = object.gmaps4rails_longitude.nil? ? "" : object.gmaps4rails_longitude
19
+
20
+ if (!(lat == "" || long == "")) %>
21
+ {"description": "<%=raw desc %>", "longitude": <%= long %>, "latitude": <%= lat %>, "marker_object": "null"} <%= ',' unless object == @objects.last %>
22
+ <%
23
+ end
24
+ end
25
+ end
26
+ %>
27
+ ]}
@@ -70,7 +70,7 @@ xml.kml do
70
70
  lat = object.gmaps4rails_latitude.nil? ? "" : object.gmaps4rails_latitude
71
71
  long = object.gmaps4rails_longitude.nil? ? "" : object.gmaps4rails_longitude
72
72
  xml.styleUrl "#customMap"
73
- xml.description desc
73
+ xml.description '<![CDATA[' + desc + ']]>'
74
74
  xml.Point do
75
75
  str = long + "," + lat + ",0"
76
76
  xml.coordinates(str)
@@ -86,7 +86,7 @@ xml.kml do
86
86
  lat = object.gmaps4rails_latitude.nil? ? "" : object.gmaps4rails_latitude
87
87
  long = object.gmaps4rails_longitude.nil? ? "" : object.gmaps4rails_longitude
88
88
 
89
- xml.description desc
89
+ xml.description '<![CDATA[' + desc +']]>'
90
90
  xml.Point do
91
91
  str = long + "," + lat + ",0"
92
92
  xml.coordinates(str)
data/config/routes.rb CHANGED
@@ -6,7 +6,7 @@ Rails.application.routes.draw do |map|
6
6
 
7
7
  map.resources :gmaps, :only => [ :index ],
8
8
  :controller => "gmaps4rails/gmaps",
9
- :path_prefix => mount_at#,
9
+ :path_prefix => mount_at
10
10
  #:name_prefix => "gmaps4rails_"
11
11
 
12
12
  end
@@ -1,5 +1,6 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
+ require 'crack'
3
4
 
4
5
  module Gmaps4rails
5
6
  module ActsAsGmappable
@@ -19,6 +20,16 @@ module Gmaps4rails
19
20
  true
20
21
  end
21
22
 
23
+ def self.gmaps4rails_markers_pic
24
+ { "picture" =>'http://inmotionchiro.com/gmap_plugin/imgs/markers/marker.png',
25
+ "width" => 22,
26
+ "length" => 32 }
27
+ end
28
+
29
+ def gmaps4rails_map_options
30
+ { "zoom" =>1, "latitude" => 0, "longitude" => 0}
31
+ end
32
+
22
33
  include Gmaps4rails::ActsAsGmappable::Base::InstanceMethods
23
34
  end
24
35
  end
@@ -26,28 +37,36 @@ module Gmaps4rails
26
37
  module InstanceMethods
27
38
 
28
39
  def get_coordinates
29
- if self.adress.nil? || self.adress == ""
40
+ if self.gmaps4rails_address.nil? || self.gmaps4rails_address.empty?
30
41
  self.gmaps = false
31
42
  else
32
- geocoder = "http://maps.google.com/maps/geo?q="
33
- output = "&output=csv"
43
+ geocoder = "http://maps.googleapis.com/maps/api/geocode/json?address="
44
+ output = "&sensor=false"
34
45
  #send request to the google api to get the lat/lng
35
- request = geocoder + self.adress + output
46
+ request = geocoder + self.gmaps4rails_address + output
36
47
  url = URI.escape(request)
37
48
  resp = Net::HTTP.get_response(URI.parse(url))
38
49
  #parse result if result received properly
39
50
  if resp.inspect.include?('HTTPOK 200 OK')
40
- fields = resp.body.split(',')
41
- self.gmaps4rails_latitude = fields[2]
42
- self.gmaps4rails_longitude = fields[3]
43
- #saves a boolean to remind the status
44
- self.gmaps = true
51
+ #parse the json
52
+ parse = Crack::JSON.parse(resp.body)
53
+ #check if google went well
54
+ if parse["status"] == "OK"
55
+ #TODO maybe handle case when there are many results
56
+ #TODO store the country name and maybe other details?
57
+ latitude = parse["results"].first["geometry"]["location"]["lat"]
58
+ longitude = parse["results"].first["geometry"]["location"]["lng"]
59
+ self.gmaps4rails_latitude = latitude
60
+ self.gmaps4rails_longitude = longitude
61
+ #saves a boolean to remind the status
62
+ self.gmaps = true
63
+ end
45
64
  else
46
65
  self.gmaps = false
47
66
  end
48
67
  end
49
68
  return true
50
- end
69
+ end
51
70
  end # InstanceMethods
52
71
  end
53
72
  end
Binary file
@@ -1,49 +1,139 @@
1
- var gmaps4rails_map;
2
- var gmaps4rails_Options;
3
- var gmaps4rails_ctaLayer;
4
- var gmaps4rails_model;
5
-
6
- function gmaps4rails_init(model) {
7
- gmaps4rails_model = model;
8
- var myLatLng = new google.maps.LatLng(0,0);
9
- gmaps4rails_Options = {
10
- zoom: 2,
11
- center: myLatLng,
12
- mapTypeId: google.maps.MapTypeId.ROADMAP
13
- }
14
- gmaps4rails_map = new google.maps.Map(document.getElementById("gmaps4rails_canvas"), gmaps4rails_Options);
15
- create_map();
16
- }
17
-
18
- function create_map(filter_value) {
19
- var date = new Date();
20
- //adding the date (which is a unique parameter, enables to bypass google map's cache on google server)
21
- var request = 'http://furious-robot-66.heroku.com/gmaps.xml?model=' + gmaps4rails_model + '&time=' + date.getTime();
22
- if (!(filter_value == null))
23
- {
24
- split_filter_value = filter_value.split('+');
25
- if (!(split_filter_value[0] == null))
26
- {
27
- request += '&filter=' + split_filter_value[0];
28
- }
29
- if (!(split_filter_value[1] == null))
30
- {
31
- request += '&options=' + split_filter_value[1];
32
- }
33
- }
34
- alert(request); //TODO remove for real production
35
- gmaps4rails_ctaLayer = new google.maps.KmlLayer(request);
36
- gmaps4rails_ctaLayer.setMap(gmaps4rails_map);
1
+ google.load('maps', '3', { other_params: 'sensor=false' });
2
+
3
+ google.setOnLoadCallback(initialize);
4
+ var gmaps4rails_map = null;
5
+ var gmaps4rails_data = null;
6
+ var markerClusterer = null;
7
+ var gmaps4rails_infowindow = null;
8
+ var gmaps_circle = null ;
9
+
10
+ //put markers on the map + launch the clusterer
11
+ function setMarkers(locations) {
12
+
13
+ //variable used for Marker Clusterer
14
+ var markers = [];
15
+
16
+ if (markerClusterer) {
17
+ markerClusterer.clearMarkers();
37
18
  }
19
+ // Add markers to the map
20
+ for (var i = 0; i < locations.markers.length; ++i) {
21
+ // Marker sizes are expressed as a Size of X,Y
22
+ var image = new google.maps.MarkerImage(gmaps4rails_marker_picture,
23
+ new google.maps.Size(gmaps4rails_marker_width, gmaps4rails_marker_length));
24
+ var myLatLng = new google.maps.LatLng(locations.markers[i].latitude, locations.markers[i].longitude);
25
+ var ThisMarker = new google.maps.Marker({position: myLatLng, map: gmaps4rails_map, icon: image}); //TODO Offer title customization title: "title"
26
+ //save object for later use, basically, to get back the text to display when clicking it
27
+ locations.markers[i].marker_object = ThisMarker;
28
+ //save the marker again in a list for the clusterer
29
+ markers.push(ThisMarker);
30
+
31
+ //add click listener
32
+ google.maps.event.addListener(locations.markers[i].marker_object, 'click', function() { if (gmaps4rails_infowindow!=null) {gmaps4rails_infowindow.close();}; getInfoWindow(this);});
33
+
34
+ }
35
+
36
+ markerClusterer = new MarkerClusterer(gmaps4rails_map, markers, {
37
+ maxZoom: 10,
38
+ gridSize: 50,
39
+ //styles: styles TODO: offer clusterer customization
40
+ });
41
+ }
38
42
 
39
- function gmaps4rails_raz(){
40
- gmaps4rails_map = new google.maps.Map(document.getElementById("gmaps4rails_canvas"), gmaps4rails_myOptions);
43
+ //get infowindow content when listener calls it
44
+ function getInfoWindow(which)
45
+ {
46
+ for ( var m = 0; m < gmaps4rails_data.markers.length; ++m )
47
+ {
48
+ var markerInfo = gmaps4rails_data.markers[m].marker_object;
49
+ if ( markerInfo == which )
50
+ {
51
+ gmaps4rails_infowindow = new google.maps.InfoWindow({content: gmaps4rails_data.markers[m].description });
52
+ gmaps4rails_infowindow.open( gmaps4rails_map, which );
53
+ return;
54
+ }
41
55
  }
56
+ }
57
+
58
+ //initializes the map
59
+ function create_map(filter_value) {
60
+ request = gmaps4rails_base_url + '?model=' + gmaps4rails_model;
61
+
62
+ if (!(filter_value == null))
63
+ {
64
+ split_filter_value = filter_value.split('+');
65
+ if (!(split_filter_value[0] == null))
66
+ {
67
+ request += '&filter=' + split_filter_value[0];
68
+ }
69
+ if (!(split_filter_value[1] == null))
70
+ {
71
+ request += '&options=' + split_filter_value[1];
72
+ }
73
+ }
74
+ jQuery.getJSON(request,
75
+ function(data){
76
+ gmaps4rails_data = data;
77
+ setMarkers(gmaps4rails_data);
78
+ });
79
+ }
42
80
 
43
- function gmaps4rails_resfreshmap()
44
- {
45
- gmaps4rails_raz();
81
+ function initialize() {
82
+ gmaps4rails_reset();
83
+ //infowindow closes when user clicks on the map
84
+ google.maps.event.addListener(gmaps4rails_map, 'click', function()
85
+ { if (gmaps4rails_infowindow != null) {gmaps4rails_infowindow.close();}
86
+ });
87
+ create_map();
88
+ }
89
+
90
+ function gmaps4rails_resfreshmap() {
91
+ gmaps4rails_reset();
46
92
  var index = document.gmaps4rails_form.gmaps4rails_list.selectedIndex;
47
93
  var filter_value = document.gmaps4rails_form.gmaps4rails_list.options[index].value;
48
94
  create_map(filter_value);
49
- }
95
+ }
96
+
97
+ function gmaps4rails_reset(){
98
+ gmaps4rails_map = new google.maps.Map(document.getElementById('gmaps4rails_map'), {
99
+ zoom: gmaps4rails_map_zoom,
100
+ center: new google.maps.LatLng(gmaps4rails_map_center_lat, gmaps4rails_map_center_long),
101
+ mapTypeId: google.maps.MapTypeId.ROADMAP
102
+ });
103
+ }
104
+
105
+ // max_distance in km
106
+ function filter_distance() {
107
+ var max_distance = parseInt(document.getElementById('gmaps4rails_user_distance').value, 10);
108
+ if (!(max_distance>0 || max_distance<0))
109
+ {
110
+ alert('Please set the max distance');
111
+ }
112
+ else{
113
+ if (gmaps_circle!=null) { gmaps_circle.setMap(null);}
114
+ var myCenter = new google.maps.LatLng(gmaps4rails_ref_lat, gmaps4rails_ref_long);
115
+ var filtered_markers = {"markers":[]};
116
+
117
+
118
+ for (var i = 0; i < gmaps4rails_data.markers.length; ++i) {
119
+ if (get_distance(gmaps4rails_ref_long, gmaps4rails_data.markers[i].longitude, gmaps4rails_ref_lat, gmaps4rails_data.markers[i].latitude) < max_distance)
120
+ { filtered_markers.markers.push(gmaps4rails_data.markers[i]);}
121
+ setMarkers(filtered_markers);
122
+ }
123
+ //radius is in meters
124
+ gmaps_circle = new google.maps.Circle({radius: max_distance*1000, center: myCenter, fillColor:"#00FF00", strokeColor: "#00EE00"});
125
+ gmaps_circle.setMap(gmaps4rails_map);
126
+ }
127
+ }
128
+
129
+ function get_distance(long1, long2, lat1, lat2) {
130
+ var theta = long1 - long2;
131
+ var dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
132
+ dist = Math.acos(dist);
133
+ dist = rad2deg(dist);
134
+ var km = dist * 60 * 1.853;
135
+ return km;
136
+ }
137
+
138
+ function deg2rad(value) { return value*Math.PI/180;}
139
+ function rad2deg(value) { return value*180/Math.PI;}
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmaps4rails
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 11
10
- version: 0.0.11
9
+ - 12
10
+ version: 0.0.12
11
11
  platform: ruby
12
12
  authors:
13
13
  - Benjamin Roth
@@ -15,10 +15,23 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-10 00:00:00 +02:00
18
+ date: 2010-10-16 00:00:00 +02:00
19
19
  default_executable:
20
- dependencies: []
21
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: crack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
22
35
  description: IN HEAVY DEV. Will enable easy display of items (taken from a model) on a Google Map. Uses Javascript API V3.
23
36
  email: apnea.diving.deep@gmail.com
24
37
  executables: []
@@ -31,17 +44,20 @@ files:
31
44
  - app/controllers/gmaps4rails/gmaps_controller.rb
32
45
  - app/helpers/application_helper.rb
33
46
  - app/helpers/gmaps4rails/Gmaps_helper.rb
47
+ - app/views/gmaps4rails/_gmaps4rails.html.erb
34
48
  - app/views/gmaps4rails/_map.html.erb
49
+ - app/views/gmaps4rails/gmaps/index.json.erb
35
50
  - app/views/gmaps4rails/gmaps/index.xml.builder
36
51
  - config/routes.rb
37
52
  - lib/acts_as_gmappable/base.rb
38
53
  - lib/application_helper.rb
39
54
  - lib/engine.rb
40
55
  - lib/gmaps4rails.rb
56
+ - public/images/marker.png
41
57
  - public/javascripts/gmaps4rails.js
42
58
  - README.rdoc
43
59
  has_rdoc: true
44
- homepage: http://github.com/apneadiving/test-for-maps
60
+ homepage: http://github.com/apneadiving/Gmaps4rails
45
61
  licenses: []
46
62
 
47
63
  post_install_message: