geos-extensions 0.2.2 → 0.3.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.
Files changed (55) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +17 -0
  4. data/Guardfile +17 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.rdoc +19 -91
  7. data/Rakefile +1 -12
  8. data/geos-extensions.gemspec +1 -9
  9. data/lib/geos-extensions.rb +1 -9
  10. data/lib/geos/coordinate_sequence.rb +92 -0
  11. data/lib/geos/extensions/version.rb +1 -1
  12. data/lib/geos/geometry.rb +252 -0
  13. data/lib/geos/geometry_collection.rb +60 -0
  14. data/lib/geos/geos_helper.rb +86 -72
  15. data/lib/geos/google_maps.rb +1 -0
  16. data/lib/geos/google_maps/api_2.rb +9 -23
  17. data/lib/geos/google_maps/api_3.rb +10 -24
  18. data/lib/geos/google_maps/api_common.rb +41 -0
  19. data/lib/geos/line_string.rb +15 -0
  20. data/lib/geos/multi_line_string.rb +15 -0
  21. data/lib/geos/multi_point.rb +15 -0
  22. data/lib/geos/multi_polygon.rb +27 -0
  23. data/lib/geos/point.rb +120 -0
  24. data/lib/geos/polygon.rb +158 -0
  25. data/lib/geos/yaml.rb +30 -0
  26. data/lib/geos/yaml/psych.rb +18 -0
  27. data/lib/geos/yaml/syck.rb +41 -0
  28. data/lib/geos_extensions.rb +110 -711
  29. data/test/google_maps_api_2_tests.rb +54 -32
  30. data/test/google_maps_api_3_tests.rb +58 -36
  31. data/test/google_maps_polyline_encoder_tests.rb +1 -1
  32. data/test/helper_tests.rb +28 -0
  33. data/test/misc_tests.rb +130 -10
  34. data/test/reader_tests.rb +38 -1
  35. data/test/test_helper.rb +54 -146
  36. data/test/writer_tests.rb +329 -10
  37. data/test/yaml_tests.rb +203 -0
  38. metadata +26 -102
  39. data/app/models/geos/geometry_column.rb +0 -39
  40. data/app/models/geos/spatial_ref_sys.rb +0 -12
  41. data/lib/geos/active_record_extensions.rb +0 -12
  42. data/lib/geos/active_record_extensions/connection_adapters/postgresql_adapter.rb +0 -151
  43. data/lib/geos/active_record_extensions/spatial_columns.rb +0 -367
  44. data/lib/geos/active_record_extensions/spatial_scopes.rb +0 -493
  45. data/lib/geos/rails/engine.rb +0 -6
  46. data/lib/tasks/test.rake +0 -42
  47. data/test/adapter_tests.rb +0 -38
  48. data/test/database.yml +0 -17
  49. data/test/fixtures/foo3ds.yml +0 -16
  50. data/test/fixtures/foo_geographies.yml +0 -16
  51. data/test/fixtures/foos.yml +0 -16
  52. data/test/geography_columns_tests.rb +0 -176
  53. data/test/geometry_columns_tests.rb +0 -178
  54. data/test/spatial_scopes_geographies_tests.rb +0 -107
  55. data/test/spatial_scopes_tests.rb +0 -337
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDdiYzQwZjU5MjYzNDMzNDI4ZGZjOTI5NmI0Yzc2NDJjOTYxNzE1Zg==
5
+ data.tar.gz: !binary |-
6
+ NDc0MWJiM2RmOTJiMzE5NTA2NGM3ZmZhMmQ3MDk1YWZjZTEwNmRkNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MGM2NDQ3ODUzYTBkM2Y3OGViZGZkNWE3OTc2OTA4NWE1NTc3OTc5ZTM2MTZj
10
+ MGMwNDA0OTY2Nzg4MTQ5OWRiMDlkODYwMjc4ZDhlZmJjMTQxMjFjMjVkZTAx
11
+ MzRmYTFmNmY2ZTk2NTdjZTI3Zjc4NTFlNWI0Y2UzMWYyZjFkZDA=
12
+ data.tar.gz: !binary |-
13
+ YTkxYzA1NTMzYTdjNzU4NmFkZTY4YTEwNjM5MjhjYWE1MWMzNTJmOWM1MTNi
14
+ ZTE5YjJhZDU3MDY2M2JjMzUyZGIyYWQxM2E5OGM2MGNkZTRhMDQ1ZTVjYTc1
15
+ MDg4YjdhY2VjOWFkMzNjNzM4NWRjZjRiOTRlM2QxZTI5YmY2Yjc=
data/.gitignore CHANGED
@@ -8,6 +8,7 @@
8
8
  *tmp*
