google_static_maps_helper 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -97,7 +97,10 @@ Another thing you might want to do is to override the center point and zoom leve
97
97
 
98
98
 
99
99
  == Paths and Polygons
100
- It is also possible to create Paths and Polygons and to use them together with markers. To create a Path you need two Points and a Path object:
100
+ It is also possible to create Paths and Polygons and to use them together with markers.
101
+ Paths and Polygons will by default encode it's points with Google's encoding algorithm.
102
+
103
+ To create a Path you need two Points and a Path object:
101
104
  path = GoogleStaticMapsHelper::Path.new
102
105
  start_point = {:lat => 1, :lng => 2} # You can also use any object which responds to lat and lng here
103
106
  end_point = {:lat => 1, :lng => 2}
@@ -136,9 +139,6 @@ It also have a helper method called <tt>endpoints_for_circle_with_radius</tt> wh
136
139
  map << path
137
140
 
138
141
 
139
- == TODO
140
- * Add support for encoded polylines (http://code.google.com/apis/maps/documentation/staticmaps/#EncodedPolylines).
141
-
142
142
  == Copyright
143
143
 
144
144
  Copyright (c) 2009 Thorbjørn Hermansen. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.3
1
+ 1.3.4
data/changelog.txt CHANGED
@@ -1,4 +1,8 @@
1
- = v.1.3.3 (in git)
1
+ = v.1.3.4
2
+ * Paths are now as default encoding it's points with Google's encoding algorithm. Thanks to Joel Rosenberg for providing an easy class to use.
3
+ This will cut the length of the generated URL quite a bit; down to between 1/3 and 1/2 of the old size.
4
+
5
+ = v.1.3.3
2
6
  * We are now supporting ruby 1.9.1.
3
7
 
4
8
  = v.1.3.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{google_static_maps_helper}
8
- s.version = "1.3.3"
8
+ s.version = "1.3.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Thorbj\303\270rn Hermansen"]
12
- s.date = %q{2009-12-01}
11
+ s.authors = ["Thorbjørn Hermansen"]
12
+ s.date = %q{2009-12-03}
13
13
  s.description = %q{This gem provides a simple interface to the Google Static Maps V2 API.}
