ym4r 0.0.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +24 -8
- data/lib/ym4r.rb +3 -4
- data/lib/ym4r/google_maps.rb +7 -0
- data/lib/ym4r/google_maps/api_key.rb +10 -0
- data/lib/ym4r/google_maps/config/config.yml +1 -0
- data/lib/ym4r/google_maps/control.rb +59 -0
- data/lib/ym4r/google_maps/helper.rb +19 -0
- data/lib/ym4r/google_maps/map.rb +94 -0
- data/lib/ym4r/google_maps/mapping.rb +70 -0
- data/lib/ym4r/google_maps/overlay.rb +125 -0
- data/lib/ym4r/google_maps/point.rb +34 -0
- data/lib/ym4r/yahoo_maps.rb +2 -0
- data/lib/ym4r/yahoo_maps/app_id.rb +5 -0
- data/lib/ym4r/yahoo_maps/building_block.rb +4 -0
- data/lib/ym4r/yahoo_maps/building_block/exception.rb +21 -0
- data/lib/ym4r/yahoo_maps/building_block/geocoding.rb +81 -0
- data/lib/ym4r/yahoo_maps/building_block/local_search.rb +156 -0
- data/lib/ym4r/yahoo_maps/building_block/map_image.rb +75 -0
- data/lib/ym4r/yahoo_maps/building_block/traffic.rb +120 -0
- data/lib/ym4r/yahoo_maps/flash.rb +7 -0
- data/lib/ym4r/yahoo_maps/flash/latlon.rb +18 -0
- data/lib/ym4r/yahoo_maps/flash/map.rb +74 -0
- data/lib/ym4r/yahoo_maps/flash/mapping.rb +71 -0
- data/lib/ym4r/yahoo_maps/flash/marker.rb +43 -0
- data/lib/ym4r/yahoo_maps/flash/overlay.rb +44 -0
- data/lib/ym4r/yahoo_maps/flash/tool.rb +30 -0
- data/lib/ym4r/yahoo_maps/flash/widget.rb +33 -0
- data/rakefile.rb +4 -4
- data/test/test_geocoding.rb +3 -3
- data/test/test_local_search.rb +2 -2
- data/test/test_map_image.rb +3 -3
- data/test/test_maps.rb +14 -0
- data/test/test_traffic.rb +1 -1
- metadata +30 -9
- data/lib/ym4r/app_id.rb +0 -3
- data/lib/ym4r/building_block/geocoding.rb +0 -81
- data/lib/ym4r/building_block/local_search.rb +0 -156
- data/lib/ym4r/building_block/map_image.rb +0 -76
- data/lib/ym4r/building_block/traffic.rb +0 -120
- data/lib/ym4r/exception.rb +0 -18
data/README
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
=YM4R
|
2
|
-
The goal of YM4R is to ease the use of
|
2
|
+
This is YM4R 0.1.2. The goal of YM4R (YM4R Maps For Ruby) is to ease the use of the Google Maps and Yahoo! Maps API's (including the Geocoding, Map Image, Traffic and Local Search API's) from Ruby and Rails.
|
3
3
|
|
4
4
|
===Operations
|
5
|
-
|
5
|
+
====Google Maps
|
6
|
+
You can use the library to display maps easily from your rails application. Update through RJS is possible. Check out the tutorial at http://thepochisuperstarmegashow.com/2006/06/02/ym4r-georuby-spatial-adapter-demo/
|
6
7
|
|
7
|
-
|
8
|
+
====Yahoo Maps
|
9
|
+
There is at the moment preliminary support for the JS-Flash Yahoo! Maps API, although it is not very polished. Check back next version!
|
10
|
+
|
11
|
+
====Yahoo Maps Building Block API
|
12
|
+
Building Block API's (Geocoding, Map Image, Traffic and Local Search) are supported. You have to pass to the +get+ method of the module a hash whose keys are a rubyfied version of the request parameters. You get back a ruby object, with accessors that let you get the returned data in a easy way. You get an exception if not all the parameters have been passed, if the connection to the service could not be made or if the parameters you have passed are of the incorrect value.
|
13
|
+
|
14
|
+
To know what parameters to pass to the +get+ methods and what results you should expect, you should consult the documentation for the building block API's on Yahoo!'s website : http://developer.yahoo.com/maps/index.html#mapsBuildingBlocks .
|
8
15
|
|
9
16
|
Here are some examples and notes about using the different Building Block API's.
|
10
|
-
|
17
|
+
=====Geocoding
|
11
18
|
Here is an example of request:
|
12
19
|
require 'ym4r'
|
13
20
|
include Ym4r::BuildingBlock
|
@@ -17,7 +24,7 @@ Here is an example of request:
|
|
17
24
|
:zip => "95014")
|
18
25
|
+results+ is an array of Geocoding::Result objects. The API can return up to 50 results for one request. Read the documentation page of the Geocoding::Result class to know how to access the data.
|
19
26
|
|
20
|
-
|
27
|
+
=====Map Image
|
21
28
|
Here is an example of request:
|
22
29
|
require 'ym4r'
|
23
30
|
include Ym4r::BuildingBlock
|
@@ -28,7 +35,7 @@ Here is an example of request:
|
|
28
35
|
:image_type => "png")
|
29
36
|
+result+ is a MapImage::Result object contains the URL for the requested image. You can download this image to a file by calling +download_to+ and passing a path.
|
30
37
|
|
31
|
-
|
38
|
+
=====Traffic
|
32
39
|
Here is an example of request:
|
33
40
|
require 'ym4r'
|
34
41
|
include Ym4r::BuildingBlock
|
@@ -39,7 +46,7 @@ Here is an example of request:
|
|
39
46
|
:include_map => true)
|
40
47
|
+results+ is a Traffic::ResultSet object (subclass of +Array+), containing Traffic::Result objects, each containing information about one traffic incident.
|
41
48
|
|
42
|
-
|
49
|
+
=====Local Search
|
43
50
|
Here is an example of request:
|
44
51
|
require 'ym4r'
|
45
52
|
include Ym4r::BuildingBlock
|
@@ -50,8 +57,17 @@ Here is an example of request:
|
|
50
57
|
:query => "chinese")
|
51
58
|
+results+ is a LocalSearch::ResultSet object (subclass of +Array+), containing LocalSearch::Result objects, each containing information about one hit on the Yahoo! local search.
|
52
59
|
|
60
|
+
===Changes since last version
|
61
|
+
- Addition of support for the Google Maps API
|
62
|
+
- Addition of preliminary support for the Yahoo! Maps JS-Flash API
|
63
|
+
|
64
|
+
===TODO
|
65
|
+
- Documentation! Documentation! Documentation!
|
66
|
+
- Tutorials
|
67
|
+
- Finish the support for the Yahoo! Maps JS-Flash API
|
68
|
+
|
53
69
|
===Disclaimer
|
54
|
-
This software is not endorsed in any way by Yahoo
|
70
|
+
This software is not endorsed in any way by Yahoo! or Google.
|
55
71
|
|
56
72
|
===License
|
57
73
|
YM4R is released under the MIT license.
|
data/lib/ym4r.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'ym4r/
|
2
|
-
require 'ym4r/
|
3
|
-
|
4
|
-
require 'ym4r/building_block/local_search'
|
1
|
+
require 'ym4r/yahoo_maps'
|
2
|
+
require 'ym4r/google_maps'
|
3
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
ABQIAAAAzMUFFnT9uH0xq39J0Y4kbhTJQa0g3IQ9GZqIMmInSLzwtGDKaBR6j135zrztfTGVOm2QlWnkaidDIQ
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'ym4r/google_maps/mapping'
|
2
|
+
|
3
|
+
module Ym4r
|
4
|
+
module GoogleMaps
|
5
|
+
class GSmallMapControl
|
6
|
+
include MappingObject
|
7
|
+
def create
|
8
|
+
"new GSmallMapControl()"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
class GLargeMapControl
|
12
|
+
include MappingObject
|
13
|
+
def create
|
14
|
+
"new GLargeMapControl()"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class GSmallZoomControl
|
18
|
+
include MappingObject
|
19
|
+
def create
|
20
|
+
"new GSmallZoomControl()"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
class GScaleControl
|
24
|
+
include MappingObject
|
25
|
+
def create
|
26
|
+
"new GScaleControl()"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
class GMapTypeControl
|
30
|
+
include MappingObject
|
31
|
+
def create
|
32
|
+
"new GMapTypeControl()"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
class GOverviewMapControl
|
36
|
+
include MappingObject
|
37
|
+
def create
|
38
|
+
"new GOverviewMapControl()"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#The first argument of the constructor is oneof the following : :top_right, :top_left, :bottom_right, :bottom_left
|
43
|
+
class GControlPosition < Struct.new(:anchor,:offset)
|
44
|
+
include MappingObject
|
45
|
+
def create
|
46
|
+
js_anchor = if anchor == :top_right
|
47
|
+
"G_ANCHOR_TOP_RIGHT"
|
48
|
+
elsif anchor == :top_left
|
49
|
+
"G_ANCHOR_TOP_LEFT"
|
50
|
+
elsif anchor == :bottom_right
|
51
|
+
"G_ANCHOR_BOTTOM_RIGHT"
|
52
|
+
else
|
53
|
+
"G_ANCHOR_BOTTOM_LEFT"
|
54
|
+
end
|
55
|
+
"new GControlPosition(#{js_anchor},#{offset})"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
Ym4r::GoogleMaps::GPolyline.class_eval do
|
3
|
+
def self.from_georuby(line_string,color = nil,weight = nil,opacity = nil)
|
4
|
+
GPolyline.new(line_string.points.collect { |point| GLatLng.new([point.y,point.x])},color,weight,opacity)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
Ym4r::GoogleMaps::GMarker.class_eval do
|
9
|
+
def self.from_georuby(point,options = {})
|
10
|
+
GMarker.new([point.y,point.x],options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Ym4r::GoogleMaps::GLatLng.class_eval do
|
15
|
+
def self.from_georuby(point,unbounded = nil)
|
16
|
+
GLatLng.new([point.y,point.x],unbounded)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Ym4r
|
2
|
+
module GoogleMaps
|
3
|
+
class GMap
|
4
|
+
include MappingObject
|
5
|
+
|
6
|
+
VML_NAMESPACE = "xmlns:v=\"urn:schemas-microsoft-com:vml\""
|
7
|
+
|
8
|
+
attr_reader :container
|
9
|
+
|
10
|
+
def initialize(container, variable = "map")
|
11
|
+
@container = container
|
12
|
+
@variable = variable
|
13
|
+
@init = ""
|
14
|
+
@global_init = ""
|
15
|
+
end
|
16
|
+
|
17
|
+
def header(with_vml = true)
|
18
|
+
a = "<script src=\"http://maps.google.com/maps?file=api&v=2&key=#{API_KEY}\" type=\"text/javascript\"></script>\n"
|
19
|
+
a << "<style type=\"text/css\">\n v\:* { behavior:url(#default#VML);}\n</style>" if with_vml
|
20
|
+
a
|
21
|
+
end
|
22
|
+
|
23
|
+
def header_width_height(width,height)
|
24
|
+
"<style type=\"text/css\">\n##{@container} { height: #{height}px;\n width: #{width}px;\n}\n</style>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def record_init(code)
|
28
|
+
@init << code
|
29
|
+
end
|
30
|
+
|
31
|
+
def control_init(controls = {})
|
32
|
+
@init << add_control(GSmallMapControl.new) if controls[:small_map]
|
33
|
+
@init << add_control(GLargeMapControl.new) if controls[:large_map]
|
34
|
+
@init << add_control(GSmallZoomControl.new) if controls[:small_zoom]
|
35
|
+
@init << add_control(GScaleControl.new) if controls[:scale]
|
36
|
+
@init << add_control(GMapTypeControl.new) if controls[:map_type]
|
37
|
+
@init << add_control(GOverviewMapControl.new) if controls[:overview_map]
|
38
|
+
end
|
39
|
+
|
40
|
+
def center_zoom_init(center, zoom)
|
41
|
+
if center.is_a?(GLatLng)
|
42
|
+
@init << set_center(center,zoom)
|
43
|
+
else
|
44
|
+
@init << set_center(GLatLng.new(center),zoom)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def record_global_init(code)
|
49
|
+
@global_init << code
|
50
|
+
end
|
51
|
+
|
52
|
+
def icon_init(icon , variable)
|
53
|
+
@global_init << icon.declare(variable)
|
54
|
+
end
|
55
|
+
|
56
|
+
#allow :script, :no_script and :load in the method parameter. If the :load parameter has been chose, the load_method parameter must be filled too.
|
57
|
+
def to_html(options = {})
|
58
|
+
no_load = options[:no_load]
|
59
|
+
load_method = options[:load_method] || "load"
|
60
|
+
no_script_tag = options[:no_script_tag]
|
61
|
+
no_declare = options[:no_declare]
|
62
|
+
no_global = options[:no_global]
|
63
|
+
|
64
|
+
html = ""
|
65
|
+
html << "<script type=\"text/javascript\">\n" if !no_script_tag
|
66
|
+
html << "function addInfoWindowToMarker(marker,info){\nGEvent.addListener(marker, \"click\", function() {\nmarker.openInfoWindowHtml(info);\n});\nreturn marker;\n}\n"
|
67
|
+
html << "function addInfoWindowTabsToMarker(marker,info){\nGEvent.addListener(marker, \"click\", function() {\nmarker.openInfoWindowTabsHtml(info);\n});\nreturn marker;\n}\n"
|
68
|
+
html << @global_init
|
69
|
+
html << "var #{@variable};\n" if !no_declare and !no_global
|
70
|
+
html << "function #{load_method}() {\nif (GBrowserIsCompatible()) {\n" if !no_load
|
71
|
+
if !no_declare and no_global
|
72
|
+
html << declare(@variable)
|
73
|
+
else
|
74
|
+
html << assign_to(@variable)
|
75
|
+
end
|
76
|
+
html << @init
|
77
|
+
html << "}\n}\n" if !no_load
|
78
|
+
html << "</script>" if !no_script_tag
|
79
|
+
html
|
80
|
+
end
|
81
|
+
|
82
|
+
def create
|
83
|
+
"new GMap2(document.getElementById(\"#{@container}\"))"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module GMapType
|
88
|
+
G_NORMAL_MAP = Variable.new("GMapType.G_NORMAL_MAP")
|
89
|
+
G_SATELLITE_MAP = Variable.new("GMapType.G_SATELLITE_MAP")
|
90
|
+
G_HYBRID_MAP = Variable.new("GMapType.G_HYBRID_MAP")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Ym4r
|
2
|
+
module GoogleMaps
|
3
|
+
module MappingObject
|
4
|
+
attr_reader :variable
|
5
|
+
|
6
|
+
#creates javascript code for missing methods
|
7
|
+
def method_missing(name,*args)
|
8
|
+
args.collect! do |arg|
|
9
|
+
javascriptify_variable(arg)
|
10
|
+
end
|
11
|
+
"#{to_javascript}.#{javascriptify_method(name.to_s)}(#{args.join(",")});\n"
|
12
|
+
end
|
13
|
+
|
14
|
+
def javascriptify_variable(arg)
|
15
|
+
if arg.is_a?(MappingObject)
|
16
|
+
arg.to_javascript
|
17
|
+
elsif arg.is_a?(String)
|
18
|
+
"\"#{escape_javascript(arg)}\""
|
19
|
+
else
|
20
|
+
arg.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#lifted from rails
|
25
|
+
def escape_javascript(javascript)
|
26
|
+
javascript.gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
27
|
+
end
|
28
|
+
|
29
|
+
#transform a ruby-type method name (like qsd_fghj) to a Yahoo! Map style one (like qsdFghj)
|
30
|
+
def javascriptify_method(method_name)
|
31
|
+
method_name.gsub(/_(\w)/){|s| $1.upcase}
|
32
|
+
end
|
33
|
+
|
34
|
+
#Declare Mapping Object (Map, Tool, Marker,...) of name variable
|
35
|
+
def declare(variable)
|
36
|
+
@variable = variable
|
37
|
+
"var #{variable} = #{create};\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def assign_to(variable)
|
41
|
+
@variable = variable
|
42
|
+
"#{variable} = #{create};\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
#Returns a Javascript script representing the object
|
46
|
+
def to_javascript
|
47
|
+
unless @variable.nil?
|
48
|
+
@variable
|
49
|
+
else
|
50
|
+
create
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#Creates a Mapping Object in Javascript
|
55
|
+
#To be implemented by subclasses if needed
|
56
|
+
def create
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
class Variable
|
62
|
+
include MappingObject
|
63
|
+
|
64
|
+
def initialize(variable)
|
65
|
+
@variable = variable
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'ym4r/google_maps/mapping'
|
2
|
+
|
3
|
+
module Ym4r
|
4
|
+
module GoogleMaps
|
5
|
+
class GMarker
|
6
|
+
include MappingObject
|
7
|
+
attr_accessor :point, :options, :info_window, :info_window_tabs
|
8
|
+
#options keys can be : :icon, :clickable and :title: Defaults to G_DEFAULT_ICON, true and empty. :info_window can also be input. However in order to be taken into account, the marker has to be declared at some point
|
9
|
+
def initialize(point, options = {})
|
10
|
+
if point.is_a?(Array)
|
11
|
+
@point = GLatLng.new(point)
|
12
|
+
else
|
13
|
+
@point = point
|
14
|
+
end
|
15
|
+
@info_window = options.delete(:info_window)
|
16
|
+
@tab_info_window = options.delete(:info_window_tabs)
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
def create
|
20
|
+
if @options.empty?
|
21
|
+
creation = "new GMarker(#{@point.to_javascript})"
|
22
|
+
else
|
23
|
+
options = "{"
|
24
|
+
options << @options.to_a.collect do |v|
|
25
|
+
"#{v[0].to_s} : #{javascriptify_variable(v[1])}"
|
26
|
+
end.join(",")
|
27
|
+
options << "}"
|
28
|
+
creation = "new GMarker(#{@point.to_javascript},#{options})"
|
29
|
+
end
|
30
|
+
if @info_window
|
31
|
+
"addInfoWindowToMarker(#{creation},#{javascriptify_variable(@info_window)})"
|
32
|
+
elsif @tab_info_window
|
33
|
+
"addInfoWindowTabsToMarker(#{creation},[#{@tab_info_window.collect{ |tab| tab.to_javascript}.join(",")}])"
|
34
|
+
else
|
35
|
+
creation
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class GInfoWindowTab < Struct.new(:tab,:content)
|
41
|
+
include MappingObject
|
42
|
+
def create
|
43
|
+
"new GInfoWindowTab(#{javascriptify_variable(tab)},#{javascriptify_variable(content)})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#Icon class. You can pass rubyfied versions of the attributes detailed in the Google Maps API documentation. You can initialize global icons to be used in the application by passing a icon object, along with a variable name, to GMap#icon_init. If you want to declare an icon outside this, you will need to declare it first.
|
48
|
+
class GIcon
|
49
|
+
include MappingObject
|
50
|
+
DEFAULT = Variable.new("G_DEFAULT_ICON")
|
51
|
+
attr_accessor :options, :copy_base
|
52
|
+
|
53
|
+
#Options can contain all the attributes (in rubifiedformat) of an GIconobject (see Google's doc) + :copy_base, which indicates if the icon is copied from another one
|
54
|
+
def initialize(options = {})
|
55
|
+
@copy_base = options.delete(:copy_base)
|
56
|
+
@options = options
|
57
|
+
end
|
58
|
+
def create
|
59
|
+
if @copy_base
|
60
|
+
"new GIcon(#{@copy_base.to_javascript})"
|
61
|
+
else
|
62
|
+
"new GIcon()"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def declare(variable)
|
66
|
+
decl = super(variable)
|
67
|
+
@options.each do |key,value|
|
68
|
+
decl << "#{variable}.#{javascriptify_method(key.to_s)} = #{javascriptify_variable(value)};\n"
|
69
|
+
end
|
70
|
+
decl
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
#A polyline. Can take an array of GLatLng or an array of 2D arrays. A method to build a polyline from a GeoRuby linestring is provided in the helper.rb file.
|
75
|
+
class GPolyline
|
76
|
+
include MappingObject
|
77
|
+
attr_accessor :points,:color,:weight,:opacity
|
78
|
+
def initialize(points,color = nil,weight = nil,opacity = nil)
|
79
|
+
if !points.empty? and points[0].is_a?(Array)
|
80
|
+
@points = points.collect { |pt| GLatLng.new(pt) }
|
81
|
+
else
|
82
|
+
@points = points
|
83
|
+
end
|
84
|
+
@color = color
|
85
|
+
@weight = weight
|
86
|
+
@opacity = opacity
|
87
|
+
end
|
88
|
+
def create
|
89
|
+
a = "new GPolyline([#{@points.collect{|pt| pt.to_javascript}.join(",")}]"
|
90
|
+
a << ",#{javascriptify_variable(@color)}" if @color
|
91
|
+
a << ",#{javascriptify_variable(@weight)}" if @weight
|
92
|
+
a << ",#{javascriptify_variable(@opacity)}" if @opacity
|
93
|
+
a << ")"
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
#A basic Latitude/longitude point.
|
99
|
+
class GLatLng
|
100
|
+
include MappingObject
|
101
|
+
attr_accessor :lat,:lng,:unbounded
|
102
|
+
|
103
|
+
def initialize(latlng,unbounded = nil)
|
104
|
+
@lat = latlng[0]
|
105
|
+
@lng = latlng[1]
|
106
|
+
@unbounded = unbounded
|
107
|
+
end
|
108
|
+
def create
|
109
|
+
unless @unbounded
|
110
|
+
"new GLatLng(#{@lat},#{@lng})"
|
111
|
+
else
|
112
|
+
"new GLatLng(#{@lat},#{@lng},#{@unbounded})"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class GLatLngBounds < Struct.new(:sw,:ne)
|
118
|
+
include MappingObject
|
119
|
+
def create
|
120
|
+
"new GLatLngBounds(#{sw},#{ne})"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|