9
9
  pkg/
10
10
  doc/
11
+ coverage/
11
12
  *.orig
12
13
  *.patch
13
14
  .vimrc_local
@@ -19,3 +20,5 @@ test/local_database.yml
19
20
  .config
20
21
  .yardoc
21
22
  Gemfile.lock
23
+ Gemfile.local
24
+ Guardfile.local
data/Gemfile CHANGED
@@ -1,3 +1,20 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem "rdoc", "~> 3.12"
6
+ gem "rake", "~> 10.0"
7
+ gem "minitest"
8
+ gem "minitest-reporters"
9
+ gem "guard-minitest"
10
+ gem "simplecov"
11
+
12
+ if RbConfig::CONFIG['host_os'] =~ /^darwin/
13
+ gem "rb-fsevent"
14
+ gem "growl"
15
+ end
16
+
17
+ if File.exists?('Gemfile.local')
18
+ instance_eval File.read('Gemfile.local')
19
+ end
20
+
@@ -0,0 +1,17 @@
1
+
2
+ guard 'minitest', :test_folders => 'test', :test_file_patterns => '*_tests.rb' do
3
+ watch(%r|^test/(.+)_tests\.rb|)
4
+
5
+ watch(%r|^lib/(.*)([^/]+)\.rb|) do |m|
6
+ "test/#{m[1]}#{m[2]}_tests.rb"
7
+ end
8
+
9
+ watch(%r|^test/test_helper\.rb|) do
10
+ "test"
11
+ end
12
+ end
13
+
14
+ if File.exists?('Guardfile.local')
15
+ instance_eval File.read('Guardfile.local')
16
+ end
17
+
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 2167961 Ontario Inc., Zoocasa <code@zoocasa.com>
1
+ Copyright (c) 2013 2167961 Ontario Inc., Zoocasa <code@zoocasa.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
@@ -1,5 +1,5 @@
1
1
 
2
- == Zoocasa GEOS Extensions
2
+ = Zoocasa GEOS Extensions
3
3
 
4
4
  The Zoocasa GEOS Extensions library (ZGEL) is a set of utilities and tools that
5
5
  extend the GEOS Ruby bindings module. From http://geos.refractions.net/ ...
@@ -46,85 +46,7 @@ ZGEL contains a number of enhancements to the GEOS Ruby library:
46
46
 
47
47
  * Geos::GeometryCollection has been made an Enumerable.
48
48
 
49
- We've also included some Rails integration for PostGIS, including:
50
-
51
- * automatic detection of geometry columns and just-in-time conversions
52
- for input and output to and from WKB when using PostGIS. This allows
53
- you to do stuff like this with your ActiveRecord models:
54
-
55
- m = MyModel.find(12345)
56
- m.the_geom # => spits out the untouched geometry value as a string in WKB
57
- m.the_geom_geos # => spits out the geometry wrapped in a Geos::Geometry object
58
- m.the_geom = 'POINT(0 0)' # => setters will automatically make
59
- conversions from any of the formats that the Geos.read can recognize,
60
- so Google Maps formats, WKT, WKB, etc. are all converted
61
- automatically.
62
- m.the_geom_wkt # => automatically converts to a WKT string
63
- m.the_geom_wkb_bin # => automatically converts to WKB in binary
64
-
65
- There's also some funky SRID handling code that will automatically
66
- look in the geometry_columns table to make conversions for you when
67
- necessary. Saving WKT as "SRID=default; POINT(0 0)" for instance will
68
- automatically set the SRID when saving the ActiveRecord, or the SRID
69
- can be specified manually.
70
-
71
- * multiple geometry columns are supported and detected for
72
- automatically. These column accessors are all generated dynamically at
73
- run time.
74
-
75
- * automatic generation of named scopes for ActiveRecord models. The
76
- usual suspects are supported:
77
-
78
- * st_contains
79
- * st_containsproperly
80
- * st_covers
81
- * st_coveredby
82
- * st_crosses
83
- * st_disjoint
84
- * st_equals
85
- * st_intersects
86
- * st_orderingequals
87
- * st_overlaps
88
- * st_touches
89
- * st_within
90
- * st_dwithin
91
-
92
- Ordering scopes are also included:
93
-
94
- * order_by_ndims
95
- * order_by_npoints
96
- * order_by_nrings
97
- * order_by_numgeometries
98
- * order_by_numinteriorring
99
- * order_by_numinteriorrings
100
- * order_by_numpoints
101
- * order_by_length3d
102
- * order_by_length
103
- * order_by_length2d
104
- * order_by_perimeter
105
- * order_by_perimeter2d
106
- * order_by_perimeter3d
107
- * order_by_distance
108
- * order_by_distance_sphere
109
- * order_by_maxdistance
110
- * order_by_hausdorffdistance
111
- * order_by_distance_spheroid
112
- * order_by_length2d_spheroid
113
- * order_by_length3d_spheroid
114
- * order_by_length_spheroid
115
-
116
- These let you chain together scopes to build geospatial queries:
117
-
118
- neighbourhood = Neighbourhood.find(12345)
119
- my_model = MyModel.active.
120
- recent.
121
- st_within(neighbourhood.the_geom_geos.envelope).
122
- st_dwithin(point, 0.1).
123
- all(
124
- :limit => 10
125
- )
126
-
127
- === Google Maps API Output
49
+ == Google Maps API Output
128
50
 