14
14
  s.email = %q{thhermansen@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "changelog.txt",
27
27
  "google_static_maps_helper.gemspec",
28
28
  "lib/google_static_maps_helper.rb",
29
+ "lib/google_static_maps_helper/gmap_polyline_encoder.rb",
29
30
  "lib/google_static_maps_helper/location.rb",
30
31
  "lib/google_static_maps_helper/map.rb",
31
32
  "lib/google_static_maps_helper/marker.rb",
@@ -4,6 +4,7 @@ require File.dirname(__FILE__) + '/google_static_maps_helper/map'
4
4
  require File.dirname(__FILE__) + '/google_static_maps_helper/location'
5
5
  require File.dirname(__FILE__) + '/google_static_maps_helper/marker'
6
6
  require File.dirname(__FILE__) + '/google_static_maps_helper/path'
7
+ require File.dirname(__FILE__) + '/google_static_maps_helper/gmap_polyline_encoder'
7
8
 
8
9
  #
9
10
  # The Google Static Map Helper provides a simple interface to the
@@ -0,0 +1,390 @@
1
+ #--
2
+ #
3
+ # Utility for creating Google Maps Encoded GPolylines
4
+ #
5
+ # License: You may distribute this code under the same terms as Ruby itself
6
+ #
7
+ # Author: Joel Rosenberg
8
+ #
9
+ # ( Drawing from the official example pages as well as Mark McClure's work )
10
+ #
11
+ # == Example
12
+ #
13
+ # data = [
14
+ # [ 37.4419, -122.1419],
15
+ # [ 37.4519, -122.1519],
16
+ # [ 37.4619, -122.1819],
17
+ # ]
18
+ #
19
+ # encoder = GMapPolylineEncoder.new()
20
+ # result = encoder.encode( data )
21
+ #
22
+ # javascript << " var myLine = new GPolyline.fromEncoded({\n"
23
+ # javascript << " color: \"#FF0000\",\n"
24
+ # javascript << " weight: 10,\n"
25
+ # javascript << " opacity: 0.5,\n"
26
+ # javascript << " zoomFactor: #{result[:zoomFactor]},\n"
27
+ # javascript << " numLevels: #{result[:numLevels]},\n"
28
+ # javascript << " points: \"#{result[:points]}\",\n"
29
+ # javascript << " levels: \"#{result[:levels]}\"\n"
30
+ # javascript << " });"
31
+ #
32
+ # == Methods
33
+ #
34
+ # Constructor args (all optional):
35
+ # :numLevels (default 18)
36
+ # :zoomFactor (default 2)
37
+ # :reduce: Reduce points (default true)
38
+ # :escape: Escape backslashes (default true)
39
+ #
40
+ # encode( points ) method
41
+ # points (required): array of longitude, latitude pairs
42
+ #
43
+ # returns hash with keys :points, :levels, :zoomFactor, :numLevels
44
+ #
45
+ # == Background
46
+ #
47
+ # Description: http://www.google.com/apis/maps/documentation/#Encoded_Polylines
48
+ # API: http://www.google.com/apis/maps/documentation/reference.html#GPolyline
49
+ # Hints: http://www.google.com/apis/maps/documentation/polylinealgorithm.html
50
+ #
51
+ # Example Javascript for instantiating an encoded polyline:
52
+ # var encodedPolyline = new GPolyline.fromEncoded({
53
+ # color: "#FF0000",
54
+ # weight: 10,
55
+ # points: "yzocFzynhVq}@n}@o}@nzD",
56
+ # levels: "BBB",
57
+ # zoomFactor: 32,
58
+ # numLevels: 4
59
+ # });
60
+ #
61
+ # == Changes
62
+ #
63
+ # 06.29.2007 - Release 0.1
64
+ # Profiling showed that distance() accounted for 50% of the time when
65
+ # processing McClure's British coast data. By moving the distance
66
+ # calculation into encode(), we can cache a few of the calculations
67
+ # (magnitude) and eliminate the overhead of the function call. This
68
+ # reduced the time to encode by ~ 30%
69
+ #
70
+ # 06.21.2007 Implementing the Doublas-Peucker algorithm for removing superflous
71
+ # points as per Mark McClure's design:
72
+ # http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/
73
+ #
74
+ # 10.14.2006 Cleaned up (and finally grasped) zoom levels
75
+ #
76
+ # 09.2006 First port of the official example's javascript. Ignoring zoom
77
+ # levels for now, showing points at all zoom levels
78
+ #
79
+ #++
80
+ module GoogleStaticMapsHelper
81
+ class GMapPolylineEncoder
82
+ attr_accessor :reduce, :escape #zoomFactor and numLevels need side effects
83
+ attr_reader :zoomFactor, :numLevels
84
+
85
+ # The minimum distance from the line that a point must exceed to avoid
86
+ # elimination under the DP Algorithm.
87
+ @@dp_threshold = 0.00001
88
+
89
+ def initialize(options = {})
90
+ # There are no required parameters
91
+
92
+ # Nice defaults
93
+ @numLevels = options.has_key?(:numLevels) ? options[:numLevels] : 18
94
+ @zoomFactor = options.has_key?(:zoomFactor) ? options[:zoomFactor] : 2
95
+
96
+ # Calculate the distance thresholds for each zoom level
97
+ calculate_zoom_breaks()
98
+
99
+ # By default we'll simplify the polyline unless told otherwise
100
+ @reduce = ! options.has_key?(:reduce) ? true : options[:reduce]
101
+
102
+ # Escape by default; most people are using this in a web context
103
+ @escape = ! options.has_key?(:escape) ? true : options[:escape]
104
+
105
+ end
106
+
107
+ def numLevels=( new_num_levels )
108
+ @numLevels = new_num_levels
109
+ # We need to recalculate our zoom breaks
110
+ calculate_zoom_breaks()
111
+ end
112
+
113
+ def zoomFactor=( new_zoom_factor )
114
+ @zoomFactor = new_zoom_factor
115
+ # We need to recalculate our zoom breaks
116
+ calculate_zoom_breaks()
117
+ end
118
+
119
+ def encode( points )
120
+
121
+ #
122
+ # This is an implementation of the Douglas-Peucker algorithm for simplifying
123
+ # a line. You can thing of it as an elimination of points that do not
124
+ # deviate enough from a vector. That threshold for point elimination is in
125
+ # @@dp_threshold. See
126
+ #
127
+ # http://everything2.com/index.pl?node_id=859282
128
+ #
129
+ # for an explanation of the algorithm
130
+ #
131
+
132
+ max_dist = 0 # Greatest distance we measured during the run
133
+ stack = []
134
+ distances = Array.new(points.size)
135
+
136
+ if(points.length > 2)
137
+ stack << [0, points.size-1]
138
+
139
+ while(stack.length > 0)
140
+ current_line = stack.pop()
141
+ p1_idx = current_line[0]
142
+ pn_idx = current_line[1]
143
+ pb_dist = 0
144
+ pb_idx = nil
145
+
146
+ x1 = points[p1_idx][0]
147
+ y1 = points[p1_idx][1]
148
+ x2 = points[pn_idx][0]
149
+ y2 = points[pn_idx][1]
150
+
151
+ # Caching the line's magnitude for performance
152
+ magnitude = Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
153
+ magnitude_squared = magnitude ** 2
154
+
155
+ # Find the farthest point and its distance from the line between our pair
156
+ for i in (p1_idx+1)..(pn_idx-1)
157
+
158
+ # Refactoring distance computation inline for performance
159
+ #current_distance = compute_distance(points[i], points[p1_idx], points[pn_idx])
160
+
161
+ #
162
+ # This uses Euclidian geometry. It shouldn't be that big of a deal since
163
+ # we're using it as a rough comparison for line elimination and zoom
164
+ # calculation.
165
+ #
166
+ # TODO: Implement Haversine functions which would probably bring this to
167
+ # a snail's pace (ehhhh)
168
+ #
169
+
170
+ px = points[i][0]
171
+ py = points[i][1]
172
+
173
+ current_distance = nil
174
+
175
+ if( magnitude == 0 )
176
+ # The line is really just a point
177
+ current_distance = Math.sqrt((x2-px)**2 + (y2-py)**2)
178
+ else
179
+
180
+ u = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / magnitude_squared
181
+
182
+ if( u <= 0 || u > 1 )
183
+ # The point is closest to an endpoint. Find out which one
184
+ ix = Math.sqrt((x1 - px)**2 + (y1 - py)**2)
185
+ iy = Math.sqrt((x2 - px)**2 + (y2 - py)**2)
186
+ if( ix > iy )
187
+ current_distance = iy
188
+ else
189
+ current_distance = ix
190
+ end
191
+ else
192
+ # The perpendicular point intersects the line
193
+ ix = x1 + u * (x2 - x1)
194
+ iy = y1 + u * (y2 - y1)
195
+ current_distance = Math.sqrt((ix - px)**2 + (iy - py)**2)
196
+ end
197
+ end
198
+
199
+ # See if this distance is the greatest for this segment so far
200
+ if(current_distance > pb_dist)
201
+ pb_dist = current_distance
202
+ pb_idx = i
203
+ end
204
+ end
205
+
206
+ # See if this is the greatest distance for all points
207
+ if(pb_dist > max_dist)
208
+ max_dist = pb_dist
209
+ end
210
+
211
+ if(pb_dist > @@dp_threshold)
212
+ # Our point, Pb, that had the greatest distance from the line, is also
213
+ # greater than our threshold. Process again using Pb as a new
214
+ # start/end point. Record this distance - we'll use it later when
215
+ # creating zoom values
216
+ distances[pb_idx] = pb_dist
217
+ stack << [p1_idx, pb_idx]
218
+ stack << [pb_idx, pn_idx]
219
+ end
220
+
221
+ end
222
+ end
223
+
224
+ # Force line endpoints to be included (sloppy, but faster than checking for
225
+ # endpoints in encode_points())
226
+ distances[0] = max_dist
227
+ distances[distances.length-1] = max_dist
228
+
229
+ # Create Base64 encoded strings for our points and zoom levels
230
+ points_enc = encode_points( points, distances)
231
+ levels_enc = encode_levels( points, distances, max_dist)
232
+
233
+ # Make points_enc an escaped string if desired.
234
+ # We should escape the levels too, in case google pulls a switcheroo
235
+ @escape && points_enc && points_enc.gsub!( /\\/, '\\\\\\\\' )
236
+
237
+
238
+ # Returning a hash. Yes, I am a Perl programmer
239
+ return {
240
+ :points => points_enc,
241
+ :levels => levels_enc,
242
+ :zoomFactor => @zoomFactor,
243
+ :numLevels => @numLevels,
244
+ }
245
+
246
+ end
247
+
248
+ private
249
+
250
+ def calculate_zoom_breaks()
251
+ # Calculate the distance thresholds for each zoom level
252
+ @zoom_level_breaks = Array.new(@numLevels);
253
+
254
+ for i in 0..(@numLevels-1)
255
+ @zoom_level_breaks[i] = @@dp_threshold * (@zoomFactor ** ( @numLevels-i-1));
256
+ end
257
+
258
+ return
259
+ end
260
+
261
+ def encode_points( points, distances )
262
+ encoded = ""
263
+
264
+ plat = 0
265
+ plon = 0
266
+
267
+ #points.each do |point| # Gah, need the distances.
268
+ for i in 0..(points.size() - 1)
269
+ if(! @reduce || distances[i] != nil )
270
+ point = points[i]
271
+ late5 = (point[0] * 1e5).floor();
272
+ lone5 = (point[1] * 1e5).floor();
273
+
274
+ dlat = late5 - plat
275
+ dlon = lone5 - plon
276
+
277
+ plat = late5;
278
+ plon = lone5;
279
+
280
+ # I used to need this for some reason
281
+ #encoded << encodeSignedNumber(Fixnum.induced_from(dlat)).to_s
282
+ #encoded << encodeSignedNumber(Fixnum.induced_from(dlon)).to_s
283
+ encoded << encodeSignedNumber(dlat).to_s
284
+ encoded << encodeSignedNumber(dlon).to_s
285
+ end
286
+ end
287
+
288
+ return encoded
289
+
290
+ end
291
+
292
+ def encode_levels( points, distances, max_dist )
293
+
294
+ encoded = "";
295
+
296
+ # Force startpoint
297
+ encoded << encodeNumber(@numLevels - 1)
298
+
299
+ if( points.size() > 2 )
300
+ for i in 1..(points.size() - 2)
301
+ distance = distances[i]
302
+ if( ! @reduce || distance != nil)
303
+ computed_level = 0
304
+
305
+ while (distance < @zoom_level_breaks[computed_level]) do
306
+ computed_level += 1
307
+ end
308
+
309
+ encoded << encodeNumber( @numLevels - computed_level - 1 )
310
+ end
311
+ end
312
+ end
313
+
314
+ # Force endpoint
315
+ encoded << encodeNumber(@numLevels - 1)
316
+
317
+ return encoded;
318
+
319
+ end
320
+
321
+ def compute_distance( point, lineStart, lineEnd )
322
+
323
+ #
324
+ # Note: This has been refactored to encode() inline for performance and
325
+ # computation caching
326
+ #
327
+
328
+ px = point[0]
329
+ py = point[1]
330
+ x1 = lineStart[0]
331
+ y1 = lineStart[1]
332
+ x2 = lineEnd[0]
333
+ y2 = lineEnd[1]
334
+
335
+ distance = nil
336
+
337
+ magnitude = Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
338
+
339
+ if( magnitude == 0 )
340
+ return Math.sqrt((x2-px)**2 + (y2-py)**2)
341
+ end
342
+
343
+ u = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / (magnitude**2)
344
+
345
+ if( u <= 0 || u > 1 )
346
+ # The point is closest to an endpoint. Find out which
347
+ ix = Math.sqrt((x1 - px)**2 + (y1 - py)**2)
348
+ iy = Math.sqrt((x2 - px)**2 + (y2 - py)**2)
349
+ if( ix > iy )
350
+ distance = iy
351
+ else
352
+ distance = ix
353
+ end
354
+ else
355
+ # The perpendicular point intersects the line
356
+ ix = x1 + u * (x2 - x1)
357
+ iy = y1 + u * (y2 - y1)
358
+ distance = Math.sqrt((ix - px)**2 + (iy - py)**2)
359
+ end
360
+
361
+ return distance
362
+ end
363
+
364
+ def encodeSignedNumber(num)
365
+ # Based on the official google example
366
+
367
+ sgn_num = num << 1
368
+
369
+ if( num < 0 )
370
+ sgn_num = ~(sgn_num)
371
+ end
372
+
373
+ return encodeNumber(sgn_num)
374
+ end
375
+
376
+ def encodeNumber(num)
377
+ # Based on the official google example
378
+
379
+ encoded = "";
380
+
381
+ while (num >= 0x20) do
382
+ encoded << ((0x20 | (num & 0x1f)) + 63).chr;
383
+ num = num >> 5;
384
+ end
385
+
386
+ encoded << (num + 63).chr;
387
+ return encoded;
388
+ end
389
+ end
390
+ end
@@ -9,7 +9,7 @@ module GoogleStaticMapsHelper
9
9
 
10
10
  OPTIONAL_OPTIONS = [:weight, :color, :fillcolor]
11
11
 
12
- attr_accessor :points, *OPTIONAL_OPTIONS
12
+ attr_accessor :encode_points, :points, *OPTIONAL_OPTIONS
13
13
 
14
14
  #
15
15
  # Creates a new Path which you can push points on to to make up lines or polygons
@@ -25,9 +25,11 @@ module GoogleStaticMapsHelper
25
25
  # as described in the <tt>:color</tt>. When used, the static map will automatically create
26
26
  # a closed shape.
27
27
  # <tt>:points</tt>:: An array of points. You can mix objects responding to lng and lat, and a Hash with lng and lat keys.
28
+ # <tt>:encode_points:: A flag which tells us if we should encode the points in this path or not. Defaults to <tt>true</tt>
28
29
  #
29
30
  def initialize(*args)
30
31
  @points = []
32
+ @encode_points = true
31
33
 
32
34
  extract_options!(args)
33
35
  add_points(args)
@@ -49,9 +51,9 @@ module GoogleStaticMapsHelper
49
51
 
50
52
  out += "#{path_params}|" unless path_params.empty?
51
53
 
52
- out += inject([]) do |point_params, point|
53
- point_params << point.to_url
54
- end.join('|')
54
+ out += encoded_url_points if encoding_points?
55
+ out += unencoded_url_points unless encoding_points?
56
+ out
55
57
  end
56
58
 
57
59
 
@@ -78,6 +80,10 @@ module GoogleStaticMapsHelper
78
80
  length == 0
79
81
  end
80
82
 
83
+ def clear
84
+ @points = []
85
+ end
86
+
81
87
  #
82
88
  # Pushes a new point into the Path
83
89
  #
@@ -91,6 +97,14 @@ module GoogleStaticMapsHelper
91
97
  self
92
98
  end
93
99
 
100
+ #
101
+ # Will answer the question if we are encoding the points or not when
102
+ # building the image URL.
103
+ #
104
+ def encoding_points?
105
+ return !!@encode_points
106
+ end
107
+
94
108
 
95
109
  private
96
110
  #
@@ -117,5 +131,19 @@ module GoogleStaticMapsHelper
117
131
  def add_points(points)
118
132
  points.each {|point| self << point}
119
133
  end
134
+
135
+ def encoded_url_points
136
+ encoder = GMapPolylineEncoder.new
137
+ points_as_array = points.map { |location| [location.lat, location.lng]}
138
+ result = encoder.encode(points_as_array)
139
+
140
+ "enc:#{result[:points]}"
141
+ end
142
+
143
+ def unencoded_url_points
144
+ inject([]) do |point_params, point|
145
+ point_params << point.to_url
146
+ end.join('|')
147
+ end
120
148
  end
121
149
  end
@@ -35,7 +35,7 @@ describe GoogleStaticMapsHelper do
35
35
  point2 = {:lat => 3, :lng => 4}
36
36
 
37
37
  out = GoogleStaticMapsHelper.url_for do
38
- path point, point2, :color => :red
38
+ path point, point2, :color => :red, :encode_points => false
39
39
  end
40
40
 
41
41
  out.should include('path=color:red|1,2|3,4')
data/spec/map_spec.rb CHANGED
@@ -357,7 +357,7 @@ describe GoogleStaticMapsHelper::Map do
357
357
 
358
358
  describe "paths" do
359
359
  before do
360
- @path = GoogleStaticMapsHelper::Path.new
360
+ @path = GoogleStaticMapsHelper::Path.new :encode_points => false
361
361
  @point = GoogleStaticMapsHelper::Location.new(:lat => 1, :lng => 2)
362
362
  @point2 = GoogleStaticMapsHelper::Location.new(:lat => 3, :lng => 4)
363
363
  @path << @point << @point2
data/spec/path_spec.rb CHANGED
@@ -21,6 +21,23 @@ describe GoogleStaticMapsHelper::Path do
21
21
  end
22
22
  end
23
23
 
24
+ describe "encoding points flag" do
25
+ it "should be able to set to false" do
26
+ path = GoogleStaticMapsHelper::Path.new(:encode_points => false)
27
+ path.should_not be_encoding_points
28
+ end
29
+
30
+ it "should be able to set to true" do
31
+ path = GoogleStaticMapsHelper::Path.new(:encode_points => true)
32
+ path.should be_encoding_points
33
+ end
34
+
35
+ it "should be true as default" do
36
+ path = GoogleStaticMapsHelper::Path.new
37
+ path.should be_encoding_points
38
+ end
39
+ end
40
+
24
41
  describe "points" do
25
42
  before do
26
43
  @point = GoogleStaticMapsHelper::Location.new(:lat => 1, :lng => 2)
@@ -50,6 +67,12 @@ describe GoogleStaticMapsHelper::Path do
50
67
  @path.points.should == []
51
68
  end
52
69
 
70
+ it "should be possible to clear points" do
71
+ @path << @point << @point2
72
+ @path.clear
73
+ @path.length.should == 0
74
+ end
75
+
53
76
  it "should be able to push points on to a path" do
54
77
  @path << @point
55
78
  @path.points.length.should == 1
@@ -102,7 +125,7 @@ describe GoogleStaticMapsHelper::Path do
102
125
 
103
126
  describe "url_params" do
104
127
  before do
105
- @path = GoogleStaticMapsHelper::Path.new
128
+ @path = GoogleStaticMapsHelper::Path.new :encode_points => false
106
129
  @point = GoogleStaticMapsHelper::Location.new(:lat => 1, :lng => 2)
107
130
  @point2 = GoogleStaticMapsHelper::Location.new(:lat => 3, :lng => 4)
108
131
  @path << @point << @point2
@@ -148,5 +171,19 @@ describe GoogleStaticMapsHelper::Path do
148
171
  it "should concat point locations without any path options" do
149
172
  @path.url_params.should == 'path=1,2|3,4'
150
173
  end
174
+
175
+ describe "encoded poly lines" do
176
+ before do
177
+ @path.encode_points = true
178
+ end
179
+
180
+ it "should include 'enc:'" do
181
+ @path.url_params.should include('enc:')
182
+ end
183
+
184
+ it "should include encoded version of lng and lat" do
185
+ @path.url_params.should include('_ibE_seK_seK_seK')
186
+ end
187
+ end
151
188
  end
152
189
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_static_maps_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Thorbj\xC3\xB8rn Hermansen"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-01 00:00:00 +01:00
12
+ date: 2009-12-03 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,7 @@ files:
41
41
  - changelog.txt
42
42
  - google_static_maps_helper.gemspec
43
43
  - lib/google_static_maps_helper.rb
44
+ - lib/google_static_maps_helper/gmap_polyline_encoder.rb
44
45
  - lib/google_static_maps_helper/location.rb
45
46
  - lib/google_static_maps_helper/map.rb
46
47
  - lib/google_static_maps_helper/marker.rb