gmaps4rails 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|