129
51
  Starting with version 0.1.0, ZGEL supports both Google Maps API
130
52
  version 2 and version 3 style outputs. By default and for the sake of
@@ -148,14 +70,20 @@ At an unspecified point in the future, we'll likely make Google Maps
148
70
  API version 3 the default, but for the time being, we'll stick with
149
71
  version 2 since switching between the two is pretty painless.
150
72
 
151
- === Running ActiveRecord Tests
152
-
153
- ActiveRecord unit tests can be run by setting the TEST_ACTIVERECORD
154
- environment variable when running `rake test`. The test database name
155
- is geos_extensions_unit_tests and requires PostGIS to be installed. The
156
- test scripts will try to find your postgis.sql and spatial_ref_sys.sql
157
- files, but if it needs a hint, set the POSTGIS_PATH environment variable
158
- to the directory the files are in to create the database properly. You
159
- can also set the database up manually before running the tests -- just
160
- make sure the database has PostGIS installed with the spatial_ref_sys
161
- table populated and you'll be fine.
73
+ == ActiveRecord Extensions
74
+
75
+ This extension used to contain a bunch of extensions to ActiveRecord, but as of
76
+ version 0.3.0 we have decided to strip those extensions out and move them into
77
+ their own gem called activerecord-spatial available at
78
+ https://github.com/zoocasa/activerecord-spatial .
79
+
80
+ == Thanks
81
+
82
+ * Thanks to Charlie Savage for donating for YAML dumping and loading
83
+ support.
84
+
85
+ == License
86
+
87
+ This gem is licensed under an MIT-style license. See the +MIT-LICENSE+ file for
88
+ details.
89
+
data/Rakefile CHANGED
@@ -2,23 +2,12 @@
2
2
  # -*- ruby -*-
3
3
 
4
4
  require 'rubygems'
5
-
6
- gem 'rdoc', '~> 3.12'
7
-
8
5
  require 'rubygems/package_task'
9
6
  require 'rake/testtask'
10
7
  require 'rdoc/task'
11
8
  require 'bundler/gem_tasks'
12
9
 
13
- if RUBY_VERSION >= '1.9'
14
- begin
15
- gem 'psych'
16
- rescue Exception => e
17
- # it's okay, fall back on the bundled psych
18
- end
19
- end
20
-
21
- $:.push 'lib'
10
+ $:.push File.expand_path(File.dirname(__FILE__), 'lib')
22
11
 
23
12
  version = Geos::Extensions::VERSION
24
13
 
@@ -20,14 +20,6 @@ Gem::Specification.new do |s|
20
20
  s.homepage = "http://github.com/zoocasa/geos-extensions"
21
21
  s.require_paths = ["lib"]
22
22
 
