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.
@@ -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