Skip to content

Commit

Permalink
Split Google Maps APIs 2 and 3 into separate components.
Browse files Browse the repository at this point in the history
  • Loading branch information
dark-panda committed Jun 27, 2011
1 parent a8ce608 commit e42ca2c
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 47 deletions.
26 changes: 25 additions & 1 deletion README.rdoc
Expand Up @@ -31,7 +31,7 @@ ZGEL contains a number of enhancements to the GEOS Ruby library:
JavaScript output formats that we use for our applications. There are
also similar methods for outputting to WKT and WKB such as
Geos::Geometry#to_wkt, #to_kml, #to_georss and a number of methods to
output to Google Maps API v2-style JavaScript.
output to Google Maps API-style JavaScript.

* a bunch of helper methods to quickly grab some information from
geometries like Geos::Point#lat and Geos::Point#lng.
Expand Down Expand Up @@ -118,6 +118,30 @@ We've also included some Rails integration for PostGIS, including:
:limit => 10
)

=== Google Maps API Output

Starting with version 0.1.0, ZGEL supports both Google Maps API
version 2 and version 3 style outputs. By default and for the sake of
backwards compatibility, API version 2 output will remain the default
but as Google has deprecated API version 2, so shall we at some point
in the future. To switch between API versions, use the
Geos::GoogleMaps.use_api(version) method:

g = Geos.read('point(0 0)')
Geos::GoogleMaps.use_api(2)
puts g.to_g_marker
Geos::GoogleMaps.use_api(3)
puts g.to_g_marker

Outputs

new google.maps.Marker(new google.maps.LatLng(0.0, 0.0), {})
new google.maps.Marker({"position": new google.maps.LatLng(0.0, 0.0)})

At an unspecified point in the future, we'll likely make Google Maps
API version 3 the default, but for the time being, we'll stick with
version 2 since switching between the two is pretty painless.

=== Running ActiveRecord Tests

ActiveRecord unit tests can be run by setting the TEST_ACTIVERECORD
Expand Down
2 changes: 2 additions & 0 deletions lib/geos-extensions.rb
Expand Up @@ -9,3 +9,5 @@
require File.join(Geos::GEOS_EXTENSIONS_BASE, %w{ .. rails railtie })
end

Geos::GoogleMaps.use_api(2)

23 changes: 22 additions & 1 deletion lib/geos/google_maps.rb
@@ -1,7 +1,28 @@