23
- s.add_dependency("activerecord", [">= 2.3"])
24
- s.add_dependency("ffi-geos", ["~> 0.0.4"])
25
- if RUBY_PLATFORM == "java"
26
- s.add_dependency("activerecord-jdbcpostgresql-adapter")
27
- else
28
- s.add_dependency("pg")
29
- end
30
- s.add_dependency("rdoc")
31
- s.add_dependency("rake", ["~> 0.9"])
23
+ s.add_dependency("ffi-geos", ["~> 0.1"])
32
24
  end
33
25
 
@@ -1,13 +1,5 @@
1
1
 
2
2
  require File.join(File.dirname(__FILE__), *%w{ geos_extensions })
3
3
 
4
- if defined?(ActiveRecord)
5
- require File.join(Geos::GEOS_EXTENSIONS_BASE, *%w{ geos active_record_extensions })
6
- end
7
-
8
- if defined?(Rails) && Rails::VERSION::MAJOR >= 3
9
- require File.join(Geos::GEOS_EXTENSIONS_BASE, %w{ geos rails engine })
10
- end
11
-
12
- Geos::GoogleMaps.use_api(2)
4
+ Geos::GoogleMaps.use_api(3)
13
5
 
@@ -0,0 +1,92 @@
1
+
2
+ module Geos
3
+ class CoordinateSequence
4
+ # Returns a Ruby Array of Arrays of coordinates within the
5
+ # CoordinateSequence in the form [ x, y, z ].
6
+ def to_a
7
+ (0...self.length).to_a.collect do |p|
8
+ [
9
+ self.get_x(p),
10
+ (self.dimensions >= 2 ? self.get_y(p) : nil),
11
+ (self.dimensions >= 3 && self.get_z(p) > 1.7e-306 ? self.get_z(p) : nil)
12
+ ].compact
13
+ end
14
+ end
15
+
16
+ # Build some XmlMarkup for KML. You can set various KML options like
17
+ # tessellate, altitudeMode, etc. Use Rails/Ruby-style code and it
18
+ # will be converted automatically, i.e. :altitudeMode, not
19
+ # :altitude_mode.
20
+ def to_kml(*args)
21
+ xml, options = Geos::Helper.xml_options(*args)
22
+
23
+ xml.LineString(:id => options[:id]) do
24
+ xml.extrude(options[:extrude]) if options[:extrude]
25
+ xml.tessellate(options[:tessellate]) if options[:tessellate]
26
+ xml.altitudeMode(Geos::Helper.camelize(options[:altitude_mode])) if options[:altitudeMode]
27
+ xml.coordinates do
28
+ self.to_a.each do
29
+ xml << (self.to_a.join(','))
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Build some XmlMarkup for GeoRSS GML. You should include the
36
+ # appropriate georss and gml XML namespaces in your document.
37
+ def to_georss(*args)
38
+ xml = Geos::Helper.xml_options(*args)[0]
39
+
40
+ xml.georss(:where) do
41
+ xml.gml(:LineString) do
42
+ xml.gml(:posList) do
43
+ xml << self.to_a.collect do |p|
44
+ "#{p[1]} #{p[0]}"
45
+ end.join(' ')
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ # Returns a Hash suitable for converting to JSON.
52
+ #
53
+ # Options:
54
+ #
55
+ # * :encoded - enable or disable Google Maps encoding. The default is
56
+ # true.
57
+ # * :level - set the level of the Google Maps encoding algorithm.
58
+ def as_json(options = {})
59
+ options = {
60
+ :encoded => true,
61
+ :level => 3
62
+ }.merge options
63
+
64
+ if options[:encoded]
65
+ {
66
+ :type => 'lineString',
67
+ :encoded => true
68
+ }.merge(Geos::GoogleMaps::PolylineEncoder.encode(self.to_a, options[:level]))
69
+ else
70
+ {
71
+ :type => 'lineString',
72
+ :encoded => false,
73
+ :points => self.to_a
74
+ }
75
+ end
76
+ end
77
+ alias :to_jsonable :as_json
78
+
79
+ def as_geojson(options = {})
80
+ {
81
+ :type => 'LineString',
82
+ :coordinates => self.to_a
83
+ }
84
+ end
85
+ alias :to_geojsonable :as_geojson
86
+
87
+ def to_geojson(options = {})
88
+ self.to_geojsonable(options).to_json
89
+ end
90
+ end
91
+ end
92
+
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Geos
3
3
  module Extensions
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
6
6
  end
