gmaps4rails 1.3.2 → 1.4.0
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/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
|