gmaps4rails 1.3.2 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/gmaps4rails/gmaps4rails.base.js.coffee +22 -5
- data/app/assets/javascripts/gmaps4rails/gmaps4rails.googlemaps.js.coffee +1 -2
- data/lib/gmaps4rails.rb +10 -5
- data/lib/gmaps4rails/acts_as_gmappable.rb +6 -19
- data/lib/gmaps4rails/base.rb +43 -315
- data/lib/gmaps4rails/extensions/array.rb +5 -4
- data/lib/gmaps4rails/geocoding.rb +115 -0
- data/lib/gmaps4rails/google_places.rb +76 -0
- data/lib/gmaps4rails/js_handler.rb +113 -0
- data/lib/gmaps4rails/json_handler.rb +111 -0
- data/public/javascripts/gmaps4rails/gmaps4rails.googlemaps.js +3 -2
- metadata +10 -6
@@ -217,14 +217,32 @@ class @Gmaps4Rails
|
|
217
217
|
fillColor: fillColor
|
218
218
|
fillOpacity: fillOpacity
|
219
219
|
clickable: false
|
220
|
+
map: @map
|
220
221
|
|
221
222
|
#save polygon in list
|
222
223
|
polygon.serviceObject = new_poly
|
223
|
-
new_poly.setMap(@map)
|
224
224
|
|
225
225
|
#////////////////////////////////////////////////////
|
226
226
|
#/////////////////// POLYLINES //////////////////////
|
227
227
|
#////////////////////////////////////////////////////
|
228
|
+
|
229
|
+
#replace old markers with new markers on an existing map
|
230
|
+
replacePolylines : (new_polylines) ->
|
231
|
+
#reset previous polylines and kill them from map
|
232
|
+
@destroy_polylines()
|
233
|
+
#set new polylines
|
234
|
+
@polylines = new_polylines
|
235
|
+
#create
|
236
|
+
@create_polylines()
|
237
|
+
#.... and adjust map boundaries
|
238
|
+
@adjustMapToBounds()
|
239
|
+
|
240
|
+
destroy_polylines : ->
|
241
|
+
for polyline in @polylines
|
242
|
+
#delete polylines from map
|
243
|
+
polyline.serviceObject.setMap(null)
|
244
|
+
#empty array
|
245
|
+
@polylines = []
|
228
246
|
|
229
247
|
#polylines is an array of arrays. It loops.
|
230
248
|
create_polylines : ->
|
@@ -382,9 +400,8 @@ class @Gmaps4Rails
|
|
382
400
|
|
383
401
|
#to make the map fit the different LatLng points
|
384
402
|
adjustMapToBounds : ->
|
385
|
-
|
386
403
|
#FIRST_STEP: retrieve all bounds
|
387
|
-
#create the bounds object only if necessary
|
404
|
+
#create the bounds object only if necessary
|
388
405
|
if @map_options.auto_adjust or @map_options.bounds isnt null
|
389
406
|
@boundsObject = @createLatLngBounds()
|
390
407
|
|
@@ -426,9 +443,9 @@ class @Gmaps4Rails
|
|
426
443
|
@map_options.center_latitude = map_center.lat()
|
427
444
|
@map_options.center_longitude = map_center.lng()
|
428
445
|
@map.setCenter(map_center)
|
429
|
-
else
|
446
|
+
else
|
430
447
|
@fitBounds()
|
431
|
-
|
448
|
+
|
432
449
|
#////////////////////////////////////////////////////
|
433
450
|
#///////////////// KML //////////////////
|
434
451
|
#////////////////////////////////////////////////////
|
@@ -171,7 +171,6 @@ class @Gmaps4RailsGoogle extends Gmaps4Rails
|
|
171
171
|
@hideMarker marker
|
172
172
|
|
173
173
|
clearMarker : (marker) ->
|
174
|
-
console.log marker
|
175
174
|
marker.serviceObject.setMap(null)
|
176
175
|
|
177
176
|
showMarker : (marker) ->
|
@@ -253,7 +252,7 @@ class @Gmaps4RailsGoogle extends Gmaps4Rails
|
|
253
252
|
#////////////////////////////////////////////////////
|
254
253
|
|
255
254
|
fitBounds : ->
|
256
|
-
@map.fitBounds(@boundsObject)
|
255
|
+
@map.fitBounds(@boundsObject) unless @boundsObject.isEmpty()
|
257
256
|
|
258
257
|
centerMapOnUser : ->
|
259
258
|
@map.setCenter(@userLocation)
|
data/lib/gmaps4rails.rb
CHANGED
@@ -2,15 +2,13 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
|
2
2
|
module Gmaps4rails
|
3
3
|
require 'rails'
|
4
4
|
require 'gmaps4rails/base'
|
5
|
-
require 'gmaps4rails/acts_as_gmappable'
|
6
|
-
require 'gmaps4rails/extensions/array'
|
7
|
-
require 'gmaps4rails/extensions/hash'
|
8
|
-
require 'gmaps4rails/helper/gmaps4rails_helper'
|
9
5
|
|
10
6
|
class Engine < Rails::Engine
|
7
|
+
|
11
8
|
initializer "gmaps4rails view helpers" do |app|
|
12
9
|
ActionView::Base.send :include, Gmaps4railsHelper
|
13
10
|
end
|
11
|
+
|
14
12
|
initializer "add asset directories to pipeline" do |app|
|
15
13
|
if Rails::VERSION::MINOR >= 1
|
16
14
|
app.config.assets.paths << "#{root}/public/stylesheets"
|
@@ -18,7 +16,14 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
|
18
16
|
app.middleware.use ::ActionDispatch::Static, "#{root}/public"
|
19
17
|
end
|
20
18
|
end
|
19
|
+
|
20
|
+
initializer "include acts_as_gmappable within ActiveRecord" do
|
21
|
+
if defined?(::ActiveRecord::Base)
|
22
|
+
ActiveRecord::Base.send(:include, Gmaps4rails::ActsAsGmappable::InstanceMethods)
|
23
|
+
ActiveRecord::Base.send(:extend, Gmaps4rails::ActsAsGmappable::ClassMethods)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
21
27
|
end
|
22
|
-
|
23
28
|
end
|
24
29
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Gmaps4rails
|
2
2
|
module ActsAsGmappable
|
3
3
|
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
4
|
module InstanceMethods
|
7
5
|
|
8
6
|
# This is a before_filter to trigger the geocoding and save its results
|
@@ -13,9 +11,9 @@ module Gmaps4rails
|
|
13
11
|
#try to geocode
|
14
12
|
begin
|
15
13
|
coordinates = Gmaps4rails.geocode(self.send(gmaps4rails_options[:address]), gmaps4rails_options[:language], false, gmaps4rails_options[:protocol])
|
16
|
-
rescue GeocodeStatus, GeocodeInvalidQuery => e #address was invalid, add error to
|
14
|
+
rescue GeocodeStatus, GeocodeInvalidQuery => e #address was invalid, add error to address.
|
17
15
|
Rails.logger.warn(e)
|
18
|
-
errors[gmaps4rails_options[:address]] << gmaps4rails_options[:msg] if gmaps4rails_options[:validation]
|
16
|
+
errors[gmaps4rails_options[:address]] << gmaps4rails_options[:msg] if Gmaps4rails.condition_eval(self, gmaps4rails_options[:validation])
|
19
17
|
rescue GeocodeNetStatus => e #connection error, No need to prevent save.
|
20
18
|
Rails.logger.warn(e)
|
21
19
|
#TODO add customization here?
|
@@ -27,7 +25,7 @@ module Gmaps4rails
|
|
27
25
|
end
|
28
26
|
# Call the callback method to let the user do what he wants with the data
|
29
27
|
self.send(gmaps4rails_options[:callback], coordinates.first[:full_data]) unless gmaps4rails_options[:callback].nil?
|
30
|
-
if gmaps4rails_options[:check_process]
|
28
|
+
if Gmaps4rails.condition_eval(self, gmaps4rails_options[:check_process])
|
31
29
|
self[gmaps4rails_options[:checker]] = true
|
32
30
|
end
|
33
31
|
end
|
@@ -35,7 +33,7 @@ module Gmaps4rails
|
|
35
33
|
|
36
34
|
def to_gmaps4rails(&block)
|
37
35
|
json = "["
|
38
|
-
json << Gmaps4rails.create_json(self, &block)
|
36
|
+
json << Gmaps4rails.create_json(self, &block) #removes the extra comma
|
39
37
|
json << "]"
|
40
38
|
end
|
41
39
|
|
@@ -67,20 +65,9 @@ module Gmaps4rails
|
|
67
65
|
:protocol => args[:protocol] || "http"
|
68
66
|
}
|
69
67
|
end
|
70
|
-
|
71
|
-
include InstanceMethods
|
72
|
-
|
68
|
+
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
76
72
|
end #ActsAsGmappable
|
77
|
-
end
|
78
|
-
|
79
|
-
ActiveSupport.on_load(:active_record) do
|
80
|
-
ActiveRecord::Base.send(:include, Gmaps4rails::ActsAsGmappable)
|
81
|
-
end
|
82
|
-
|
83
|
-
#::ActiveRecord::Base.send :include, Gmaps4rails::ActsAsGmappable
|
84
|
-
# Mongoid::Document::ClassMethods.class_eval do
|
85
|
-
# include Gmaps4rails::ActsAsGmappable::Base
|
86
|
-
# end
|
73
|
+
end
|
data/lib/gmaps4rails/base.rb
CHANGED
@@ -1,335 +1,63 @@
|
|
1
|
-
require '
|
2
|
-
require 'uri'
|
3
|
-
require 'crack'
|
1
|
+
require 'gmaps4rails/acts_as_gmappable'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
class DirectionStatus < StandardError; end
|
12
|
-
class DirectionNetStatus < StandardError; end
|
13
|
-
class DirectionInvalidQuery < StandardError; end
|
3
|
+
require 'gmaps4rails/js_handler'
|
4
|
+
require 'gmaps4rails/json_handler'
|
5
|
+
require 'gmaps4rails/geocoding'
|
6
|
+
require 'gmaps4rails/google_places'
|
7
|
+
require 'gmaps4rails/extensions/array'
|
8
|
+
require 'gmaps4rails/extensions/hash'
|
14
9
|
|
15
|
-
|
16
|
-
# This json will contian the marker's attributes of the object
|
17
|
-
mattr_accessor :json_from_block
|
10
|
+
require 'gmaps4rails/helper/gmaps4rails_helper'
|
18
11
|
|
19
|
-
|
20
|
-
@json_from_block = String.new
|
21
|
-
unless object.send(object.gmaps4rails_options[:lat_column]).blank? && object.send(object.gmaps4rails_options[:lng_column]).blank?
|
22
|
-
Gmaps4rails.block_handling(object, &block)
|
23
|
-
"{#{description(object)}#{get_title(object)}#{get_sidebar(object)}#{marker_picture(object)}#{@json_from_block}\"lng\": \"#{object.send(object.gmaps4rails_options[:lng_column])}\", \"lat\": \"#{object.send(object.gmaps4rails_options[:lat_column])}\"},\n"
|
24
|
-
end
|
25
|
-
end
|
12
|
+
module Gmaps4rails
|
26
13
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Gmaps4rails.json(block_result) if block_result.is_a? String
|
31
|
-
end
|
32
|
-
|
33
|
-
def Gmaps4rails.json(string)
|
34
|
-
@json_from_block << "#{gsub_string(string)}, "
|
35
|
-
return true
|
36
|
-
end
|
37
|
-
|
38
|
-
################################################
|
39
|
-
# in use to create json from model
|
40
|
-
def Gmaps4rails.marker_picture(object)
|
41
|
-
create_js_for_picture object.gmaps4rails_marker_picture if object.respond_to?("gmaps4rails_marker_picture")
|
42
|
-
end
|
43
|
-
|
44
|
-
# in use in block
|
45
|
-
def Gmaps4rails.picture(hash)
|
46
|
-
@json_from_block << (create_js_for_picture hash)
|
47
|
-
return true
|
48
|
-
end
|
49
|
-
|
50
|
-
# Returns picture js from a hash
|
51
|
-
def Gmaps4rails.create_js_for_picture(raw_hash)
|
52
|
-
hash = raw_hash.with_indifferent_access
|
53
|
-
result = hash.map do |k,v|
|
54
|
-
#specific case, anchors are array and should be interpreted this way
|
55
|
-
if k.include? "_anchor"
|
56
|
-
"\"#{k}\": [#{v[0]}, #{v[1]}]"
|
57
|
-
else
|
58
|
-
"\"#{k}\": \"#{v}\""
|
59
|
-
end
|
60
|
-
end.join(", ") + ", "
|
61
|
-
end
|
62
|
-
##################################################
|
63
|
-
# in use in block
|
64
|
-
def Gmaps4rails.infowindow(string)
|
65
|
-
@json_from_block << (create_js_for_infowindow string)
|
66
|
-
return true
|
67
|
-
end
|
14
|
+
class GeocodeStatus < StandardError; end
|
15
|
+
class GeocodeNetStatus < StandardError; end
|
16
|
+
class GeocodeInvalidQuery < StandardError; end
|
68
17
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
def Gmaps4rails.create_js_for_infowindow(string)
|
75
|
-
"\"description\": \"#{gsub_string(string)}\", "
|
76
|
-
end
|
77
|
-
|
78
|
-
##################################################
|
79
|
-
# in use in block
|
80
|
-
def Gmaps4rails.title(string)
|
81
|
-
create_js_for_title string
|
82
|
-
end
|
83
|
-
|
84
|
-
# in use to create json from model
|
85
|
-
def Gmaps4rails.get_title(object)
|
86
|
-
create_js_for_title object.gmaps4rails_title if object.respond_to?("gmaps4rails_title")
|
87
|
-
end
|
18
|
+
class DirectionStatus < StandardError; end
|
19
|
+
class DirectionNetStatus < StandardError; end
|
20
|
+
class DirectionInvalidQuery < StandardError; end
|
88
21
|
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
##################################################
|
22
|
+
class PlacesStatus < StandardError; end
|
23
|
+
class PlacesNetStatus < StandardError; end
|
24
|
+
class PlacesInvalidQuery < StandardError; end
|
93
25
|
|
94
|
-
|
95
|
-
def Gmaps4rails.sidebar(string)
|
96
|
-
create_js_for_sidebar string
|
97
|
-
end
|
26
|
+
mattr_accessor :http_proxy
|
98
27
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
##################################################
|
108
|
-
|
109
|
-
|
110
|
-
def Gmaps4rails.gsub_string(string)
|
111
|
-
string #you could do override with something like: string.gsub(/\n/, '').gsub(/"/, '\"')
|
112
|
-
end
|
113
|
-
|
114
|
-
# This method geocodes an address using the GoogleMaps webservice
|
115
|
-
# options are:
|
116
|
-
# * address: string, mandatory
|
117
|
-
# * lang: to set the language one wants the result to be translated (default is english)
|
118
|
-
# * raw: to get the raw response from google, default is false
|
119
|
-
def Gmaps4rails.geocode(address, lang="en", raw = false, protocol = "http")
|
120
|
-
if address.nil? || address.empty?
|
121
|
-
raise Gmaps4rails::GeocodeInvalidQuery, "You must provide an address"
|
122
|
-
else #coordinates are valid
|
123
|
-
geocoder = "#{protocol}://maps.googleapis.com/maps/api/geocode/json?language=#{lang}&address="
|
124
|
-
output = "&sensor=false"
|
125
|
-
#send request to the google api to get the lat/lng
|
126
|
-
request = geocoder + address + output
|
127
|
-
url = URI.escape(request)
|
128
|
-
Gmaps4rails.handle_geocoding_response(request, Net::HTTP.get_response(URI.parse(url)), raw)
|
129
|
-
end # end address valid
|
28
|
+
def Gmaps4rails.condition_eval(object, condition)
|
29
|
+
case condition
|
30
|
+
when Symbol then object.send condition
|
31
|
+
when Proc then condition.call(object)
|
32
|
+
when TrueClass then condition
|
33
|
+
when FalseClass then condition
|
34
|
+
end
|
130
35
|
end
|
131
36
|
|
132
|
-
|
133
|
-
# options are:
|
134
|
-
# * start_end: Hash { "from" => string, "to" => string}, mandatory
|
135
|
-
# * options: details given in the github's wiki
|
136
|
-
# * output: could be "pretty", "raw" or "clean"; filters the output from google
|
137
|
-
#output could be raw, pretty or clean
|
138
|
-
def Gmaps4rails.destination(start_end, options={}, output="pretty")
|
139
|
-
if start_end["from"].nil? || start_end["to"].empty?
|
140
|
-
raise Gmaps4rails::DirectionInvalidQuery, "Origin and destination must be provided in a hash as first argument"
|
141
|
-
else #great, we have stuff to work with
|
142
|
-
geocoder = "http://maps.googleapis.com/maps/api/directions/json?origin=#{start_end["from"]}&destination=#{start_end["to"]}"
|
143
|
-
#if value is an Array, it means it contains the waypoints, otherwise it's chained normally
|
144
|
-
dest_options = options.empty? ? "" : "&" + options.map {|k,v| v.is_a?(Array) ? k + "=" + v * ("|") : k + "=" + v }*("&")
|
145
|
-
#send request to the google api to get the directions
|
146
|
-
request = geocoder + dest_options + "&sensor=false"
|
147
|
-
url = URI.escape(request)
|
148
|
-
Gmaps4rails.handle_destination_response(request, Net::HTTP.get_response(URI.parse(url)), output)
|
149
|
-
end # end origin + destination exist
|
150
|
-
end #end destination
|
37
|
+
private
|
151
38
|
|
152
39
|
# To create valid js, this method escapes everything but Numeric, true or false
|
153
40
|
def Gmaps4rails.filter(data)
|
154
|
-
|
155
|
-
"'#{data}'"
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
|
160
|
-
def Gmaps4rails.handle_geocoding_response(request, response, raw)
|
161
|
-
#parse result if result received properly
|
162
|
-
if response.is_a?(Net::HTTPSuccess)
|
163
|
-
#parse the json
|
164
|
-
parse = Crack::JSON.parse(response.body)
|
165
|
-
#check if google went well
|
166
|
-
if parse["status"] == "OK"
|
167
|
-
return parse if raw == true
|
168
|
-
array = []
|
169
|
-
parse["results"].each do |result|
|
170
|
-
array << {
|
171
|
-
:lat => result["geometry"]["location"]["lat"],
|
172
|
-
:lng => result["geometry"]["location"]["lng"],
|
173
|
-
:matched_address => result["formatted_address"],
|
174
|
-
:bounds => result["geometry"]["bounds"],
|
175
|
-
:full_data => result
|
176
|
-
}
|
177
|
-
end
|
178
|
-
return array
|
179
|
-
else #status != OK
|
180
|
-
raise Gmaps4rails::GeocodeStatus, "The address you passed seems invalid, status was: #{parse["status"]}.
|
181
|
-
Request was: #{request}"
|
182
|
-
end #end parse status
|
183
|
-
|
184
|
-
else #if not http success
|
185
|
-
raise Gmaps4rails::GeocodeNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
186
|
-
Response was: #{response}"
|
187
|
-
end #end resp test
|
188
|
-
end
|
189
|
-
|
190
|
-
def Gmaps4rails.handle_destination_response(request, response, output)
|
191
|
-
if response.is_a?(Net::HTTPSuccess)
|
192
|
-
#parse the json
|
193
|
-
parse = Crack::JSON.parse(response.body)
|
194
|
-
#check if google went well
|
195
|
-
if parse["status"] == "OK"
|
196
|
-
legs = []
|
197
|
-
#Each element in the legs array specifies a single leg of the journey from the origin to the destination in the calculated route
|
198
|
-
parse["routes"].first["legs"].each do |leg|
|
199
|
-
#delete coded polyline elements from legs and store it in polylines to make output cleaner
|
200
|
-
polylines = leg["steps"].map {|step| step.delete("polyline")} if output == "pretty" || output == "clean"
|
201
|
-
legs << {
|
202
|
-
"duration" => { "text" => leg["duration"]["text"], "value" => leg["duration"]["value"].to_f },
|
203
|
-
"distance" => { "text" => leg["distance"]["text"], "value" => leg["distance"]["value"].to_f },
|
204
|
-
"steps" => leg["steps"]
|
205
|
-
}
|
206
|
-
if output == "pretty"
|
207
|
-
#polylines contain levels data, which are not that useful.
|
208
|
-
polylines.map{|poly| poly.delete("levels")}
|
209
|
-
#create valid json from all polylines, this could be directly passed to javascript for display
|
210
|
-
json = polylines.map { |poly| {"coded_array" => poly["points"]} }.to_json
|
211
|
-
#merge results in legs
|
212
|
-
legs.last.merge!({ "polylines" => json })
|
213
|
-
end
|
214
|
-
end
|
215
|
-
return legs
|
216
|
-
else #status != OK
|
217
|
-
raise Gmaps4rails::DirectionStatus, "The query you passed seems invalid, status was: #{parse["status"]}.
|
218
|
-
Request was: #{request}"
|
219
|
-
end #end parse status
|
220
|
-
else #if not http success
|
221
|
-
raise Gmaps4rails::DirectionNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
222
|
-
Response was: #{response}"
|
223
|
-
end #end resp test
|
224
|
-
end
|
225
|
-
|
226
|
-
###### JS CREATION #######
|
227
|
-
|
228
|
-
def Gmaps4rails.js_function_name(hash)
|
229
|
-
"load_" + Gmaps4rails.get_map_id(hash[:map_options])
|
230
|
-
end
|
231
|
-
|
232
|
-
def Gmaps4rails.get_map_id(hash)
|
233
|
-
hash.nil? || hash[:id].nil? ? DEFAULT_MAP_ID : hash[:id]
|
41
|
+
data.to_json
|
234
42
|
end
|
235
43
|
|
236
|
-
|
237
|
-
|
44
|
+
# get the response from the url encoded address string
|
45
|
+
def Gmaps4rails.get_response(url)
|
46
|
+
url = URI.parse(url)
|
47
|
+
http = Gmaps4rails.http_agent
|
48
|
+
http.get_response(url)
|
238
49
|
end
|
239
50
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
else
|
249
|
-
output << "#{map_id}.map_options.#{option_k} = #{Gmaps4rails.filter option_v};"
|
250
|
-
end
|
251
|
-
end
|
51
|
+
# looks for proxy settings and returns a Net::HTTP or Net::HTTP::Proxy class
|
52
|
+
def Gmaps4rails.http_agent
|
53
|
+
proxy = ENV['HTTP_PROXY'] || ENV['http_proxy'] || self.http_proxy
|
54
|
+
if proxy
|
55
|
+
proxy = URI.parse(proxy)
|
56
|
+
http_agent = Net::HTTP::Proxy(proxy.host,proxy.port)
|
57
|
+
else
|
58
|
+
http_agent = Net::HTTP
|
252
59
|
end
|
253
|
-
|
60
|
+
http_agent
|
254
61
|
end
|
255
62
|
|
256
|
-
|
257
|
-
hash = hash.with_indifferent_access
|
258
|
-
output = Array.new
|
259
|
-
output << "#{map_id}.#{category} = #{hash[:data]};"
|
260
|
-
hash[:options] ||= Array.new
|
261
|
-
hash[:options].each do |option_k, option_v|
|
262
|
-
if option_k.to_sym == :raw
|
263
|
-
output << "#{map_id}.#{category}_conf.#{option_k} = #{option_v};"
|
264
|
-
else
|
265
|
-
output << "#{map_id}.#{category}_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
266
|
-
end
|
267
|
-
end
|
268
|
-
output << "#{map_id}.create_#{category}();"
|
269
|
-
output
|
270
|
-
end
|
271
|
-
|
272
|
-
def Gmaps4rails.create_direction_js(hash, map_id)
|
273
|
-
hash = hash.with_indifferent_access
|
274
|
-
output = Array.new
|
275
|
-
output << "#{map_id}.direction_conf.origin = '#{hash["data"]["from"]}';"
|
276
|
-
output << "#{map_id}.direction_conf.destination = '#{hash["data"]["to"]}';"
|
277
|
-
hash[:options] ||= Array.new
|
278
|
-
hash[:options].each do |option_k, option_v|
|
279
|
-
if option_k.to_sym == :waypoints
|
280
|
-
waypoints = Array.new
|
281
|
-
option_v.each do |waypoint|
|
282
|
-
waypoints << { "location" => waypoint, "stopover" => true }.to_json
|
283
|
-
end
|
284
|
-
output << "#{map_id}.direction_conf.waypoints = [#{waypoints * (",")}];"
|
285
|
-
else #option_k != "waypoint"
|
286
|
-
output << "#{map_id}.direction_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
287
|
-
end
|
288
|
-
end #end .each
|
289
|
-
output << "#{map_id}.create_direction();"
|
290
|
-
output
|
291
|
-
end
|
292
|
-
|
293
|
-
def Gmaps4rails.create_js_from_hash(hash)
|
294
|
-
#the variable 'options' must have the following structure
|
295
|
-
#{
|
296
|
-
# :map_options => hash,
|
297
|
-
# :markers => { :data => json, :options => hash },
|
298
|
-
# :polylines => { :data => json, :options => hash },
|
299
|
-
# :polygons => { :data => json, :options => hash },
|
300
|
-
# :circles => { :data => json, :options => hash },
|
301
|
-
# :direction => { :data => hash, :options => hash },
|
302
|
-
# :kml => { :data => json, :options => hash }
|
303
|
-
#}
|
304
|
-
result = Array.new
|
305
|
-
map_id = "Gmaps." + Gmaps4rails.get_map_id(hash[:map_options])
|
306
|
-
|
307
|
-
#means we are creating a new map
|
308
|
-
result << "#{map_id} = new #{Gmaps4rails.get_constructor hash[:map_options] }" + ";"
|
309
|
-
result << "Gmaps.#{Gmaps4rails.js_function_name hash } = function() {"
|
310
|
-
result << Gmaps4rails.create_map_js(hash[:map_options], map_id) unless hash[:map_options].nil?
|
311
|
-
result << "#{map_id}.initialize();"
|
312
|
-
|
313
|
-
hash.each do |category, content| #loop through options hash
|
314
|
-
skipped_categories = [:map_options, :last_map, :scripts]
|
315
|
-
unless skipped_categories.include? category.to_sym
|
316
|
-
if category.to_sym == :direction
|
317
|
-
result << Gmaps4rails.create_direction_js(content, map_id)
|
318
|
-
else
|
319
|
-
result << Gmaps4rails.create_general_js(content, map_id, category)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
end
|
323
|
-
result << "#{map_id}.adjustMapToBounds();"
|
324
|
-
result << "#{map_id}.callback();"
|
325
|
-
|
326
|
-
result << "};"
|
327
|
-
if hash[:last_map].nil? || hash[:last_map] == true
|
328
|
-
result << "window.onload = function() { Gmaps.loadMaps(); };"
|
329
|
-
end
|
330
|
-
|
331
|
-
result * ('
|
332
|
-
')
|
333
|
-
end
|
334
|
-
|
335
|
-
end
|
63
|
+
end
|
@@ -2,11 +2,12 @@ class Array
|
|
2
2
|
#Scopes on models generate Arrays
|
3
3
|
#this method enables short call to the json creation for all elements in the array
|
4
4
|
def to_gmaps4rails(&block)
|
5
|
-
|
5
|
+
output = "["
|
6
|
+
json_array = []
|
6
7
|
each do |object|
|
7
|
-
|
8
|
+
json_array << Gmaps4rails.create_json(object, &block).to_s
|
8
9
|
end
|
9
|
-
|
10
|
-
|
10
|
+
output << json_array * (",")
|
11
|
+
output << "]"
|
11
12
|
end
|
12
13
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Gmaps4rails
|
6
|
+
|
7
|
+
# This method geocodes an address using the GoogleMaps webservice
|
8
|
+
# options are:
|
9
|
+
# * address: string, mandatory
|
10
|
+
# * lang: to set the language one wants the result to be translated (default is english)
|
11
|
+
# * raw: to get the raw response from google, default is false
|
12
|
+
def Gmaps4rails.geocode(address, lang="en", raw = false, protocol = "http")
|
13
|
+
if address.nil? || address.empty?
|
14
|
+
raise Gmaps4rails::GeocodeInvalidQuery, "You must provide an address"
|
15
|
+
else #coordinates are valid
|
16
|
+
geocoder = "#{protocol}://maps.googleapis.com/maps/api/geocode/json?language=#{lang}&address="
|
17
|
+
output = "&sensor=false"
|
18
|
+
#send request to the google api to get the lat/lng
|
19
|
+
request = geocoder + address + output
|
20
|
+
url = URI.escape(request)
|
21
|
+
Gmaps4rails.handle_geocoding_response(request, Gmaps4rails.get_response(url), raw)
|
22
|
+
end # end address valid
|
23
|
+
end
|
24
|
+
|
25
|
+
# This method retrieves destination results provided by GoogleMaps webservice
|
26
|
+
# options are:
|
27
|
+
# * start_end: Hash { "from" => string, "to" => string}, mandatory
|
28
|
+
# * options: details given in the github's wiki
|
29
|
+
# * output: could be "pretty", "raw" or "clean"; filters the output from google
|
30
|
+
#output could be raw, pretty or clean
|
31
|
+
def Gmaps4rails.destination(start_end, options={}, output="pretty")
|
32
|
+
if start_end["from"].nil? || start_end["to"].empty?
|
33
|
+
raise Gmaps4rails::DirectionInvalidQuery, "Origin and destination must be provided in a hash as first argument"
|
34
|
+
else #great, we have stuff to work with
|
35
|
+
geocoder = "http://maps.googleapis.com/maps/api/directions/json?origin=#{start_end["from"]}&destination=#{start_end["to"]}"
|
36
|
+
#if value is an Array, it means it contains the waypoints, otherwise it's chained normally
|
37
|
+
dest_options = options.empty? ? "" : "&" + options.map {|k,v| v.is_a?(Array) ? k + "=" + v * ("|") : k + "=" + v }*("&")
|
38
|
+
#send request to the google api to get the directions
|
39
|
+
request = geocoder + dest_options + "&sensor=false"
|
40
|
+
url = URI.escape(request)
|
41
|
+
Gmaps4rails.handle_destination_response(request, Gmaps4rails.get_response(url), output)
|
42
|
+
end # end origin + destination exist
|
43
|
+
end #end destination
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def Gmaps4rails.handle_geocoding_response(request, response, raw)
|
48
|
+
#parse result if result received properly
|
49
|
+
if response.is_a?(Net::HTTPSuccess)
|
50
|
+
#parse the json
|
51
|
+
#parse = Crack::JSON.parse(response.body)
|
52
|
+
parse = JSON.parse(response.body)
|
53
|
+
#check if google went well
|
54
|
+
if parse["status"] == "OK"
|
55
|
+
return parse if raw == true
|
56
|
+
array = []
|
57
|
+
parse["results"].each do |result|
|
58
|
+
array << {
|
59
|
+
:lat => result["geometry"]["location"]["lat"],
|
60
|
+
:lng => result["geometry"]["location"]["lng"],
|
61
|
+
:matched_address => result["formatted_address"],
|
62
|
+
:bounds => result["geometry"]["bounds"],
|
63
|
+
:full_data => result
|
64
|
+
}
|
65
|
+
end
|
66
|
+
return array
|
67
|
+
else #status != OK
|
68
|
+
raise Gmaps4rails::GeocodeStatus, "The address you passed seems invalid, status was: #{parse["status"]}.
|
69
|
+
Request was: #{request}"
|
70
|
+
end #end parse status
|
71
|
+
|
72
|
+
else #if not http success
|
73
|
+
raise Gmaps4rails::GeocodeNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
74
|
+
Response was: #{response}"
|
75
|
+
end #end resp test
|
76
|
+
end
|
77
|
+
|
78
|
+
def Gmaps4rails.handle_destination_response(request, response, output)
|
79
|
+
if response.is_a?(Net::HTTPSuccess)
|
80
|
+
#parse the json
|
81
|
+
#parse = Crack::JSON.parse(response.body)
|
82
|
+
parse = JSON.parse(response.body)
|
83
|
+
#check if google went well
|
84
|
+
if parse["status"] == "OK"
|
85
|
+
legs = []
|
86
|
+
#Each element in the legs array specifies a single leg of the journey from the origin to the destination in the calculated route
|
87
|
+
parse["routes"].first["legs"].each do |leg|
|
88
|
+
#delete coded polyline elements from legs and store it in polylines to make output cleaner
|
89
|
+
polylines = leg["steps"].map {|step| step.delete("polyline")} if output == "pretty" || output == "clean"
|
90
|
+
legs << {
|
91
|
+
"duration" => { "text" => leg["duration"]["text"], "value" => leg["duration"]["value"].to_f },
|
92
|
+
"distance" => { "text" => leg["distance"]["text"], "value" => leg["distance"]["value"].to_f },
|
93
|
+
"steps" => leg["steps"]
|
94
|
+
}
|
95
|
+
if output == "pretty"
|
96
|
+
#polylines contain levels data, which are not that useful.
|
97
|
+
polylines.map{|poly| poly.delete("levels")}
|
98
|
+
#create valid json from all polylines, this could be directly passed to javascript for display
|
99
|
+
json = polylines.map { |poly| {"coded_array" => poly["points"]} }.to_json
|
100
|
+
#merge results in legs
|
101
|
+
legs.last.merge!({ "polylines" => json })
|
102
|
+
end
|
103
|
+
end
|
104
|
+
return legs
|
105
|
+
else #status != OK
|
106
|
+
raise Gmaps4rails::DirectionStatus, "The query you passed seems invalid, status was: #{parse["status"]}.
|
107
|
+
Request was: #{request}"
|
108
|
+
end #end parse status
|
109
|
+
else #if not http success
|
110
|
+
raise Gmaps4rails::DirectionNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
111
|
+
Response was: #{response}"
|
112
|
+
end #end resp test
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Gmaps4rails
|
2
|
+
|
3
|
+
# does two things... 1) gecode the given address string and 2) triggers a a places query around that geo location
|
4
|
+
# optionally a keyword can be given for a filter over all places fields (e.g. "Bungy" to give all Bungy related places)
|
5
|
+
# IMPORTANT: Places API calls require an API key (param "key")
|
6
|
+
|
7
|
+
def Gmaps4rails.places_for_address(address, key, keyword = nil, radius = 7500, lang="en", raw = false)
|
8
|
+
if address.nil?
|
9
|
+
raise Gmaps4rails::GeocodeInvalidQuery, "you must provide an address for a places_for_address query"
|
10
|
+
elsif key.nil?
|
11
|
+
raise "Google Places API requires an API key"
|
12
|
+
else
|
13
|
+
res = Gmaps4rails.geocode(address) # will throw exception if nothing could be geocoded
|
14
|
+
Gmaps4rails.places(res.first[:lat], res.first[:lng], key, keyword, radius, lang, raw)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# does a places query around give geo location (lat/lng)
|
19
|
+
# optionally a keyword can be given for a filter over all places fields (e.g. "Bungy" to give all Bungy related places)
|
20
|
+
# IMPORTANT: Places API calls require an API key (param "key")
|
21
|
+
def Gmaps4rails.places(lat, lng, key, keyword = nil, radius = 7500, lang="en", raw = false, protocol = "https")
|
22
|
+
if lat.nil? || lng.nil?
|
23
|
+
raise Gmaps4rails::PlacesInvalidQuery, "You must provide at least a lat/lon for a Google places query"
|
24
|
+
elsif key.nil?
|
25
|
+
raise "Google Places API requires an API key"
|
26
|
+
else #lat/lng are valid
|
27
|
+
geocoder = "#{protocol}://maps.googleapis.com/maps/api/place/search/json?language=#{lang}&location=#{[lat.to_s, lng.to_s].join(",")}"
|
28
|
+
output = "&sensor=false&radius=#{radius}&key=#{key}"
|
29
|
+
|
30
|
+
# add filter keyword
|
31
|
+
geocoder += "&keyword=#{keyword}" unless keyword.nil?
|
32
|
+
|
33
|
+
#send request to the google api to get the lat/lng
|
34
|
+
request = geocoder + output
|
35
|
+
url = URI.escape(request)
|
36
|
+
uri = URI.parse(url)
|
37
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
38
|
+
http.use_ssl = true # Places API wants https
|
39
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # to avoid any cert issues
|
40
|
+
|
41
|
+
Gmaps4rails.handle_places_response(request, http.request(Net::HTTP::Get.new(uri.request_uri)), raw)
|
42
|
+
end # end lat/lng valid
|
43
|
+
end
|
44
|
+
|
45
|
+
# handles the places query response
|
46
|
+
def Gmaps4rails.handle_places_response(request, response, raw)
|
47
|
+
#parse result if result received properly
|
48
|
+
if response.is_a?(Net::HTTPSuccess)
|
49
|
+
#parse the json
|
50
|
+
parse = JSON.parse(response.body)
|
51
|
+
#check if google went well
|
52
|
+
if parse["status"] == "OK"
|
53
|
+
return parse if raw == true
|
54
|
+
array = []
|
55
|
+
parse["results"].each do |result|
|
56
|
+
array << {
|
57
|
+
:lat => result["geometry"]["location"]["lat"],
|
58
|
+
:lng => result["geometry"]["location"]["lng"],
|
59
|
+
:name => result["name"],
|
60
|
+
:reference => result["reference"],
|
61
|
+
:vicinity => result["vicinity"],
|
62
|
+
:full_data => result
|
63
|
+
}
|
64
|
+
end
|
65
|
+
return array
|
66
|
+
else #status != OK
|
67
|
+
raise Gmaps4rails::PlacesStatus, "The address you passed seems invalid, status was: #{parse["status"]}.
|
68
|
+
Request was: #{request}"
|
69
|
+
end #end parse status
|
70
|
+
|
71
|
+
else #if not http success
|
72
|
+
raise Gmaps4rails::PlacesNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
73
|
+
Response was: #{response}"
|
74
|
+
end #end resp test
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Gmaps4rails
|
2
|
+
|
3
|
+
DEFAULT_MAP_ID = "map"
|
4
|
+
|
5
|
+
def Gmaps4rails.js_function_name(hash)
|
6
|
+
"load_" + Gmaps4rails.get_map_id(hash[:map_options])
|
7
|
+
end
|
8
|
+
|
9
|
+
def Gmaps4rails.get_map_id(hash)
|
10
|
+
hash.nil? || hash[:id].nil? ? DEFAULT_MAP_ID : hash[:id]
|
11
|
+
end
|
12
|
+
|
13
|
+
def Gmaps4rails.get_constructor(hash)
|
14
|
+
hash.nil? || hash[:provider].nil? ? "Gmaps4RailsGoogle()" : "Gmaps4Rails#{hash[:provider].capitalize}()"
|
15
|
+
end
|
16
|
+
|
17
|
+
def Gmaps4rails.create_map_js(map_hash, map_id)
|
18
|
+
output = Array.new
|
19
|
+
skipped_keys = [:class, :container_class]
|
20
|
+
map_hash.each do |option_k, option_v|
|
21
|
+
unless skipped_keys.include? option_k.to_sym
|
22
|
+
case option_k.to_sym
|
23
|
+
when :bounds, :raw #particular case, render the content unescaped
|
24
|
+
output << "#{map_id}.map_options.#{option_k} = #{option_v};"
|
25
|
+
else
|
26
|
+
output << "#{map_id}.map_options.#{option_k} = #{Gmaps4rails.filter option_v};"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
output
|
31
|
+
end
|
32
|
+
|
33
|
+
def Gmaps4rails.create_general_js(hash, map_id, category)
|
34
|
+
hash = hash.with_indifferent_access
|
35
|
+
output = Array.new
|
36
|
+
output << "#{map_id}.#{category} = #{hash[:data]};"
|
37
|
+
hash[:options] ||= Array.new
|
38
|
+
hash[:options].each do |option_k, option_v|
|
39
|
+
if option_k.to_sym == :raw
|
40
|
+
output << "#{map_id}.#{category}_conf.#{option_k} = #{option_v};"
|
41
|
+
else
|
42
|
+
output << "#{map_id}.#{category}_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
output << "#{map_id}.create_#{category}();"
|
46
|
+
output
|
47
|
+
end
|
48
|
+
|
49
|
+
def Gmaps4rails.create_direction_js(hash, map_id)
|
50
|
+
hash = hash.with_indifferent_access
|
51
|
+
output = Array.new
|
52
|
+
output << "#{map_id}.direction_conf.origin = '#{hash["data"]["from"]}';"
|
53
|
+
output << "#{map_id}.direction_conf.destination = '#{hash["data"]["to"]}';"
|
54
|
+
hash[:options] ||= Array.new
|
55
|
+
hash[:options].each do |option_k, option_v|
|
56
|
+
if option_k.to_sym == :waypoints
|
57
|
+
waypoints = Array.new
|
58
|
+
option_v.each do |waypoint|
|
59
|
+
waypoints << { "location" => waypoint, "stopover" => true }.to_json
|
60
|
+
end
|
61
|
+
output << "#{map_id}.direction_conf.waypoints = [#{waypoints * (",")}];"
|
62
|
+
else #option_k != "waypoint"
|
63
|
+
output << "#{map_id}.direction_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
64
|
+
end
|
65
|
+
end #end .each
|
66
|
+
output << "#{map_id}.create_direction();"
|
67
|
+
output
|
68
|
+
end
|
69
|
+
|
70
|
+
#the variable 'hash' must have the following structure
|
71
|
+
#{
|
72
|
+
# :map_options => hash,
|
73
|
+
# :markers => { :data => json, :options => hash },
|
74
|
+
# :polylines => { :data => json, :options => hash },
|
75
|
+
# :polygons => { :data => json, :options => hash },
|
76
|
+
# :circles => { :data => json, :options => hash },
|
77
|
+
# :direction => { :data => hash, :options => hash },
|
78
|
+
# :kml => { :data => json, :options => hash }
|
79
|
+
#}
|
80
|
+
def Gmaps4rails.create_js_from_hash(hash)
|
81
|
+
result = Array.new
|
82
|
+
map_id = "Gmaps." + Gmaps4rails.get_map_id(hash[:map_options])
|
83
|
+
|
84
|
+
#means we are creating a new map
|
85
|
+
result << "#{map_id} = new #{Gmaps4rails.get_constructor hash[:map_options] }" + ";"
|
86
|
+
result << "Gmaps.#{Gmaps4rails.js_function_name hash } = function() {"
|
87
|
+
result << Gmaps4rails.create_map_js(hash[:map_options], map_id) unless hash[:map_options].nil?
|
88
|
+
result << "#{map_id}.initialize();"
|
89
|
+
|
90
|
+
hash.each do |category, content| #loop through options hash
|
91
|
+
skipped_categories = [:map_options, :last_map, :scripts]
|
92
|
+
unless skipped_categories.include? category.to_sym
|
93
|
+
if category.to_sym == :direction
|
94
|
+
result << Gmaps4rails.create_direction_js(content, map_id)
|
95
|
+
else
|
96
|
+
result << Gmaps4rails.create_general_js(content, map_id, category)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
result << "#{map_id}.adjustMapToBounds();"
|
101
|
+
result << "#{map_id}.callback();"
|
102
|
+
|
103
|
+
result << "};"
|
104
|
+
if hash[:last_map].nil? || hash[:last_map] == true
|
105
|
+
result << "window.onload = function() { Gmaps.loadMaps(); };"
|
106
|
+
end
|
107
|
+
|
108
|
+
result * ('
|
109
|
+
')
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Gmaps4rails
|
2
|
+
|
3
|
+
mattr_accessor :json_hash, :custom_json, :object
|
4
|
+
|
5
|
+
def Gmaps4rails.create_json(object, &block)
|
6
|
+
@object, @json_hash, @custom_json = object, Hash.new, nil
|
7
|
+
if compliant?
|
8
|
+
handle_block(&block) if block_given?
|
9
|
+
handle_model_methods
|
10
|
+
return_json
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def Gmaps4rails.infowindow(string)
|
15
|
+
@json_hash[:description] = string
|
16
|
+
end
|
17
|
+
|
18
|
+
def Gmaps4rails.title(string)
|
19
|
+
@json_hash[:title] = string
|
20
|
+
end
|
21
|
+
|
22
|
+
def Gmaps4rails.sidebar(string)
|
23
|
+
@json_hash[:sidebar] = string
|
24
|
+
end
|
25
|
+
|
26
|
+
def Gmaps4rails.json(json)
|
27
|
+
return @json_hash.merge! json if json.is_a? Hash
|
28
|
+
json
|
29
|
+
end
|
30
|
+
|
31
|
+
def Gmaps4rails.picture(hash)
|
32
|
+
@json_hash.merge! hash
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def Gmaps4rails.model_attributes
|
38
|
+
{
|
39
|
+
:description => :gmaps4rails_infowindow,
|
40
|
+
:title => :gmaps4rails_title,
|
41
|
+
:sidebar => :gmaps4rails_sidebar,
|
42
|
+
:marker_picture => :gmaps4rails_marker_picture,
|
43
|
+
:lat => @object.gmaps4rails_options[:lat_column],
|
44
|
+
:lng => @object.gmaps4rails_options[:lng_column]
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def Gmaps4rails.handle_model_methods
|
49
|
+
model_attributes.each do |json_name, method_name|
|
50
|
+
if @object.respond_to? method_name
|
51
|
+
if json_name == :marker_picture
|
52
|
+
@json_hash.merge! @object.send(method_name)
|
53
|
+
else
|
54
|
+
@json_hash[json_name] = @object.send(method_name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# returns the proper json
|
61
|
+
# three cases here:
|
62
|
+
# - no custom json provided
|
63
|
+
# - custom json provided as a hash (marker.json { :id => user.id }) => merge hashes then create json
|
64
|
+
# - custom json provided as string (marker.json {"\"id\": #{user.id}" } => create json from hash then insert string inside
|
65
|
+
def Gmaps4rails.return_json
|
66
|
+
return @json_hash.to_json if @custom_json.nil?
|
67
|
+
if @custom_json.is_a? Hash
|
68
|
+
@json_hash.merge! @custom_json
|
69
|
+
return @json_hash.to_json
|
70
|
+
elsif @custom_json.is_a? String
|
71
|
+
output = @json_hash.to_json
|
72
|
+
return output.insert(1, @custom_json + ",")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def Gmaps4rails.compliant?
|
77
|
+
!(@object.send(@object.gmaps4rails_options[:lat_column]).blank? && @object.send(@object.gmaps4rails_options[:lng_column]).blank?)
|
78
|
+
end
|
79
|
+
|
80
|
+
# the to_gmaps4rails method accepts a block to customize:
|
81
|
+
# - infowindow
|
82
|
+
# - picture
|
83
|
+
# - title
|
84
|
+
# - sidebar
|
85
|
+
# - json
|
86
|
+
#
|
87
|
+
# This works this way:
|
88
|
+
# @json = User.all.to_gmaps4rails do |user, marker|
|
89
|
+
# marker.infowindow render_to_string(:partial => "/users/my_template", :locals => { :object => user}).gsub(/\n/, '').gsub(/"/, '\"')
|
90
|
+
# marker.picture({
|
91
|
+
# :picture => "http://www.blankdots.com/img/github-32x32.png",
|
92
|
+
# :width => "32",
|
93
|
+
# :height => "32"
|
94
|
+
# })
|
95
|
+
# marker.title "i'm the title"
|
96
|
+
# marker.sidebar "i'm the sidebar"
|
97
|
+
# marker.json { :id => user.id }
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# For backward compability, a mere string could be passed:
|
101
|
+
# @json = User.all.to_gmaps4rails do |user, marker|
|
102
|
+
# "\"id\": #{user.id}"
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
def Gmaps4rails.handle_block(&block)
|
106
|
+
block_result = yield(@object, ::Gmaps4rails)
|
107
|
+
return Gmaps4rails.json(block_result) unless block_result.is_a? String
|
108
|
+
@custom_json = block_result
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
@@ -193,7 +193,6 @@
|
|
193
193
|
return _results;
|
194
194
|
};
|
195
195
|
Gmaps4RailsGoogle.prototype.clearMarker = function(marker) {
|
196
|
-
console.log(marker);
|
197
196
|
return marker.serviceObject.setMap(null);
|
198
197
|
};
|
199
198
|
Gmaps4RailsGoogle.prototype.showMarker = function(marker) {
|
@@ -277,7 +276,9 @@
|
|
277
276
|
return kml;
|
278
277
|
};
|
279
278
|
Gmaps4RailsGoogle.prototype.fitBounds = function() {
|
280
|
-
|
279
|
+
if (!this.boundsObject.isEmpty()) {
|
280
|
+
return this.map.fitBounds(this.boundsObject);
|
281
|
+
}
|
281
282
|
};
|
282
283
|
Gmaps4RailsGoogle.prototype.centerMapOnUser = function() {
|
283
284
|
return this.map.setCenter(this.userLocation);
|
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: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 1.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Benjamin Roth
|
@@ -16,10 +16,10 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date:
|
19
|
+
date: 2012-01-02 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
22
|
+
name: json
|
23
23
|
prerelease: false
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
@@ -62,7 +62,11 @@ files:
|
|
62
62
|
- lib/gmaps4rails/base.rb
|
63
63
|
- lib/gmaps4rails/extensions/array.rb
|
64
64
|
- lib/gmaps4rails/extensions/hash.rb
|
65
|
+
- lib/gmaps4rails/geocoding.rb
|
66
|
+
- lib/gmaps4rails/google_places.rb
|
65
67
|
- lib/gmaps4rails/helper/gmaps4rails_helper.rb
|
68
|
+
- lib/gmaps4rails/js_handler.rb
|
69
|
+
- lib/gmaps4rails/json_handler.rb
|
66
70
|
- public/images/marker.png
|
67
71
|
- public/javascripts/gmaps4rails/gmaps4rails.base.js
|
68
72
|
- public/javascripts/gmaps4rails/gmaps4rails.bing.js
|