7
7
 
@@ -0,0 +1,252 @@
1
+
2
+ module Geos
3
+ # This is our base module that we use for some generic methods used all
4
+ # over the place.
5
+ class Geometry
6
+ protected
7
+
8
+ WKB_WRITER_OPTIONS = [ :output_dimensions, :byte_order, :include_srid ].freeze
9
+ def wkb_writer(options = {}) #:nodoc:
10
+ writer = WkbWriter.new
11
+ options.reject { |k, v| !WKB_WRITER_OPTIONS.include?(k) }.each do |k, v|
12
+ writer.send("#{k}=", v)
13
+ end
14
+ writer
15
+ end
16
+
17
+ public
18
+
19
+ # Spits the geometry out into WKB in binary.
20
+ #
21
+ # You can set the :output_dimensions, :byte_order and :include_srid
22
+ # options via the options Hash.
23
+ def to_wkb_bin(options = {})
24
+ wkb_writer(options).write(self)
25
+ end
26
+
27
+ # Quickly call to_wkb_bin with :include_srid set to true.
28
+ def to_ewkb_bin(options = {})
29
+ options = {
30
+ :include_srid => true
31
+ }.merge options
32
+ to_wkb_bin(options)
33
+ end
34
+
35
+ # Spits the geometry out into WKB in hex.
36
+ #
37
+ # You can set the :output_dimensions, :byte_order and :include_srid
38
+ # options via the options Hash.
39
+ def to_wkb(options = {})
40
+ wkb_writer(options).write_hex(self)
41
+ end
42
+
43
+ # Quickly call to_wkb with :include_srid set to true.
44
+ def to_ewkb(options = {})
45
+ options = {
46
+ :include_srid => true
47
+ }.merge options
48
+ to_wkb(options)
49
+ end
50
+
51
+ # Spits the geometry out into WKT. You can specify the :include_srid
52
+ # option to create a PostGIS-style EWKT output.
53
+ def to_wkt(options = {})
54
+ writer = WktWriter.new
55
+
56
+ # Older versions of the Geos library don't allow for options here.
57
+ args = if WktWriter.instance_method(:write).arity < -1
58
+ [ options ]
59
+ else
60
+ []
61
+ end
62
+
63
+ ret = ''
64
+
65
+ if options[:include_srid]
66
+ srid = if options[:srid]
67
+ options[:srid]
68
+ else
69
+ self.srid
70
+ end
71
+
72
+ ret << "SRID=#{srid};"
73
+ end
74
+
75
+ ret << writer.write(self, *args)
76
+ ret
77
+ end
78
+
79
+ # Quickly call to_wkt with :include_srid set to true.
80
+ def to_ewkt(options = {})
81
+ options = {
82
+ :include_srid => true
83
+ }.merge options
84
+ to_wkt(options)
85
+ end
86
+
87
+ # Returns a Point for the envelope's upper left coordinate.
88
+ def upper_left
89
+ if defined?(@upper_left)
90
+ @upper_left
91
+ else
92
+ cs = self.envelope.exterior_ring.coord_seq
93
+ @upper_left = Geos::wkt_reader_singleton.read("POINT(#{cs.get_x(3)} #{cs.get_y(3)})")
94
+ end
95
+ end
96
+ alias :nw :upper_left
97
+ alias :northwest :upper_left
98
+
99
+ # Returns a Point for the envelope's upper right coordinate.
100
+ def upper_right
101
+ if defined?(@upper_right)
102
+ @upper_right
103
+ else
104
+ cs = self.envelope.exterior_ring.coord_seq
105
+ @upper_right = Geos::wkt_reader_singleton.read("POINT(#{cs.get_x(2)} #{cs.get_y(2)})")
106
+ end
107
+ end
108
+ alias :ne :upper_right
109
+ alias :northeast :upper_right
110
+
111
+ # Returns a Point for the envelope's lower right coordinate.
112
+ def lower_right
113
+ if defined?(@lower_right)
114
+ @lower_right
115
+ else
116
+ cs = self.envelope.exterior_ring.coord_seq
117
+ @lower_right = Geos::wkt_reader_singleton.read("POINT(#{cs.get_x(1)} #{cs.get_y(1)})")
118
+ end
119
+ end
120
+ alias :se :lower_right
121
+ alias :southeast :lower_right
122
+
123
+ # Returns a Point for the envelope's lower left coordinate.
124
+ def lower_left
125
+ if defined?(@lower_left)
126
+ @lower_left
127
+ else
128
+ cs = self.envelope.exterior_ring.coord_seq
129
+ @lower_left = Geos::wkt_reader_singleton.read("POINT(#{cs.get_x(0)} #{cs.get_y(0)})")
130
+ end
131
+ end
132
+ alias :sw :lower_left
133
+ alias :southwest :lower_left
134
+
135
+ # Northern-most Y coordinate.
136
+ def top
137
+ if defined?(@top)
138
+ @top
139
+ else
140
+ @top = self.upper_right.y
141
+ end
142
+ end
143
+ alias :n :top
144
+ alias :north :top
145
+
146
+ # Eastern-most X coordinate.
147
+ def right
148
+ if defined?(@right)
149
+ @right
150
+ else
151
+ @right = self.upper_right.x
152
+ end
153
+ end
154
+ alias :e :right
155
+ alias :east :right
156
+
157
+ # Southern-most Y coordinate.
158
+ def bottom
159
+ if defined?(@bottom)
160
+ @bottom
161
+ else
162
+ @bottom = self.lower_left.y
163
+ end
164
+ end
165
+ alias :s :bottom
166
+ alias :south :bottom
167
+
168
+ # Western-most X coordinate.
169
+ def left
170
+ if defined?(@left)
171
+ @left
172
+ else
173
+ @left = self.lower_left.x
174
+ end
175
+ end
176
+ alias :w :left
177
+ alias :west :left
178
+
179
+ # Spits out a bounding box the way Flickr likes it. You can set the
180
+ # precision of the rounding using the :precision option. In order to
181
+ # ensure that the box is indeed a box and not merely a point, the
182
+ # southwest coordinates are floored and the northeast point ceiled.
183
+ def to_flickr_bbox(options = {})
184
+ options = {
185
+ :precision => 1
186
+ }.merge(options)
187
+ precision = 10.0 ** options[:precision]
188
+
189
+ [
190
+ (self.west * precision).floor / precision,
191
+ (self.south * precision).floor / precision,
192
+ (self.east * precision).ceil / precision,
193
+ (self.north * precision).ceil / precision
194
+ ].join(',')
195
+ end
196
+
197
+ # Spits out the actual stringified GeoJSON.
198
+ def to_geojson(options = {})
199
+ self.to_geojsonable(options).to_json
200
+ end
201
+
202
+ # Returns the Y and X coordinates of the Geometry's centroid in an Array.
203
+ def lat_lng
204
+ self.centroid.to_a[0, 2].reverse
205
+ end
206
+ alias :lat_long :lat_lng
207
+ alias :latlng :lat_lng
208
+ alias :latlong :lat_lng
209
+ alias :lat_lon :lat_lng
210
+ alias :latlon :lat_lng
211
+
212
+ # Returns the X and Y coordinates of the Geometry's centroid in an Array.
213
+ def lng_lat
214
+ self.centroid.to_a[0, 2]
215
+ end
216
+ alias :long_lat :lng_lat
217
+ alias :lnglat :lng_lat
218
+ alias :longlat :lng_lat
219
+ alias :lon_lat :lng_lat
220
+ alias :lonlat :lng_lat
221
+
222
+ # Spits out a Hash containing the cardinal points that describe the
223
+ # Geometry's bbox.
224
+ def to_bbox(long_or_short_names = :long)
225
+ case long_or_short_names
226
+ when :long
227
+ {
228
+ :north => self.north,
229
+ :east => self.east,
230
+ :south => self.south,
231
+ :west => self.west
232
+ }
233
+ when :short
234
+ {
235
+ :n => self.north,
236
+ :e => self.east,
237
+ :s => self.south,
238
+ :w => self.west
239
+ }
240
+ else
241
+ raise ArgumentError.new("Expected either :long or :short for long_or_short_names argument")
242
+ end
243
+ end
244
+
245
+ # Spits out a PostGIS BOX2D-style representing the Geometry's bounding
246
+ # box.
247
+ def to_box2d
248
+ "BOX(#{self.southwest.to_a.join(' ')}, #{self.northeast.to_a.join(' ')})"
249
+ end
250
+ end
251
+ end
252
+