gmaps4rails 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -54
- data/lib/acts_as_gmappable/base.rb +84 -45
- data/lib/array.rb +1 -2
- data/public/javascripts/gmaps4rails.js +33 -28
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -57,67 +57,19 @@ Done again!
|
|
57
57
|
|
58
58
|
== Options
|
59
59
|
|
60
|
-
|
61
|
-
To add an info window (visible when you click a marker), add this method in your model:
|
60
|
+
* Info window
|
62
61
|
|
63
|
-
|
64
|
-
# add here whatever html content you desire, it will be displayed when users clicks on the marker
|
65
|
-
end
|
66
|
-
|
67
|
-
=== List of Options
|
68
|
-
You can customize the following:
|
69
|
-
|
70
|
-
processing: 'rails_model', //or 'json'
|
71
|
-
marker_picture : 'http://www.mbs.edu/i/gmap_marker_default.gif,
|
72
|
-
model_scope : null,
|
73
|
-
marker_width : 22,
|
74
|
-
marker_length : 32,
|
75
|
-
map_center_latitude : 0,
|
76
|
-
map_center_longitude : 0,
|
77
|
-
map_zoom : 1,
|
78
|
-
do_clustering: true,
|
79
|
-
clusterer_gridSize: 50,
|
80
|
-
clusterer_maxZoom: 10
|
81
|
-
|
82
|
-
=== How to set your own options
|
83
|
-
Change the call in your view this way and add an additional hash containing the options you want:
|
84
|
-
<%= gmaps4rails_map("User", {"map_center_longitude" => "90", "do_clustering" => false}) %>
|
85
|
-
|
86
|
-
=== Scopes (displays a dropdown list enabling you to filter the map content)
|
87
|
-
Note that you can pass a model_scope in the options to filter the data you want to be displayed.
|
88
|
-
So as above, change the call in your view:
|
89
|
-
|
90
|
-
<%= gmaps4rails_map("User", {"model_scope" => "my_scope"}) %>
|
91
|
-
|
92
|
-
In this case, you must add in your model:
|
93
|
-
|
94
|
-
def self.gmaps4rails_trusted_scopes
|
95
|
-
["my_scope", "another_trusted_scope"]
|
96
|
-
end
|
97
|
-
|
98
|
-
Why? because you shall never trust the params, so it's a way to keep control.
|
99
|
-
|
100
|
-
=== Create from your own json
|
101
|
-
If you want to use your own json to initialize the map, create your json with the following attributes
|
102
|
-
|
103
|
-
@json = '[
|
104
|
-
{"description": "", "longitude": "", "latitude": "", "picture": "", "width": "", "height": ""},
|
105
|
-
{"longitude": "", "latitude": "" }
|
106
|
-
]'
|
107
|
-
|
108
|
-
Only `latitude` and `longitude` are mandatory. But you can customize any single marker.
|
62
|
+
* Custom Marker
|
109
63
|
|
110
|
-
|
64
|
+
* Scopes
|
111
65
|
|
112
|
-
|
66
|
+
* Create from your own json
|
113
67
|
|
114
|
-
|
115
|
-
|
116
|
-
<%= gmaps4rails_map(@json, {"processing" => 'json', "map_center_longitude" => "90"}) %>
|
68
|
+
{More details in the Wiki}[https://github.com/apneadiving/Google-Maps-for-Rails/wiki]
|
117
69
|
|
118
70
|
== Todo?
|
119
71
|
|
120
|
-
Feel free ton contact
|
72
|
+
Feel free ton contact us, you have your say. I hope I'll have time enough to improve it.
|
121
73
|
|
122
74
|
== Copyright
|
123
75
|
MIT license. Authors: Benjamin Roth, David Ruyer
|
@@ -1,19 +1,61 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'uri'
|
3
3
|
require 'crack'
|
4
|
+
require 'logger'
|
4
5
|
|
5
6
|
module Gmaps4rails
|
6
7
|
|
8
|
+
class GeocodeStatus < StandardError; end
|
9
|
+
class GeocodeNetStatus < StandardError; end
|
10
|
+
|
7
11
|
def Gmaps4rails.create_json(object)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
unless object.gmaps4rails_latitude.nil? && object.gmaps4rails_longitude.nil?
|
13
|
+
"{\"description\": \"#{object.gmaps4rails_infowindow}\",
|
14
|
+
\"longitude\": \"#{object.gmaps4rails_longitude}\",
|
15
|
+
\"latitude\": \"#{object.gmaps4rails_latitude}\",
|
16
|
+
\"picture\": \"#{object.gmaps4rails_marker_picture['picture']}\",
|
17
|
+
\"width\": \"#{object.gmaps4rails_marker_picture['width']}\",
|
18
|
+
\"height\": \"#{object.gmaps4rails_marker_picture['height']}\"
|
19
|
+
} ,"
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
23
|
+
def Gmaps4rails.geocode(address)
|
24
|
+
if address.nil? || address.empty?
|
25
|
+
else #coordinates are valid
|
26
|
+
geocoder = "http://maps.googleapis.com/maps/api/geocode/json?address="
|
27
|
+
output = "&sensor=false"
|
28
|
+
#send request to the google api to get the lat/lng
|
29
|
+
request = geocoder + address + output
|
30
|
+
url = URI.escape(request)
|
31
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
32
|
+
#parse result if result received properly
|
33
|
+
if resp.is_a?(Net::HTTPSuccess)
|
34
|
+
#parse the json
|
35
|
+
parse = Crack::JSON.parse(resp.body)
|
36
|
+
#logger.debug "Google geocoding. Address: #{address}. Result: #{resp.body}"
|
37
|
+
#check if google went well
|
38
|
+
if parse["status"] == "OK"
|
39
|
+
array = []
|
40
|
+
parse["results"].each do |result|
|
41
|
+
array << { :lat => result["geometry"]["location"]["lat"],
|
42
|
+
:lng => result["geometry"]["location"]["lng"],
|
43
|
+
:matched_address => result["formatted_address"] }
|
44
|
+
end
|
45
|
+
return array
|
46
|
+
else #status != OK
|
47
|
+
raise Gmaps4rails::GeocodeStatus, "The adress you passed seems invalid, status was: #{parse["status"]}.
|
48
|
+
Request was: #{request}"
|
49
|
+
end #end parse status
|
50
|
+
|
51
|
+
else #if not http success
|
52
|
+
raise Gmaps4rails::GeocodeNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
53
|
+
Response was: #{resp}"
|
54
|
+
end #end resp test
|
55
|
+
|
56
|
+
end # end address valid
|
57
|
+
end #end process_geocoding
|
58
|
+
|
17
59
|
module ActsAsGmappable
|
18
60
|
|
19
61
|
module Base
|
@@ -24,8 +66,23 @@ module Gmaps4rails
|
|
24
66
|
end
|
25
67
|
|
26
68
|
module Config
|
27
|
-
def acts_as_gmappable
|
28
|
-
|
69
|
+
def acts_as_gmappable args = {}
|
70
|
+
unless args[:process_geocoding] == false
|
71
|
+
validate :process_geocoding
|
72
|
+
end
|
73
|
+
|
74
|
+
define_method "gmaps4rails_options" do
|
75
|
+
{
|
76
|
+
:lat_column => args[:lat] || "gmaps4rails_latitude",
|
77
|
+
:lng_column => args[:lng] || "gmaps4rails_longitude",
|
78
|
+
:check_process => args[:check_process] || true,
|
79
|
+
:checker => args[:checker] || "gmaps",
|
80
|
+
:msg => args[:msg] || "Address invalid",
|
81
|
+
:validation => args[:validation] || true
|
82
|
+
#TODO: address as a proc?
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
29
86
|
include Gmaps4rails::ActsAsGmappable::Base::InstanceMethods
|
30
87
|
end
|
31
88
|
end
|
@@ -33,11 +90,23 @@ module Gmaps4rails
|
|
33
90
|
module InstanceMethods
|
34
91
|
|
35
92
|
def gmaps4rails_infowindow
|
36
|
-
self.gmaps4rails_picture.blank? ? "" : "<img width='40' heigth='40' src='" + self.gmaps4rails_picture + "'>"
|
37
93
|
end
|
38
94
|
|
39
|
-
def
|
40
|
-
|
95
|
+
def process_geocoding
|
96
|
+
begin
|
97
|
+
coordinates = Gmaps4rails.geocode(self.gmaps4rails_address)
|
98
|
+
rescue GeocodeStatus #adress was invalid, add error to base.
|
99
|
+
errors[:base] << gmaps4rails_options[:msg] if gmaps4rails_options[:validation]
|
100
|
+
rescue GeocodeNetStatus => e #connection error, No need to prevent save.
|
101
|
+
logger.warn(e)
|
102
|
+
#TODO add customization here?
|
103
|
+
else #if no exception
|
104
|
+
self[gmaps4rails_options[:lng_column]] = coordinates.first[:lng]
|
105
|
+
self[gmaps4rails_options[:lat_column]] = coordinates.first[:lat]
|
106
|
+
if gmaps4rails_options[:check_process] = true
|
107
|
+
self[gmaps4rails_options[:checker]] = true
|
108
|
+
end
|
109
|
+
end
|
41
110
|
end
|
42
111
|
|
43
112
|
def gmaps4rails_marker_picture
|
@@ -55,42 +124,12 @@ module Gmaps4rails
|
|
55
124
|
def to_gmaps4rails
|
56
125
|
json = "["
|
57
126
|
if (!(self.gmaps4rails_latitude == "" || self.gmaps4rails_longitude == ""))
|
58
|
-
json += Gmaps4rails.create_json(self)
|
59
|
-
json += ","
|
127
|
+
json += Gmaps4rails.create_json(self).to_s
|
60
128
|
end
|
61
|
-
json.chop!
|
129
|
+
json.chop! #removes the extra comma
|
62
130
|
json += "]"
|
63
131
|
end
|
64
|
-
|
65
|
-
def get_coordinates
|
66
|
-
if self.gmaps4rails_address.nil? || self.gmaps4rails_address.empty?
|
67
|
-
self.gmaps = false
|
68
|
-
else
|
69
|
-
geocoder = "http://maps.googleapis.com/maps/api/geocode/json?address="
|
70
|
-
output = "&sensor=false"
|
71
|
-
#send request to the google api to get the lat/lng
|
72
|
-
request = geocoder + self.gmaps4rails_address + output
|
73
|
-
url = URI.escape(request)
|
74
|
-
resp = Net::HTTP.get_response(URI.parse(url))
|
75
|
-
#parse result if result received properly
|
76
|
-
if resp.inspect.include?('HTTPOK 200 OK')
|
77
|
-
#parse the json
|
78
|
-
parse = Crack::JSON.parse(resp.body)
|
79
|
-
#check if google went well
|
80
|
-
if parse["status"] == "OK"
|
81
|
-
#TODO maybe handle case when there are many results
|
82
|
-
#TODO store the country name and maybe other details?
|
83
|
-
self.gmaps4rails_latitude = parse["results"].first["geometry"]["location"]["lat"]
|
84
|
-
self.gmaps4rails_longitude = parse["results"].first["geometry"]["location"]["lng"]
|
85
|
-
#saves a boolean to remind the status
|
86
|
-
self.gmaps = true
|
87
|
-
end
|
88
|
-
else
|
89
|
-
self.gmaps = false
|
90
|
-
end
|
91
|
-
end
|
92
|
-
return true
|
93
|
-
end
|
132
|
+
|
94
133
|
end # InstanceMethods
|
95
134
|
end
|
96
135
|
end
|
data/lib/array.rb
CHANGED
@@ -3,7 +3,7 @@ google.load('maps', '3', { other_params: 'sensor=false' });
|
|
3
3
|
var Gmaps4Rails = {
|
4
4
|
processing: 'rails_model',
|
5
5
|
map: null,
|
6
|
-
marker_picture :
|
6
|
+
marker_picture : "",
|
7
7
|
marker_width : 22,
|
8
8
|
marker_length : 32,
|
9
9
|
map_center_latitude : 0,
|
@@ -75,32 +75,28 @@ var Gmaps4Rails = {
|
|
75
75
|
}
|
76
76
|
// Add markers to the map
|
77
77
|
for (var i = 0; i < this.locations.length; ++i) {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
gridSize: this.clusterer_gridSize,
|
101
|
-
//styles: styles TODO: offer clusterer customization
|
102
|
-
});
|
103
|
-
}
|
78
|
+
//test if value passed or use default
|
79
|
+
var marker_picture = this.locations[i].picture != "" && typeof this.locations[i].picture !== "undefined" ? this.locations[i].picture : this.marker_picture;
|
80
|
+
var marker_width = this.locations[i].width != "" && typeof this.locations[i].width !== "undefined" ? this.locations[i].width : this.marker_width;
|
81
|
+
var marker_height = this.locations[i].height != "" && typeof this.locations[i].height !== "undefined" ? this.locations[i].height : this.marker_length;
|
82
|
+
var myLatLng = new google.maps.LatLng(this.locations[i].latitude, this.locations[i].longitude);
|
83
|
+
|
84
|
+
// Marker sizes are expressed as a Size of X,Y
|
85
|
+
if (marker_picture == "")
|
86
|
+
{ var ThisMarker = new google.maps.Marker({position: myLatLng, map: this.map}); }
|
87
|
+
else
|
88
|
+
{
|
89
|
+
var image = new google.maps.MarkerImage(marker_picture, new google.maps.Size(marker_width, marker_height) );
|
90
|
+
var ThisMarker = new google.maps.Marker({position: myLatLng, map: this.map, icon: image}); //TODO Offer title customization title: "title"
|
91
|
+
}
|
92
|
+
//save object for later use, basically, to get back the text to display when clicking it
|
93
|
+
this.locations[i].marker_object = ThisMarker;
|
94
|
+
//save the marker again in a list for the clusterer
|
95
|
+
markers.push(ThisMarker);
|
96
|
+
//add click listener
|
97
|
+
google.maps.event.addListener(Gmaps4Rails.locations[i].marker_object, 'click', function() { if (Gmaps4Rails.info_window!=null) {Gmaps4Rails.info_window.close();}; Gmaps4Rails.getInfoWindow(this);});
|
98
|
+
}
|
99
|
+
this.setup_Clusterer(markers);
|
104
100
|
},
|
105
101
|
|
106
102
|
//get info_window content when listener calls it
|
@@ -116,6 +112,15 @@ var Gmaps4Rails = {
|
|
116
112
|
return;
|
117
113
|
}
|
118
114
|
}
|
115
|
+
},
|
116
|
+
setup_Clusterer: function(markers)
|
117
|
+
{
|
118
|
+
if (this.do_clustering == true)
|
119
|
+
{
|
120
|
+
this.markerClusterer = new MarkerClusterer(this.map, markers, { maxZoom: this.clusterer_maxZoom,
|
121
|
+
gridSize: this.clusterer_gridSize,
|
122
|
+
//styles: styles TODO: offer clusterer customization
|
123
|
+
});
|
124
|
+
}
|
119
125
|
}
|
120
|
-
|
121
126
|
};
|
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 6
|
10
|
+
version: 0.2.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Benjamin Roth
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-02-
|
19
|
+
date: 2011-02-16 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|