module Geos
module GoogleMaps
class << self
def use_api(version)
version_const = Geos::GoogleMaps.const_get("Api#{version}")
version_const.constants.each do |c|
mod = version_const.const_get(c)
klass = Geos.const_get(c)
regex = %r{_api#{version}$}

if !klass.include?(mod)
klass.send(:include, mod)
end

mod.instance_methods.each do |method|
klass.send(:alias_method, method.to_s.sub(regex, ''), method)
end
end
end
end

autoload :PolylineEncoder, File.join(GEOS_EXTENSIONS_BASE, *%w{ geos google_maps polyline_encoder })
autoload :ApiIncluder, File.join(GEOS_EXTENSIONS_BASE, *%w{ geos google_maps api_includer })
autoload :Api2, File.join(GEOS_EXTENSIONS_BASE, *%w{ geos google_maps api_2 })
autoload :Api3, File.join(GEOS_EXTENSIONS_BASE, *%w{ geos google_maps api_3 })
end
end

75 changes: 34 additions & 41 deletions lib/geos/google_maps/api_2.rb
@@ -1,56 +1,53 @@

module Geos
class Geometry
module Geos::GoogleMaps::Api2
module Geometry
# Returns a new GLatLngBounds object with the proper GLatLngs in place
# for determining the geometry bounds.
def to_g_lat_lng_bounds(options = {})
def to_g_lat_lng_bounds_api2(options = {})
klass = if options[:short_class]
'GLatLngBounds'
else
'google.maps.LatLngBounds'
end

"new #{klass}(#{self.lower_left.to_g_lat_lng(options)}, #{self.upper_right.to_g_lat_lng(options)})"
"new #{klass}(#{self.lower_left.to_g_lat_lng_api2(options)}, #{self.upper_right.to_g_lat_lng_api2(options)})"
end

# Returns a String in Google Maps' GLatLngBounds#toString() format.
def to_g_lat_lng_bounds_string(precision = 10)
"((#{self.lower_left.to_g_url_value(precision)}), (#{self.upper_right.to_g_url_value(precision)}))"
def to_g_lat_lng_bounds_string_api2(precision = 10)
"((#{self.lower_left.to_g_url_value_api2(precision)}), (#{self.upper_right.to_g_url_value_api2(precision)}))"
end

# Returns a new GPolyline.
def to_g_polyline polyline_options = {}, options = {}
self.coord_seq.to_g_polyline polyline_options, options
def to_g_polyline_api2(polyline_options = {}, options = {})
self.coord_seq.to_g_polyline_api2(polyline_options, options)
end

# Returns a new GPolygon.
def to_g_polygon polygon_options = {}, options = {}
self.coord_seq.to_g_polygon polygon_options, options
def to_g_polygon_api2(polygon_options = {}, options = {})
self.coord_seq.to_g_polygon_api2(polygon_options, options)
end

# Returns a new GMarker at the centroid of the geometry. The options
# Hash works the same as the Google Maps API GMarkerOptions class does,
# but allows for underscored Ruby-like options which are then converted
# to the appropriate camel-cased Javascript options.
def to_g_marker marker_options = {}, options = {}
def to_g_marker_api2(marker_options = {}, options = {})
klass = if options[:short_class]
'GMarker'
else
'google.maps.Marker'
end

opts = marker_options.inject({}) do |memo, (k, v)|
memo[Geos::Helper.camelize(k.to_s)] = v
memo
end
opts = Geos::Helper.camelize_keys(marker_options)

"new #{klass}(#{self.centroid.to_g_lat_lng(options)}, #{opts.to_json})"
end
end

class CoordinateSequence
module CoordinateSequence
# Returns a Ruby Array of GLatLngs.
def to_g_lat_lng(options = {})
def to_g_lat_lng_api2(options = {})
klass = if options[:short_class]
'GLatLng'
else
Expand All @@ -69,18 +66,15 @@ def to_g_lat_lng(options = {})
# The options Hash follows the Google Maps API arguments to the
# GPolyline constructor and include :color, :weight, :opacity and
# :options. 'null' is used in place of any unset options.
def to_g_polyline polyline_options = {}, options = {}
def to_g_polyline_api2(polyline_options = {}, options = {})
klass = if options[:short_class]
'GPolyline'
else
'google.maps.Polyline'
end

poly_opts = if polyline_options[:polyline_options]
polyline_options[:polyline_options].inject({}) do |memo, (k, v)|
memo[Geos::Helper.camelize(k.to_s)] = v
memo
end
Geos::Helper.camelize_keys(polyline_options[:polyline_options])
end

args = [
Expand All @@ -101,18 +95,15 @@ def to_g_polyline polyline_options = {}, options = {}
# GPolygon constructor and include :stroke_color, :stroke_weight,
# :stroke_opacity, :fill_color, :fill_opacity and :options. 'null' is
# used in place of any unset options.
def to_g_polygon polygon_options = {}, options = {}
def to_g_polygon_api2(polygon_options = {}, options = {})
klass = if options[:short_class]
'GPolygon'
else
'google.maps.Polygon'
end

poly_opts = if polygon_options[:polygon_options]
polygon_options[:polygon_options].inject({}) do |memo, (k, v)|
memo[Geos::Helper.camelize(k.to_s)] = v
memo
end
Geos::Helper.camelize_keys(polygon_options[:polygon_options])
end

args = [
Expand All @@ -123,13 +114,13 @@ def to_g_polygon polygon_options = {}, options = {}
(polygon_options[:fill_opacity] || 'null'),
(poly_opts ? poly_opts.to_json : 'null')
].join(', ')
"new #{klass}([#{self.to_g_lat_lng(options).join(', ')}], #{args})"
"new #{klass}([#{self.to_g_lat_lng_api2(options).join(', ')}], #{args})"
end
end

class Point
module Point
# Returns a new GLatLng.
def to_g_lat_lng(options = {})
def to_g_lat_lng_api2(options = {})
klass = if options[:short_class]
'GLatLng'
else
Expand All @@ -140,7 +131,7 @@ def to_g_lat_lng(options = {})
end

# Returns a new GPoint
def to_g_point(options = {})
def to_g_point_api2(options = {})
klass = if options[:short_class]
'GPoint'
else
Expand All @@ -151,37 +142,39 @@ def to_g_point(options = {})
end
end

class Polygon
module Polygon
# Returns a GPolyline of the exterior ring of the Polygon. This does
# not take into consideration any interior rings the Polygon may
# have.
def to_g_polyline polyline_options = {}, options = {}
self.exterior_ring.to_g_polyline polyline_options, options
def to_g_polyline_api2(polyline_options = {}, options = {})
self.exterior_ring.to_g_polyline_api2(polyline_options, options)
end

# Returns a GPolygon of the exterior ring of the Polygon. This does
# not take into consideration any interior rings the Polygon may
# have.
def to_g_polygon polygon_options = {}, options = {}
self.exterior_ring.to_g_polygon polygon_options, options
def to_g_polygon_api2(polygon_options = {}, options = {})
self.exterior_ring.to_g_polygon_api2(polygon_options, options)
end
end

class GeometryCollection
module GeometryCollection
# Returns a Ruby Array of GPolylines for each geometry in the
# collection.
def to_g_polyline polyline_options = {}, options = {}
def to_g_polyline_api2(polyline_options = {}, options = {})
self.collect do |p|
p.to_g_polyline polyline_options, options
p.to_g_polyline_api2(polyline_options, options)
end
end

# Returns a Ruby Array of GPolygons for each geometry in the
# collection.
def to_g_polygon polygon_options = {}, options = {}
def to_g_polygon_api2(polygon_options = {}, options = {})
self.collect do |p|
p.to_g_polygon polygon_options, options
p.to_g_polygon_api2(polygon_options, options)
end
end
end
end

Geos::GoogleMaps.use_api(2)

0 comments on commit e42ca2c

Please sign in to comment.