googlestaticmap 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +23 -0
- data/README +54 -0
- data/lib/googlestaticmap.rb +284 -0
- data/lib/googlestaticmap_helper.rb +27 -0
- data/test/tc_google_static_map.rb +135 -0
- data/test/tc_helper.rb +61 -0
- data/test/tc_map_location.rb +37 -0
- data/test/tc_map_marker.rb +51 -0
- data/test/tc_map_path_and_polygon.rb +60 -0
- metadata +67 -0
data/History.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
=== 1.1.0 / 2011-10-18
|
2
|
+
* Added an option to make requests through a proxy server (thanks bardsley!)
|
3
|
+
|
4
|
+
=== 1.0.1 / 2011-09-23
|
5
|
+
* Added a scale parameter to the map (thanks backspace!)
|
6
|
+
|
7
|
+
=== 1.0.0 / 2011-07-21
|
8
|
+
* An explicitly set map center is now properly encoded - was previously being doubly encoded (thanks abecciu)
|
9
|
+
* Gem will now load on some bad Rubygems installations (path issue)
|
10
|
+
* Version 1.0, yeah!
|
11
|
+
|
12
|
+
=== 0.1.5 / 2011-02-08
|
13
|
+
* Fixed bug which caused require 'googlestaticmap' to not work on some versions of Ruby
|
14
|
+
|
15
|
+
=== 0.1.4 / 2010-08-21
|
16
|
+
* Added unit tests
|
17
|
+
|
18
|
+
=== 0.1.2 / 2010-08-20
|
19
|
+
* Now works in Ruby 1.8 as well as 1.9
|
20
|
+
* Fixed a bug when getting a map without specifying a file
|
21
|
+
|
22
|
+
=== 0.1.0 / 2010-08-19
|
23
|
+
* Initial release
|
data/README
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= googlestaticmap gem
|
2
|
+
|
3
|
+
This gem is on Gemcutter, simply type "gem install googlestaticmap" to install it.
|
4
|
+
|
5
|
+
Available on github at http://github.com/brentsowers1/googlestaticmap
|
6
|
+
|
7
|
+
Class for generating URLs for and downloading static maps from the Google Maps
|
8
|
+
Static API service. GoogleStaticMap is the main class to use, instantiate it,
|
9
|
+
set the attributes to what you want, and call url on the instance to get the
|
10
|
+
URL to download the map from. You can also call get_map to actually
|
11
|
+
download the map from Google, return the bytes, and optionally write the
|
12
|
+
image to a file.
|
13
|
+
|
14
|
+
== Examples:
|
15
|
+
|
16
|
+
Get a simple static map centered at Washington, DC, with the default size
|
17
|
+
(500 x 350), zoomed to level 11
|
18
|
+
require 'googlestaticmap'
|
19
|
+
map = GoogleStaticMap.new(:zoom => 11, :center => MapLocation.new(:address => "Washington, DC"))
|
20
|
+
image = map.get_map
|
21
|
+
|
22
|
+
Get a map with blue markers at the White House and the Supreme Court, zoomed
|
23
|
+
the closest that the map can be with both markers visible, at the default
|
24
|
+
size.
|
25
|
+
require 'googlestaticmap'
|
26
|
+
map = GoogleStaticMap.new
|
27
|
+
map.markers << MapMarker.new(:color => "blue", :location => MapLocation.new(:address => "1600 Pennsylvania Ave., Washington, DC"))
|
28
|
+
map.markers << MapMarker.new(:color => "blue", :location => MapLocation.new(:address => "1 1st Street Northeast, Washington, DC"))
|
29
|
+
image = map.get_map
|
30
|
+
|
31
|
+
Get a GIF satellite map, with a size of 640 x 480, with a
|
32
|
+
semi transparent green box drawn around a set of 4 coordinates, with the box
|
33
|
+
outline solid, centered at the middle of the box, written out to the file
|
34
|
+
map.gif:
|
35
|
+
require 'googlestaticmap'
|
36
|
+
map = GoogleStaticMap.new(:maptype => "satellite", :format => "gif", :width => 640, :height => 480)
|
37
|
+
poly = MapPolygon.new(:color => "0x00FF00FF", :fillcolor => "0x00FF0060")
|
38
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
39
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -76.9)
|
40
|
+
poly.points << MapLocation.new(:latitude => 39.2, :longitude => -76.9)
|
41
|
+
poly.points << MapLocation.new(:latitude => 39.2, :longitude => -77.5)
|
42
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
43
|
+
map.paths << poly
|
44
|
+
map.get_map("map.gif")
|
45
|
+
|
46
|
+
If you're working behind a proxy, create the map object this way:
|
47
|
+
map = GoogleStaticMap.new(:proxy_address=>'my.proxy.host', :proxy_port=>8080, :width => 640, :height => 480)
|
48
|
+
|
49
|
+
|
50
|
+
Author:: Brent Sowers (mailto:brent@coordinatecommons.com)
|
51
|
+
License:: You're free to do whatever you want with this
|
52
|
+
|
53
|
+
To post comments about this gem, go to my blog posting at
|
54
|
+
http://rails.brentsowers.com/2010/08/gem-for-getting-google-static-maps.html
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# = googlestaticmap gem
|
2
|
+
#
|
3
|
+
# This gem is on Gemcutter, simply type "gem install googlestaticmap" to install it.
|
4
|
+
#
|
5
|
+
# Available on github at http://github.com/brentsowers1/googlestaticmap
|
6
|
+
#
|
7
|
+
# Class for generating URLs for and downloading static maps from the Google Maps
|
8
|
+
# Static API service. GoogleStaticMap is the main class to use, instantiate it,
|
9
|
+
# set the attributes to what you want, and call full_url on the instance to get
|
10
|
+
# the URL to download the map from. You can also call get_map to actually
|
11
|
+
# download the map from Google, return the bytes, and optionally write the
|
12
|
+
# image to a file.
|
13
|
+
#
|
14
|
+
# Examples:
|
15
|
+
#
|
16
|
+
# Get a simple static map centered at Washington, DC, with the default size
|
17
|
+
# (500 x 350), zoomed to level 11
|
18
|
+
# map = GoogleStaticMap.new(:zoom => 11, :center => MapLocation.new(:address => "Washington, DC"))
|
19
|
+
# image = map.get_map
|
20
|
+
#
|
21
|
+
# Get a map with blue markers at the White House and the Supreme Court, zoomed
|
22
|
+
# the closest that the map can be with both markers visible, at the default
|
23
|
+
# size.
|
24
|
+
# map = GoogleStaticMap.new
|
25
|
+
# map.markers << MapMarker.new(:color => "blue", :location => MapLocation.new(:address => "1600 Pennsylvania Ave., Washington, DC"))
|
26
|
+
# map.markers << MapMarker.new(:color => "blue", :location => MapLocation.new(:address => "1 1st Street Northeast, Washington, DC"))
|
27
|
+
# image = map.get_map
|
28
|
+
#
|
29
|
+
# Get a GIF satellite map, with a size of 640 x 480, with a
|
30
|
+
# semi transparent green box drawn around a set of 4 coordinates, with the box
|
31
|
+
# outline solid, centered at the middle of the box, written out to the file
|
32
|
+
# map.gif:
|
33
|
+
# map = GoogleStaticMap.new(:maptype => "satellite", :format => "gif", :width => 640, :height => 480)
|
34
|
+
# poly = MapPolygon.new(:color => "0x00FF00FF", :fillcolor => "0x00FF0060")
|
35
|
+
# poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
36
|
+
# poly.points << MapLocation.new(:latitude => 38.8, :longitude => -76.9)
|
37
|
+
# poly.points << MapLocation.new(:latitude => 39.2, :longitude => -76.9)
|
38
|
+
# poly.points << MapLocation.new(:latitude => 39.2, :longitude => -77.5)
|
39
|
+
# poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
40
|
+
# map.paths << poly
|
41
|
+
# map.get_map("map.gif")
|
42
|
+
#
|
43
|
+
# If you're working behind a proxy, create the map object this way:
|
44
|
+
# map = GoogleStaticMap.new(:proxy_address=>'my.proxy.host', :proxy_port=>8080, :width => 640, :height => 480)
|
45
|
+
#
|
46
|
+
# Author:: Brent Sowers (mailto:brent@coordinatecommons.com)
|
47
|
+
# License:: You're free to do whatever you want with this
|
48
|
+
|
49
|
+
require 'cgi'
|
50
|
+
require 'net/http'
|
51
|
+
require File.dirname(__FILE__) + '/googlestaticmap_helper'
|
52
|
+
|
53
|
+
# Main class for creating a static map. Create an instance, Set attributes
|
54
|
+
# that describe properties of the map. Then call url to get a URL that you
|
55
|
+
# can use as the src of an img tag. You can also call get_map to actually
|
56
|
+
# download the map from Google, and optionally write it to a file.
|
57
|
+
class GoogleStaticMap
|
58
|
+
# Width of resulting image in pixels, defaults to 500, maximum 640
|
59
|
+
attr_accessor :width
|
60
|
+
|
61
|
+
# Height of resulting image in pixels, defaults to 350, maximum 640
|
62
|
+
attr_accessor :height
|
63
|
+
|
64
|
+
# An optional array of MapMarker instances
|
65
|
+
attr_accessor :markers
|
66
|
+
|
67
|
+
# An optional array of MapPath instances and/or MapPolygon instances to draw
|
68
|
+
attr_accessor :paths
|
69
|
+
|
70
|
+
# MapLocation for the center of the map. If this is not specified, the map
|
71
|
+
# will zoom to the markers
|
72
|
+
attr_accessor :center
|
73
|
+
|
74
|
+
# 0 (the whole world) to 21 (individual buildings)
|
75
|
+
attr_accessor :zoom
|
76
|
+
|
77
|
+
# Applications that determine the user's location via a sensor must set this
|
78
|
+
# to true, defaults to false
|
79
|
+
attr_accessor :sensor
|
80
|
+
|
81
|
+
# 1, 2, or 4 for Maps API Premier customers. Defaults to 1. Makes everything
|
82
|
+
# in the image appear larger, useful for displaying on high res mobile
|
83
|
+
# screens. When setting this, the image's actual width and height in pixels
|
84
|
+
# will be scale * width and scale * height
|
85
|
+
attr_accessor :scale
|
86
|
+
|
87
|
+
# format of the image:
|
88
|
+
# * png8 - 8 bit PNG (default)
|
89
|
+
# * png32 - 32 bit PNG
|
90
|
+
# * gif
|
91
|
+
# * jpg
|
92
|
+
# * jpg-baseline - non-progressive JPEG
|
93
|
+
attr_accessor :format
|
94
|
+
|
95
|
+
# Type of map to create:
|
96
|
+
# * roadmap (default)
|
97
|
+
# * satellite
|
98
|
+
# * terrain
|
99
|
+
# * hybrid - satellite imagery with roads
|
100
|
+
attr_accessor :maptype
|
101
|
+
|
102
|
+
# If you need to use a proxy server to reach Google, set the name/address
|
103
|
+
# of the proxy server here
|
104
|
+
attr_accessor :proxy_address
|
105
|
+
|
106
|
+
# If proxy_address is set, set this to the port of the proxy server
|
107
|
+
attr_accessor :proxy_port
|
108
|
+
|
109
|
+
# Takes an optional hash of attributes
|
110
|
+
def initialize(attrs={})
|
111
|
+
defaults = {:width => 500, :height => 350, :markers => [],
|
112
|
+
:sensor => false, :maptype => "roadmap", :paths => [],
|
113
|
+
:proxy_port => nil, :proxy_address => nil,}
|
114
|
+
|
115
|
+
attributes = defaults.merge(attrs)
|
116
|
+
attributes.each {|k,v| self.send("#{k}=".to_sym,v)}
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the full URL to retrieve this static map. You can use this as the
|
120
|
+
# src for an img to display an image directly on a web page
|
121
|
+
# Example - "http://maps.google.com/maps/api/staticmap?params..."
|
122
|
+
def url
|
123
|
+
unless @center || @markers.length > 0 || @paths.length > 0
|
124
|
+
raise Exception.new("Need to specify either a center, markers, or a path")
|
125
|
+
end
|
126
|
+
u = "http://maps.google.com/maps/api/staticmap?"
|
127
|
+
attrs = GoogleStaticMapHelpers.safe_instance_variables(self,
|
128
|
+
["markers", "paths", "width", "height", "center",
|
129
|
+
"proxy_address", "proxy_port"],
|
130
|
+
:cgi_escape_values => true).to_a
|
131
|
+
attrs << ["size", "#{@width}x#{@height}"] if @width && @height
|
132
|
+
markers.each {|m| attrs << ["markers",m.to_s] }
|
133
|
+
paths.each {|p| attrs << ["path",p.to_s] }
|
134
|
+
attrs << ["center", center.to_s] if !center.nil?
|
135
|
+
u << attrs.collect {|attr| "#{attr[0]}=#{attr[1]}"}.join("&")
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns the URL to retrieve the map, relative to http://maps.google.com
|
139
|
+
# Example - "/maps/api/staticmap?params..."
|
140
|
+
def relative_url
|
141
|
+
url.gsub(/http\:\/\/maps\.google\.com/, "")
|
142
|
+
end
|
143
|
+
|
144
|
+
# Connects to Google, retrieves the map, and returns the bytes for the image.
|
145
|
+
# Optionally, pass it an output name and the contents will get written to
|
146
|
+
# this file name
|
147
|
+
def get_map(output_file=nil)
|
148
|
+
http = Net::HTTP.Proxy(@proxy_address,@proxy_port).new("maps.google.com", 80)
|
149
|
+
resp, data = http.get2(relative_url)
|
150
|
+
if resp && resp.is_a?(Net::HTTPSuccess)
|
151
|
+
if output_file
|
152
|
+
File.open(output_file, "wb") {|f| f << data }
|
153
|
+
end
|
154
|
+
data
|
155
|
+
else
|
156
|
+
if resp
|
157
|
+
raise Exception.new("Error encountered while retrieving google map, code #{resp.code}, text #{resp.body}")
|
158
|
+
else
|
159
|
+
raise Exception.new("Error while retrieve google map, no response")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Container class for a location on the map. Set either a latitude and
|
166
|
+
# longitude, or an address
|
167
|
+
class MapLocation
|
168
|
+
# Decimal degrees, positive is north
|
169
|
+
attr_accessor :latitude
|
170
|
+
|
171
|
+
# Decimal degrees, positive is east
|
172
|
+
attr_accessor :longitude
|
173
|
+
|
174
|
+
# String address - can be a full address, city name, zip code, etc. This is
|
175
|
+
# ignored if latitude and longitude are set.
|
176
|
+
attr_accessor :address
|
177
|
+
|
178
|
+
def initialize(attrs={})
|
179
|
+
attrs.each {|k,v| self.send("#{k}=".to_sym,v.to_s)}
|
180
|
+
end
|
181
|
+
|
182
|
+
def to_s
|
183
|
+
if latitude && longitude
|
184
|
+
"#{CGI.escape(latitude.to_s)},#{CGI.escape(longitude.to_s)}"
|
185
|
+
elsif address
|
186
|
+
CGI.escape(address)
|
187
|
+
else
|
188
|
+
raise Exception.new("Need to set either latitude and longitude, or address")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# A single marker to place on the map. Initialize and pass
|
194
|
+
class MapMarker
|
195
|
+
# A 24-bit color (example: 0xFFFFCC) or a predefined color from the set
|
196
|
+
# {black, brown, green, purple, yellow, blue, gray, orange, red, white}
|
197
|
+
attr_accessor :color
|
198
|
+
|
199
|
+
# MapLocation for the position of this marker
|
200
|
+
attr_accessor :location
|
201
|
+
|
202
|
+
# (optional) The size of marker from the set {tiny, small, mid}. Defaults to
|
203
|
+
# mid
|
204
|
+
attr_accessor :size
|
205
|
+
|
206
|
+
# (optional) A single uppercase alphanumeric character label from the set
|
207
|
+
# {A-Z, 0-9}. Not allowed for tiny and small sizes
|
208
|
+
attr_accessor :label
|
209
|
+
|
210
|
+
# a URL to use as the marker's custom icon. Images may be in PNG, JPEG or GIF
|
211
|
+
# formats, though PNG is recommended
|
212
|
+
attr_accessor :icon
|
213
|
+
|
214
|
+
# true (default) indicates that the Static Maps service should construct an
|
215
|
+
# appropriate shadow for the image. This shadow is based on the image's
|
216
|
+
# visible region and its opacity/transparency.
|
217
|
+
attr_accessor :shadow
|
218
|
+
|
219
|
+
# Takes an optional hash of attributes
|
220
|
+
def initialize(attrs={})
|
221
|
+
attrs.each {|k,v| self.send("#{k}=".to_sym,v)}
|
222
|
+
end
|
223
|
+
|
224
|
+
def to_s
|
225
|
+
raise Exception.new("Need a location for the marker") unless @location && @location.is_a?(MapLocation)
|
226
|
+
attrs = GoogleStaticMapHelpers.safe_instance_variables(self, ["location"])
|
227
|
+
s = attrs.to_a.collect do |k|
|
228
|
+
# If the icon URL is URL encoded, it won't work
|
229
|
+
val = (k[0] == "icon" ? k[1] : CGI.escape(k[1].to_s))
|
230
|
+
"#{k[0]}:#{val}"
|
231
|
+
end.join("|")
|
232
|
+
s << "|#{@location.to_s}"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# A path line to draw on the map. Initialize and set attributes.
|
237
|
+
class MapPath
|
238
|
+
# Thickness of the path line in pixels, defaults to 5
|
239
|
+
attr_accessor :weight
|
240
|
+
|
241
|
+
# Color of the path, either as a 24-bit (example: color=0xFFFFCC), a 32-bit
|
242
|
+
# hexadecimal value (example: color=0xFFFFCCFF), or from the set
|
243
|
+
# {black, brown, green, purple, yellow, blue, gray, orange, red, white}
|
244
|
+
# When a 32-bit hex value is specified, the last two characters specify the
|
245
|
+
# 8-bit alpha transparency value. This value varies between 00
|
246
|
+
# (completely transparent) and FF (completely opaque).
|
247
|
+
attr_accessor :color
|
248
|
+
|
249
|
+
# MapPositions for each point on the line
|
250
|
+
attr_accessor :points
|
251
|
+
|
252
|
+
# Pass an optional hash of arguments
|
253
|
+
def initialize(attrs={})
|
254
|
+
@points = []
|
255
|
+
attrs.each {|k,v| self.send("#{k}=".to_sym,v)}
|
256
|
+
end
|
257
|
+
|
258
|
+
def to_s
|
259
|
+
raise Exception.new("Need more than one point for the path") unless @points && @points.length > 1
|
260
|
+
attrs = GoogleStaticMapHelpers.safe_instance_variables(self, ["points"])
|
261
|
+
s = attrs.to_a.collect {|k| "#{k[0]}:#{CGI.escape(k[1].to_s)}"}.join("|")
|
262
|
+
s << "|" << @points.join("|")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# A polygon to draw and fill on the map. Has the same properties as a path
|
267
|
+
# with the addition of a fill color. The points do not need to form a closed
|
268
|
+
# loop, the last point will automatically be joined the first point
|
269
|
+
class MapPolygon < MapPath
|
270
|
+
# Color to fill in, either as a 24-bit (example: color=0xFFFFCC), a 32-bit
|
271
|
+
# hexadecimal value (example: color=0xFFFFCCFF), or from the set
|
272
|
+
# {black, brown, green, purple, yellow, blue, gray, orange, red, white}
|
273
|
+
# When a 32-bit hex value is specified, the last two characters specify the
|
274
|
+
# 8-bit alpha transparency value. This value varies between 00
|
275
|
+
# (completely transparent) and FF (completely opaque).
|
276
|
+
attr_accessor :fillcolor
|
277
|
+
|
278
|
+
def initialize(attrs={})
|
279
|
+
@points = []
|
280
|
+
attrs.each {|k,v| self.send("#{k}=".to_sym,v)}
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Helper methods used in this code
|
2
|
+
module GoogleStaticMapHelpers #:nodoc: all
|
3
|
+
# Returns a hash of instance variables for the passed in Object, where the
|
4
|
+
# key is the instance variable name ("@instance_variable"), and the value is
|
5
|
+
# the current instance variable value. This is safe for Ruby 1.8 and 1.9.
|
6
|
+
# Pass an optional array of instance variable name strings
|
7
|
+
# (["instance_variable_1", "instance_variable_2"]) to not include in the
|
8
|
+
# result. Example result:
|
9
|
+
# {"variable_1" => 123, "variable_2" => "2 value"}
|
10
|
+
# All inputs and outputs do NOT have the @ in the instance variable name
|
11
|
+
# options -
|
12
|
+
# :cgi_escape_values - set this to true to return all values as
|
13
|
+
# CGI escaped strings
|
14
|
+
def self.safe_instance_variables(object, ivs_to_exclude=[], options={})
|
15
|
+
ivs = {}
|
16
|
+
object.instance_variables.each do |i|
|
17
|
+
# Don't include the @
|
18
|
+
iv_name = i.to_s[1..-1]
|
19
|
+
unless ivs_to_exclude.include?(iv_name)
|
20
|
+
val = object.instance_variable_get(i)
|
21
|
+
val = CGI.escape(val.to_s) if options.has_key?(:cgi_escape_values)
|
22
|
+
ivs[iv_name] = val
|
23
|
+
end
|
24
|
+
end
|
25
|
+
ivs
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'cgi'
|
4
|
+
require 'net/http'
|
5
|
+
require 'mocha'
|
6
|
+
require File.dirname(__FILE__) + '/../lib/googlestaticmap'
|
7
|
+
|
8
|
+
class MockSuccess < Net::HTTPSuccess #:nodoc: all
|
9
|
+
def initialize
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MockFailure < Net::HTTPServiceUnavailable #:nodoc: all
|
14
|
+
def initialize
|
15
|
+
end
|
16
|
+
def code
|
17
|
+
100
|
18
|
+
end
|
19
|
+
def body
|
20
|
+
"epic fail"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class MockHttp #:nodoc: all
|
25
|
+
def initialize
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class GoogleStaticMapTest < Test::Unit::TestCase #:nodoc: all
|
30
|
+
|
31
|
+
class MockFile #:nodoc: all
|
32
|
+
@@file = nil
|
33
|
+
def self.open(name, &block)
|
34
|
+
@@file = {name => yield}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_exception_no_items
|
39
|
+
g = GoogleStaticMap.new
|
40
|
+
assert_raise Exception do
|
41
|
+
g.url
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_set_attributes
|
46
|
+
g = nil
|
47
|
+
assert_nothing_raised { g = default_map }
|
48
|
+
assert_equal 600, g.width
|
49
|
+
assert_equal "hybrid", g.maptype
|
50
|
+
assert_equal 1, g.markers.length
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_url
|
54
|
+
g = default_map
|
55
|
+
u = nil
|
56
|
+
assert_nothing_raised { u = g.url }
|
57
|
+
assert_equal 7, u.split("&").length, u
|
58
|
+
assert u.include?("size=600x400"), "width and height did not get converted in to a size"
|
59
|
+
assert u.include?("maptype=hybrid")
|
60
|
+
assert u.include?("scale=2")
|
61
|
+
assert u.include?("asdf")
|
62
|
+
assert u.include?("http://maps.google.com")
|
63
|
+
assert u.include?("color:0x00FF00FF|fillcolor:0x00FF0060|38.8,-77.5|38.8,-76.9|39.2,-76.9|39.2,-77.5|38.8,-77.5"), "Polygon not in URL"
|
64
|
+
assert u.include?("Washington%2C+DC")
|
65
|
+
|
66
|
+
f = nil
|
67
|
+
assert_nothing_raised {f = g.relative_url}
|
68
|
+
assert !f.include?("http://maps.google.com")
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_get_map_success_no_file
|
72
|
+
test_data = "asdf"
|
73
|
+
MockHttp.any_instance.expects(:get2).returns([MockSuccess.new,test_data])
|
74
|
+
Net::HTTP.expects(:new).returns(MockHttp.new)
|
75
|
+
|
76
|
+
g = default_map
|
77
|
+
r = nil
|
78
|
+
assert_nothing_raised {r = g.get_map}
|
79
|
+
assert_equal r, test_data
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_get_map_success_write_file
|
83
|
+
test_data = "asdf"
|
84
|
+
MockHttp.any_instance.expects(:get2).returns([MockSuccess.new,test_data])
|
85
|
+
Net::HTTP.expects(:new).returns(MockHttp.new)
|
86
|
+
file_data = ""
|
87
|
+
file_name = "testdata.png"
|
88
|
+
# File.open should be called, with the name of the file and write binary
|
89
|
+
# passed in. The object passed to the yield should be a file object that
|
90
|
+
# gets the test data appended to it. If we sub out a string for the
|
91
|
+
# file object we can later check the contents
|
92
|
+
File.expects(:open).with(file_name, "wb").yields(file_data)
|
93
|
+
g = default_map
|
94
|
+
r = nil
|
95
|
+
assert_nothing_raised {r = g.get_map(file_name)}
|
96
|
+
assert_equal r, test_data
|
97
|
+
assert_equal file_data, test_data
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def test_get_map_failure
|
102
|
+
MockHttp.any_instance.expects(:get2).returns([MockFailure.new,""])
|
103
|
+
Net::HTTP.expects(:new).returns(MockHttp.new)
|
104
|
+
g = default_map
|
105
|
+
assert_raise Exception do
|
106
|
+
g.get_map
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_get_map_nothing
|
111
|
+
MockHttp.any_instance.expects(:get2).returns(nil)
|
112
|
+
Net::HTTP.expects(:new).returns(MockHttp.new)
|
113
|
+
g = default_map
|
114
|
+
assert_raise Exception do
|
115
|
+
g.get_map
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def default_map
|
121
|
+
poly = MapPolygon.new(:color => "0x00FF00FF", :fillcolor => "0x00FF0060")
|
122
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
123
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -76.9)
|
124
|
+
poly.points << MapLocation.new(:latitude => 39.2, :longitude => -76.9)
|
125
|
+
poly.points << MapLocation.new(:latitude => 39.2, :longitude => -77.5)
|
126
|
+
poly.points << MapLocation.new(:latitude => 38.8, :longitude => -77.5)
|
127
|
+
|
128
|
+
GoogleStaticMap.new(:width => 600, :height => 400,
|
129
|
+
:markers => [MapMarker.new(:location => MapLocation.new(:address => "asdf"))],
|
130
|
+
:center => MapLocation.new(:address => "Washington, DC"),
|
131
|
+
:paths => [poly],
|
132
|
+
:scale => 2,
|
133
|
+
:maptype => "hybrid")
|
134
|
+
end
|
135
|
+
end
|
data/test/tc_helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cgi'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/googlestaticmap_helper'
|
4
|
+
|
5
|
+
class GoogleStaticMapHelperTest < Test::Unit::TestCase #:nodoc: all
|
6
|
+
|
7
|
+
IVS = {"@var1" => 1, "@var2" => 2, "@var3" => 3,
|
8
|
+
"@url" => "http://maps.google.com"}
|
9
|
+
|
10
|
+
class MockRuby18Object
|
11
|
+
def self.instance_variables
|
12
|
+
IVS.keys
|
13
|
+
end
|
14
|
+
def self.instance_variable_get(variable)
|
15
|
+
IVS[variable]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Ruby 1.9 refers to instance variables as symbols, like :@var1. The
|
20
|
+
# helper class needs to handle both cases
|
21
|
+
class MockRuby19Object
|
22
|
+
def self.instance_variables
|
23
|
+
IVS.keys.collect {|k| k.to_sym}
|
24
|
+
end
|
25
|
+
def self.instance_variable_get(variable)
|
26
|
+
IVS[variable.to_s]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def test_safe_instance_variables_no_params
|
32
|
+
[MockRuby18Object, MockRuby19Object].each do |o|
|
33
|
+
assert_equal ivs_no_at, GoogleStaticMapHelpers.safe_instance_variables(o)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_safe_instance_variables_exclude
|
38
|
+
[MockRuby18Object, MockRuby19Object].each do |o|
|
39
|
+
sivs = GoogleStaticMapHelpers.safe_instance_variables(o, ["var2"])
|
40
|
+
assert_equal IVS.length-1, sivs.length
|
41
|
+
assert !sivs.has_key?("@var2")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_safe_instance_variables_cgi
|
46
|
+
[MockRuby18Object, MockRuby19Object].each do |o|
|
47
|
+
sivs = GoogleStaticMapHelpers.safe_instance_variables(o, [], :cgi_escape_values => true)
|
48
|
+
assert_equal IVS.length, sivs.length
|
49
|
+
assert_equal CGI.escape(IVS["@url"]), sivs["url"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def ivs_no_at
|
55
|
+
ivs = {}
|
56
|
+
IVS.each do |k,v|
|
57
|
+
ivs[k[1..-1]] = v
|
58
|
+
end
|
59
|
+
ivs
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cgi'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/googlestaticmap'
|
4
|
+
|
5
|
+
class MapLocationTest < Test::Unit::TestCase #:nodoc: all
|
6
|
+
def test_exception_no_location
|
7
|
+
m = MapLocation.new
|
8
|
+
assert_raise Exception do
|
9
|
+
m.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_attributes_filled_in
|
14
|
+
m = MapLocation.new(:latitude => 39, :longitude => -77)
|
15
|
+
assert_equal "39", m.latitude
|
16
|
+
assert_equal "-77", m.longitude
|
17
|
+
assert_nil m.address
|
18
|
+
m = MapLocation.new(:address => "Washington, DC")
|
19
|
+
assert_equal "Washington, DC", m.address
|
20
|
+
assert_nil m.latitude
|
21
|
+
assert_nil m.longitude
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_with_address
|
25
|
+
m = MapLocation.new(:address => "Washington, DC")
|
26
|
+
s = ""
|
27
|
+
assert_nothing_raised { s = m.to_s }
|
28
|
+
assert_equal s, CGI.escape("Washington, DC")
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_with_latitude_longitude
|
32
|
+
m = MapLocation.new(:latitude => 39, :longitude => -77)
|
33
|
+
s = ""
|
34
|
+
assert_nothing_raised { s = m.to_s }
|
35
|
+
assert_equal s, "39,-77"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cgi'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/googlestaticmap'
|
4
|
+
|
5
|
+
class MapMarkerTest < Test::Unit::TestCase #:nodoc: all
|
6
|
+
def test_exception_no_location
|
7
|
+
m = MapMarker.new
|
8
|
+
assert_raise Exception do
|
9
|
+
m.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_exception_invalid_location
|
14
|
+
m = MapMarker.new
|
15
|
+
m.location = 99
|
16
|
+
assert_raise Exception do
|
17
|
+
m.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_set_parameters
|
22
|
+
m = nil
|
23
|
+
assert_nothing_raised { m = default_marker }
|
24
|
+
assert_equal "green", m.color
|
25
|
+
assert_equal "Washington, DC", m.location.address
|
26
|
+
assert_equal "tiny", m.size
|
27
|
+
assert_equal "B", m.label
|
28
|
+
assert_equal "http://www.google.com", m.icon
|
29
|
+
assert_equal false, m.shadow
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_get_string
|
33
|
+
m = default_marker
|
34
|
+
s = nil
|
35
|
+
assert_nothing_raised {s = m.to_s}
|
36
|
+
assert_equal 6, s.split("|").length
|
37
|
+
assert s.include?(CGI.escape("Washington, DC"))
|
38
|
+
assert s.include?("color:green")
|
39
|
+
assert s.include?("icon:http://www.google.com")
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def default_marker
|
44
|
+
MapMarker.new(:color => "green",
|
45
|
+
:location => MapLocation.new(:address => "Washington, DC"),
|
46
|
+
:size => "tiny",
|
47
|
+
:label => "B",
|
48
|
+
:icon => "http://www.google.com",
|
49
|
+
:shadow => false)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cgi'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/googlestaticmap'
|
4
|
+
|
5
|
+
class MapPathAndPolygonTest < Test::Unit::TestCase #:nodoc: all
|
6
|
+
def test_exception_no_points
|
7
|
+
m = MapPath.new
|
8
|
+
assert_raise Exception do
|
9
|
+
m.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_exception_empty_points
|
14
|
+
m = MapPath.new
|
15
|
+
m.points = [MapLocation.new(:address => "asdf")]
|
16
|
+
assert_raise Exception do
|
17
|
+
m.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_set_parameters
|
22
|
+
p = nil
|
23
|
+
assert_nothing_raised { p = default_path }
|
24
|
+
assert_equal 2, p.weight
|
25
|
+
assert_equal "0xFF0000FF", p.color
|
26
|
+
assert_equal 2, p.points.length
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_get_string
|
30
|
+
p = default_path
|
31
|
+
s = nil
|
32
|
+
assert_nothing_raised { s = p.to_s }
|
33
|
+
assert_equal 4, s.split("|").length
|
34
|
+
assert s.include?("color:0xFF0000FF")
|
35
|
+
assert s.include?("loc1")
|
36
|
+
assert s.include?("loc2")
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_polygon
|
40
|
+
# Polygon inherits from MapPath and uses MapPath's to_s method, so only
|
41
|
+
# limited testing needs to happen here
|
42
|
+
p = nil
|
43
|
+
assert_nothing_raised do
|
44
|
+
p = MapPolygon.new(:fillcolor => "0xFFFF00FF",
|
45
|
+
:color => "0xFF0000FF",
|
46
|
+
:points => [MapLocation.new(:address => "loc1"),
|
47
|
+
MapLocation.new(:address => "loc2")])
|
48
|
+
end
|
49
|
+
assert_equal "0xFFFF00FF", p.fillcolor
|
50
|
+
assert_equal "0xFF0000FF", p.color
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def default_path
|
55
|
+
MapPath.new(:weight => 2, :color => "0xFF0000FF",
|
56
|
+
:points => [MapLocation.new(:address => "loc1"),
|
57
|
+
MapLocation.new(:address => "loc2")])
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: googlestaticmap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brent Sowers
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-10-18 00:00:00 Z
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Easily retrieve single PNG, GIF, or JPG map images from Google with your own custom markers and paths using the Static Maps API service with this gem. Simply set the attributes you want for your map and GoogleStaticMap will take care of getting the map for you, or giving your the URL to retrieve the map.
|
17
|
+
email: brent@coordinatecommons.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- History.txt
|
25
|
+
files:
|
26
|
+
- lib/googlestaticmap.rb
|
27
|
+
- lib/googlestaticmap_helper.rb
|
28
|
+
- test/tc_map_path_and_polygon.rb
|
29
|
+
- test/tc_map_location.rb
|
30
|
+
- test/tc_google_static_map.rb
|
31
|
+
- test/tc_helper.rb
|
32
|
+
- test/tc_map_marker.rb
|
33
|
+
- README
|
34
|
+
- History.txt
|
35
|
+
homepage: http://www.coordinatecommons.com/googlestaticmap/
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.7
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: Class for retrieving maps from the Google Maps Static API service
|
62
|
+
test_files:
|
63
|
+
- test/tc_map_path_and_polygon.rb
|
64
|
+
- test/tc_map_location.rb
|
65
|
+
- test/tc_google_static_map.rb
|
66
|
+
- test/tc_helper.rb
|
67
|
+
- test/tc_map_marker.rb
|