gmaps4rails 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,67 +57,19 @@ Done again!
57
57
 
58
58
  == Options
59
59
 
60
- === Add an info window
61
- To add an info window (visible when you click a marker), add this method in your model:
60
+ * Info window
62
61
 
63
- def gmaps4rails_infowindow
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
- Then in your view:
64
+ * Scopes
111
65
 
112
- <%= gmaps4rails_map(@json, { "processing" => 'json' }) %>
66
+ * Create from your own json
113
67
 
114
- Or with options as well:
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 me, you have your say. I hope I'll have time enough to improve it.
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
- "{\"description\": \"#{object.gmaps4rails_infowindow}\",
9
- \"longitude\": \"#{object.gmaps4rails_longitude}\",
10
- \"latitude\": \"#{object.gmaps4rails_latitude}\",
11
- \"picture\": \"#{object.gmaps4rails_marker_picture['picture']}\",
12
- \"width\": \"#{object.gmaps4rails_marker_picture['width']}\",
13
- \"height\": \"#{object.gmaps4rails_marker_picture['height']}\"
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 options = {}
28
- before_save :get_coordinates
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 gmaps4rails_picture
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
@@ -3,8 +3,7 @@ class Array
3
3
  json = "["
4
4
  each do |object|
5
5
  if (!(object.gmaps4rails_latitude == "" || object.gmaps4rails_longitude == ""))
6
- json += Gmaps4rails.create_json(object)
7
- json += ","
6
+ json += Gmaps4rails.create_json(object).to_s
8
7
  end
9
8
  end
10
9
  json.chop!
@@ -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 : 'http://inmotionchiro.com/gmap_plugin/imgs/markers/marker.png',
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
- //test if value passed or use default
80
- var marker_picture = this.locations[i].picture != "" && typeof this.locations[i].picture !== "undefined" ? this.locations[i].picture : this.marker_picture;
81
- var marker_width = this.locations[i].width != "" && typeof this.locations[i].width !== "undefined" ? this.locations[i].width : this.marker_width;
82
- var marker_height = this.locations[i].height != "" && typeof this.locations[i].height !== "undefined" ? this.locations[i].height : this.marker_length;
83
- // Marker sizes are expressed as a Size of X,Y
84
- var image = new google.maps.MarkerImage(marker_picture,
85
- new google.maps.Size(marker_width, marker_height)
86
- );
87
- var myLatLng = new google.maps.LatLng(this.locations[i].latitude, this.locations[i].longitude);
88
- var ThisMarker = new google.maps.Marker({position: myLatLng, map: this.map, icon: image}); //TODO Offer title customization title: "title"
89
- //save object for later use, basically, to get back the text to display when clicking it
90
- this.locations[i].marker_object = ThisMarker;
91
- //save the marker again in a list for the clusterer
92
- markers.push(ThisMarker);
93
- //add click listener
94
- google.maps.event.addListener(Gmaps4Rails.locations[i].marker_object, 'click', function() { if (Gmaps4Rails.info_window!=null) {Gmaps4Rails.info_window.close();}; Gmaps4Rails.getInfoWindow(this);});
95
- }
96
- if (this.do_clustering == true)
97
- {
98
- this.markerClusterer = new MarkerClusterer(this.map, markers, {
99
- maxZoom: this.clusterer_maxZoom,
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: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 5
10
- version: 0.2.5
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-15 00:00:00 +01:00
19
+ date: 2011-02-16 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency